summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/uart-s5l8702.c
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2016-05-12 06:47:38 +0200
committerCástor Muñoz <cmvidal@gmail.com>2016-05-13 23:21:42 +0200
commit8fb67f48ab57770c3233352de17846a8a773192a (patch)
treefcf00f022dcd297c10ab92df8b85021f55e96f6f /firmware/target/arm/s5l8702/uart-s5l8702.c
parent2a1e9eb8a8f50f636f86988de1f0cd1b3acf55bb (diff)
downloadrockbox-8fb67f48ab57770c3233352de17846a8a773192a.tar.gz
rockbox-8fb67f48ab57770c3233352de17846a8a773192a.zip
iPod Classic: updates for uc8702 driver
- Small rework on the UC8702 UART controller to make it compatible with other s5l870x SOCs. Files moved and renamed, many conditional code added to deal with capabilities and 'features' of the different CPUs. - A couple of optimizacions that should not affect the functionality. Change-Id: I705169f7e8b18d5d1da642f81ffc31c4089780a6
Diffstat (limited to 'firmware/target/arm/s5l8702/uart-s5l8702.c')
-rw-r--r--firmware/target/arm/s5l8702/uart-s5l8702.c155
1 files changed, 89 insertions, 66 deletions
diff --git a/firmware/target/arm/s5l8702/uart-s5l8702.c b/firmware/target/arm/s5l8702/uart-s5l8702.c
index 45d61ba627..9d8faaa173 100644
--- a/firmware/target/arm/s5l8702/uart-s5l8702.c
+++ b/firmware/target/arm/s5l8702/uart-s5l8702.c
@@ -18,110 +18,133 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21#include <stdint.h>
22/* Include Standard files */ 22#include <stdbool.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <stdarg.h>
26 23
27#include "config.h" 24#include "config.h"
28#include "cpu.h" 25#include "cpu.h"
29#include "system.h" 26#include "system.h"
30#include "kernel.h"
31 27
32#include "s5l8702.h" 28#include "s5l8702.h"
33#include "uc8702.h" 29#include "uc870x.h"
34#include "uart-s5l8702.h"
35 30
36 31
37/* s5l8702 UART configuration */ 32/*
38struct uartc s5l8702_uart = { 33 * s5l8702 UC870X HW: 1 UARTC, 4 ports
39 .baddr = S5L8702_UART_BASE 34 */
35static struct uartc_port *uartc_port_l[UARTC_N_PORTS];
36const struct uartc s5l8702_uartc =
37{
38 .id = 0,
39 .baddr = UARTC_BASE_ADDR,
40 .port_off = UARTC_PORT_OFFSET,
41 .n_ports = UARTC_N_PORTS,
42 .port_l = uartc_port_l,
40}; 43};
41 44
42/* 45/*
43 * Device level functions specific to S5L8702 46 * Device level functions specific to S5L8702
44 */ 47 */
45void uart_gpio_control(int port_id, bool onoff) 48void uart_target_enable_gpio(int uart_id, int port_id)
46{ 49{
47 if (onoff) { 50 (void) uart_id;
48 switch (port_id) { 51 switch (port_id) {
49 case 0: 52 case 0:
50 /* configure UART0 Tx/Rx GPIO ports */ 53 /* configure UART0 Tx/Rx GPIO ports */
51 PCON0 = (PCON0 & 0xff00ffff) | 0x00220000; 54 PCON0 = (PCON0 & 0xff00ffff) | 0x00220000;
52 break; 55 break;
53 case 1: 56 case 1:
54 /* configure UART1 GPIO ports, including RTS/CTS signals */ 57 /* configure UART1 GPIO ports, including RTS/CTS signals */
55 PCOND = (PCOND & 0xff0000ff) | 0x00222200; 58 PCOND = (PCOND & 0xff0000ff) | 0x00222200;
56 break; 59 break;
57 case 2: 60 case 2:
58 case 3: 61 case 3:
59 /* unknown, probably UART3/4 not routed on s5l8702 */ 62 /* unknown */
60 default: 63 default:
61 break; 64 break;
62 }
63 } 65 }
64 else { 66}
67
68void uart_target_disable_gpio(int uart_id, int port_id)
69{
70 (void) uart_id;
71 switch (port_id) {
65 /* configure minimal power consumption */ 72 /* configure minimal power consumption */
66 switch (port_id) { 73 case 0:
67 case 0: 74 PCON0 = (PCON0 & 0xff00ffff) | 0x00ee0000;
68 PCON0 = (PCON0 & 0xff00ffff) | 0x00ee0000; 75 break;
69 break; 76 case 1:
70 case 1: 77 PCOND = (PCOND & 0xff0000ff) | 0x00eeee00;
71 PCOND = (PCOND & 0xff0000ff) | 0x00eeee00; 78 break;
72 break; 79 case 2:
73 case 2: 80 case 3:
74 case 3: 81 default:
75 default: 82 break;
76 break;
77 }
78 } 83 }
79} 84}
80 85
81/* reset s5l8702 uart related hardware */ 86void uart_target_enable_irq(int uart_id, int port_id)
82static void s5l8702_uart_hw_init(void)
83{ 87{
84 for (int id = 0; id < S5L8702_UART_PORT_MAX; id++) { 88 (void) uart_id;
85 VIC0INTENCLEAR = 1 << IRQ_UART(id); /* mask INT */ 89 VIC0INTENABLE = 1 << IRQ_UART(port_id);
86 uart_gpio_control(id, 0);
87 }
88} 90}
89 91
90void uart_init(void) 92void uart_target_disable_irq(int uart_id, int port_id)
91{ 93{
92 s5l8702_uart_hw_init(); 94 (void) uart_id;
93 PWRCON(1) &= ~(1 << (CLOCKGATE_UART - 32)); /* on */ 95 VIC0INTENCLEAR = 1 << IRQ_UART(port_id);
94 uartc_open(&s5l8702_uart);
95} 96}
96 97
97void uart_close(void) 98void uart_target_clear_irq(int uart_id, int port_id)
98{ 99{
99 uartc_close(&s5l8702_uart); 100 (void) uart_id;
100 PWRCON(1) |= (1 << (CLOCKGATE_UART - 32)); /* off */ 101 (void) port_id;
101 s5l8702_uart_hw_init();
102} 102}
103 103
104void uart_port_init(struct uartc_port *port) 104void uart_target_enable_clocks(int uart_id)
105{ 105{
106 uart_gpio_control(port->id, 1); 106 (void) uart_id;
107 uartc_port_open(port); 107 PWRCON(1) &= ~(1 << (CLOCKGATE_UARTC - 32));
108 VIC0INTENABLE = 1 << IRQ_UART(port->id); /* unmask INT */
109} 108}
110 109
111void uart_port_close(struct uartc_port *port) 110void uart_target_disable_clocks(int uart_id)
112{ 111{
113 VIC0INTENCLEAR = 1 << IRQ_UART(port->id); /* mask INT */ 112 (void) uart_id;
114 uartc_port_close(port); 113 PWRCON(1) |= (1 << (CLOCKGATE_UARTC - 32));
115 uart_gpio_control(port->id, 0);
116} 114}
117 115
118/* ISRs */ 116/*
117 * ISRs
118 */
119
120/* On Classic, PORT0 interrupts are not used when iAP is disabled */
121#if !defined(IPOD_6G) || defined(IPOD_ACCESSORY_PROTOCOL)
119void ICODE_ATTR INT_UART0(void) 122void ICODE_ATTR INT_UART0(void)
120{ 123{
121 uartc_callback(&s5l8702_uart, 0); 124 uartc_callback(&s5l8702_uartc, 0);
122} 125}
126#endif
123 127
128/* PORT1,2,3 not used on Classic */
129#ifndef IPOD_6G
124void ICODE_ATTR INT_UART1(void) 130void ICODE_ATTR INT_UART1(void)
125{ 131{
126 uartc_callback(&s5l8702_uart, 1); 132 uartc_callback(&s5l8702_uartc, 1);
133}
134
135void ICODE_ATTR INT_UART2(void)
136{
137 uartc_callback(&s5l8702_uartc, 2);
138}
139
140void ICODE_ATTR INT_UART3(void)
141{
142 uartc_callback(&s5l8702_uartc, 3);
143}
144#endif
145
146/* Main init */
147void uart_init(void)
148{
149 uartc_open(&s5l8702_uartc);
127} 150}