diff options
Diffstat (limited to 'firmware/target/arm/s5l8702/uart-s5l8702.c')
-rw-r--r-- | firmware/target/arm/s5l8702/uart-s5l8702.c | 155 |
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 | /* |
38 | struct uartc s5l8702_uart = { | 33 | * s5l8702 UC870X HW: 1 UARTC, 4 ports |
39 | .baddr = S5L8702_UART_BASE | 34 | */ |
35 | static struct uartc_port *uartc_port_l[UARTC_N_PORTS]; | ||
36 | const 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 | */ |
45 | void uart_gpio_control(int port_id, bool onoff) | 48 | void 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 | |||
68 | void 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 */ | 86 | void uart_target_enable_irq(int uart_id, int port_id) |
82 | static 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 | ||
90 | void uart_init(void) | 92 | void 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 | ||
97 | void uart_close(void) | 98 | void 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 | ||
104 | void uart_port_init(struct uartc_port *port) | 104 | void 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 | ||
111 | void uart_port_close(struct uartc_port *port) | 110 | void 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) | ||
119 | void ICODE_ATTR INT_UART0(void) | 122 | void 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 | ||
124 | void ICODE_ATTR INT_UART1(void) | 130 | void ICODE_ATTR INT_UART1(void) |
125 | { | 131 | { |
126 | uartc_callback(&s5l8702_uart, 1); | 132 | uartc_callback(&s5l8702_uartc, 1); |
133 | } | ||
134 | |||
135 | void ICODE_ATTR INT_UART2(void) | ||
136 | { | ||
137 | uartc_callback(&s5l8702_uartc, 2); | ||
138 | } | ||
139 | |||
140 | void ICODE_ATTR INT_UART3(void) | ||
141 | { | ||
142 | uartc_callback(&s5l8702_uartc, 3); | ||
143 | } | ||
144 | #endif | ||
145 | |||
146 | /* Main init */ | ||
147 | void uart_init(void) | ||
148 | { | ||
149 | uartc_open(&s5l8702_uartc); | ||
127 | } | 150 | } |