diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/config/ipodnano2g.h | 9 | ||||
-rw-r--r-- | firmware/export/s5l8700.h | 52 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/serial-nano2g.c | 113 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/system-s5l8700.c | 12 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/uart-s5l8701.c | 17 |
5 files changed, 183 insertions, 20 deletions
diff --git a/firmware/export/config/ipodnano2g.h b/firmware/export/config/ipodnano2g.h index a9c7239056..8e8f40f56c 100644 --- a/firmware/export/config/ipodnano2g.h +++ b/firmware/export/config/ipodnano2g.h | |||
@@ -231,9 +231,14 @@ | |||
231 | 231 | ||
232 | /* Define this if you can switch on/off the accessory power supply */ | 232 | /* Define this if you can switch on/off the accessory power supply */ |
233 | #define HAVE_ACCESSORY_SUPPLY | 233 | #define HAVE_ACCESSORY_SUPPLY |
234 | //#define IPOD_ACCESSORY_PROTOCOL | 234 | |
235 | #ifdef LOGF_SERIAL | 235 | /* Serial */ |
236 | #ifndef BOOTLOADER | ||
236 | #define HAVE_SERIAL | 237 | #define HAVE_SERIAL |
238 | /* Disable iAP when LOGF_SERIAL is enabled to avoid conflicts */ | ||
239 | #ifndef LOGF_SERIAL | ||
240 | #define IPOD_ACCESSORY_PROTOCOL | ||
241 | #endif | ||
237 | #endif | 242 | #endif |
238 | 243 | ||
239 | /* Define this, if you can switch on/off the lineout */ | 244 | /* Define this, if you can switch on/off the lineout */ |
diff --git a/firmware/export/s5l8700.h b/firmware/export/s5l8700.h index e8497ff337..3444919bc3 100644 --- a/firmware/export/s5l8700.h +++ b/firmware/export/s5l8700.h | |||
@@ -133,33 +133,61 @@ | |||
133 | #define PWRCONEXT (*(REG32_PTR_T)(0x3C500040)) /* Clock power control register 2 */ | 133 | #define PWRCONEXT (*(REG32_PTR_T)(0x3C500040)) /* Clock power control register 2 */ |
134 | 134 | ||
135 | /* 06. INTERRUPT CONTROLLER UNIT */ | 135 | /* 06. INTERRUPT CONTROLLER UNIT */ |
136 | #if CONFIG_CPU==S5L8700 | ||
136 | #define SRCPND (*(REG32_PTR_T)(0x39C00000)) /* Indicates the interrupt request status. */ | 137 | #define SRCPND (*(REG32_PTR_T)(0x39C00000)) /* Indicates the interrupt request status. */ |
137 | #define INTMOD (*(REG32_PTR_T)(0x39C00004)) /* Interrupt mode register. */ | 138 | #define INTMOD (*(REG32_PTR_T)(0x39C00004)) /* Interrupt mode register. */ |
138 | #define INTMSK (*(REG32_PTR_T)(0x39C00008)) /* Determines which interrupt source is masked. The */ | 139 | #define INTMSK (*(REG32_PTR_T)(0x39C00008)) /* Determines which interrupt source is masked. The */ |
139 | #if CONFIG_CPU==S5L8701 | ||
140 | #define INTMSK_TIMERA (1<<5) | ||
141 | #define INTMSK_TIMERB (1<<5) | ||
142 | #define INTMSK_TIMERC (1<<5) | ||
143 | #define INTMSK_TIMERD (1<<5) | ||
144 | #define INTMSK_ECC (1<<19) | ||
145 | #define INTMSK_USB_OTG (1<<16) | ||
146 | #define INTMSK_UART0 (0) /* Unknown */ | ||
147 | #define INTMSK_UART1 (1<<12) | ||
148 | #define INTMSK_UART2 (1<<7) | ||
149 | #else | ||
150 | #define INTMSK_TIMERA (1<<5) | 140 | #define INTMSK_TIMERA (1<<5) |
151 | #define INTMSK_TIMERB (1<<7) | 141 | #define INTMSK_TIMERB (1<<7) |
152 | #define INTMSK_TIMERC (1<<8) | 142 | #define INTMSK_TIMERC (1<<8) |
153 | #define INTMSK_TIMERD (1<<9) | 143 | #define INTMSK_TIMERD (1<<9) |
154 | #define INTMSK_UART0 (1<<22) | 144 | #define INTMSK_UART0 (1<<22) |
155 | #define INTMSK_UART1 (1<<14) | 145 | #define INTMSK_UART1 (1<<14) |
156 | #endif | ||
157 | #define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */ | 146 | #define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */ |
158 | #define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */ | 147 | #define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */ |
159 | #define INTOFFSET (*(REG32_PTR_T)(0x39C00014)) /* Indicates the IRQ interrupt request source */ | 148 | #define INTOFFSET (*(REG32_PTR_T)(0x39C00014)) /* Indicates the IRQ interrupt request source */ |
160 | #define EINTPOL (*(REG32_PTR_T)(0x39C00018)) /* Indicates external interrupt polarity */ | 149 | #define EINTPOL (*(REG32_PTR_T)(0x39C00018)) /* Indicates external interrupt polarity */ |
161 | #define EINTPEND (*(REG32_PTR_T)(0x39C0001C)) /* Indicates whether external interrupts are pending. */ | 150 | #define EINTPEND (*(REG32_PTR_T)(0x39C0001C)) /* Indicates whether external interrupts are pending. */ |
162 | #define EINTMSK (*(REG32_PTR_T)(0x39C00020)) /* Indicates whether external interrupts are masked */ | 151 | #define EINTMSK (*(REG32_PTR_T)(0x39C00020)) /* Indicates whether external interrupts are masked */ |
152 | #else /* S5L8701 */ | ||
153 | #define SRCPND (*(REG32_PTR_T)(0x39C00000)) /* Indicates the interrupt request status. */ | ||
154 | #define INTMOD (*(REG32_PTR_T)(0x39C00004)) /* Interrupt mode register. */ | ||
155 | #define INTMSK (*(REG32_PTR_T)(0x39C00008)) /* Determines which interrupt source is masked. The */ | ||
156 | #define INTMSK_EINTG0 (1<<1) | ||
157 | #define INTMSK_EINTG1 (1<<2) | ||
158 | #define INTMSK_EINTG2 (1<<3) | ||
159 | #define INTMSK_EINTG3 (1<<4) | ||
160 | #define INTMSK_TIMERA (1<<5) | ||
161 | #define INTMSK_TIMERB (1<<5) | ||
162 | #define INTMSK_TIMERC (1<<5) | ||
163 | #define INTMSK_TIMERD (1<<5) | ||
164 | #define INTMSK_ECC (1<<19) | ||
165 | #define INTMSK_USB_OTG (1<<16) | ||
166 | #define INTMSK_UART0 (0) /* (AFAIK) no IRQ to ICU, uses EINTG0 */ | ||
167 | #define INTMSK_UART1 (1<<12) | ||
168 | #define INTMSK_UART2 (1<<7) | ||
169 | #define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */ | ||
170 | #define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */ | ||
171 | #define INTOFFSET (*(REG32_PTR_T)(0x39C00014)) /* Indicates the IRQ interrupt request source */ | ||
172 | /* | ||
173 | * s5l8701 GPIO (External) Interrupt Controller. | ||
174 | * | ||
175 | * At first glance it looks very similar to gpio-s5l8702, but | ||
176 | * not fully tested, so this information could be wrong. | ||
177 | * | ||
178 | * Group0[31:10] Not used | ||
179 | * [9] UART0 IRQ | ||
180 | * [8] VBUS | ||
181 | * [7:0] PDAT1 | ||
182 | * Group1[31:0] PDAT5:PDAT4:PDAT3:PDAT2 | ||
183 | * Group2[31:0] PDAT11:PDAT10:PDAT7:PDAT6 | ||
184 | * Group3[31:0] PDAT15:PDAT14:PDAT13:PDAT12 | ||
185 | */ | ||
186 | #define GPIOIC_INTLEVEL(g) (*(REG32_PTR_T)(0x39C00018 + 4*(g))) | ||
187 | #define GPIOIC_INTSTAT(g) (*(REG32_PTR_T)(0x39C00028 + 4*(g))) | ||
188 | #define GPIOIC_INTEN(g) (*(REG32_PTR_T)(0x39C00038 + 4*(g))) | ||
189 | #define GPIOIC_INTTYPE(g) (*(REG32_PTR_T)(0x39C00048 + 4*(g))) | ||
190 | #endif | ||
163 | 191 | ||
164 | /* 07. MEMORY INTERFACE UNIT (MIU) */ | 192 | /* 07. MEMORY INTERFACE UNIT (MIU) */ |
165 | 193 | ||
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/serial-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/serial-nano2g.c index 487984fbe3..5ff0b0ca25 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/serial-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/serial-nano2g.c | |||
@@ -47,6 +47,9 @@ | |||
47 | 47 | ||
48 | 48 | ||
49 | extern const struct uartc s5l8701_uartc0; | 49 | extern const struct uartc s5l8701_uartc0; |
50 | #ifdef IPOD_ACCESSORY_PROTOCOL | ||
51 | void iap_rx_isr(int, char*, char*, uint32_t); | ||
52 | #endif | ||
50 | 53 | ||
51 | struct uartc_port ser_port IDATA_ATTR = | 54 | struct uartc_port ser_port IDATA_ATTR = |
52 | { | 55 | { |
@@ -61,7 +64,11 @@ struct uartc_port ser_port IDATA_ATTR = | |||
61 | .clkhz = NANO2G_UART_CLK_HZ, | 64 | .clkhz = NANO2G_UART_CLK_HZ, |
62 | 65 | ||
63 | /* interrupt callbacks */ | 66 | /* interrupt callbacks */ |
67 | #ifdef IPOD_ACCESSORY_PROTOCOL | ||
68 | .rx_cb = iap_rx_isr, | ||
69 | #else | ||
64 | .rx_cb = NULL, | 70 | .rx_cb = NULL, |
71 | #endif | ||
65 | .tx_cb = NULL, /* polling */ | 72 | .tx_cb = NULL, /* polling */ |
66 | }; | 73 | }; |
67 | 74 | ||
@@ -94,3 +101,109 @@ void tx_writec(unsigned char c) | |||
94 | { | 101 | { |
95 | uartc_port_tx_byte(&ser_port, c); | 102 | uartc_port_tx_byte(&ser_port, c); |
96 | } | 103 | } |
104 | |||
105 | |||
106 | #ifdef IPOD_ACCESSORY_PROTOCOL | ||
107 | #include "iap.h" | ||
108 | |||
109 | static enum { | ||
110 | ABR_STATUS_LAUNCHED, /* ST_SYNC */ | ||
111 | ABR_STATUS_SYNCING, /* ST_SOF */ | ||
112 | ABR_STATUS_DONE | ||
113 | } abr_status; | ||
114 | |||
115 | void serial_bitrate(int rate) | ||
116 | { | ||
117 | logf("[%lu] serial_bitrate(%d)", (uint32_t)USEC_TIMER, rate); | ||
118 | |||
119 | if (rate == 0) { | ||
120 | /* Using auto-bitrate (ABR) to detect accessory Tx speed: | ||
121 | * | ||
122 | * + Here: | ||
123 | * - Disable Rx logic to clean the FIFO and the shift | ||
124 | * register, thus no Rx data interrupts are generated. | ||
125 | * - Launch ABR and wait for a low pulse in Rx line. | ||
126 | * | ||
127 | * + In ISR, when a low pulse is detected (ideally it is the | ||
128 | * start bit of 0xff): | ||
129 | * - Calculate and configure detected speed. | ||
130 | * - Enable Rx to verify that the next received data frame | ||
131 | * is 0x55 or 0xff: | ||
132 | * - If so, it's assumed bit rate is correctly detected, | ||
133 | * it will not be modified until speed is changed using | ||
134 | * RB options menu. | ||
135 | * - If not, reset iAP state machine and launch a new ABR. | ||
136 | */ | ||
137 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_DISABLED); | ||
138 | uartc_port_abr_start(&ser_port); | ||
139 | abr_status = ABR_STATUS_LAUNCHED; | ||
140 | } | ||
141 | else { | ||
142 | uint32_t brdata; | ||
143 | if (rate == 57600) brdata = BRDATA_57600; | ||
144 | else if (rate == 38400) brdata = BRDATA_38400; | ||
145 | else if (rate == 19200) brdata = BRDATA_19200; | ||
146 | else brdata = BRDATA_9600; | ||
147 | uartc_port_abr_stop(&ser_port); /* abort ABR if already launched */ | ||
148 | uartc_port_set_bitrate_raw(&ser_port, brdata); | ||
149 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); | ||
150 | abr_status = ABR_STATUS_DONE; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | void iap_rx_isr(int len, char *data, char *err, uint32_t abr_cnt) | ||
155 | { | ||
156 | /* ignore Rx errors, upper layer will discard bad packets */ | ||
157 | (void) err; | ||
158 | |||
159 | static int sync_retry; | ||
160 | |||
161 | if (abr_status == ABR_STATUS_LAUNCHED) { | ||
162 | /* autobauding */ | ||
163 | if (abr_cnt) { | ||
164 | #define BR2CNT(s) (NANO2G_UART_CLK_HZ / (unsigned)(s)) | ||
165 | if (abr_cnt < BR2CNT(57600*1.1) || abr_cnt > BR2CNT(9600*0.9)) { | ||
166 | /* detected speed out of range, relaunch ABR */ | ||
167 | uartc_port_abr_start(&ser_port); | ||
168 | return; | ||
169 | } | ||
170 | /* valid speed detected, select it */ | ||
171 | uint32_t brdata; | ||
172 | if (abr_cnt < BR2CNT(48000)) brdata = BRDATA_57600; | ||
173 | else if (abr_cnt < BR2CNT(33600)) brdata = BRDATA_38400; | ||
174 | else if (abr_cnt < BR2CNT(24000)) brdata = BRDATA_28800; | ||
175 | else if (abr_cnt < BR2CNT(14400)) brdata = BRDATA_19200; | ||
176 | else brdata = BRDATA_9600; | ||
177 | |||
178 | /* set detected speed */ | ||
179 | uartc_port_set_bitrate_raw(&ser_port, brdata); | ||
180 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); | ||
181 | |||
182 | /* enter SOF state */ | ||
183 | iap_getc(0xff); | ||
184 | |||
185 | abr_status = ABR_STATUS_SYNCING; | ||
186 | sync_retry = 2; /* we are expecting [0xff] 0x55 */ | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /* process received data */ | ||
191 | while (len--) | ||
192 | { | ||
193 | bool sync_done = !iap_getc(*data++); | ||
194 | |||
195 | if (abr_status == ABR_STATUS_SYNCING) | ||
196 | { | ||
197 | if (sync_done) { | ||
198 | abr_status = ABR_STATUS_DONE; | ||
199 | } | ||
200 | else if (--sync_retry == 0) { | ||
201 | /* invalid speed detected, relaunch ABR | ||
202 | discarding remaining data (if any) */ | ||
203 | serial_bitrate(0); | ||
204 | break; | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | #endif /* IPOD_ACCESSORY_PROTOCOL */ | ||
diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c index 728fea0432..226464fb08 100644 --- a/firmware/target/arm/s5l8700/system-s5l8700.c +++ b/firmware/target/arm/s5l8700/system-s5l8700.c | |||
@@ -85,6 +85,10 @@ default_interrupt(INT_ADC); | |||
85 | #if CONFIG_CPU==S5L8701 | 85 | #if CONFIG_CPU==S5L8701 |
86 | default_interrupt(INT_UNK); | 86 | default_interrupt(INT_UNK); |
87 | default_interrupt(INT_UART2); | 87 | default_interrupt(INT_UART2); |
88 | default_interrupt(EINT_G0); | ||
89 | default_interrupt(EINT_G1); | ||
90 | default_interrupt(EINT_G2); | ||
91 | default_interrupt(EINT_G3); | ||
88 | #endif | 92 | #endif |
89 | 93 | ||
90 | 94 | ||
@@ -99,8 +103,8 @@ void INT_TIMER(void) | |||
99 | 103 | ||
100 | #if CONFIG_CPU==S5L8701 | 104 | #if CONFIG_CPU==S5L8701 |
101 | static void (* const irqvector[])(void) = | 105 | static void (* const irqvector[])(void) = |
102 | { /* still 90% unverified and probably incorrect */ | 106 | { /* still 80% unverified and probably incorrect */ |
103 | EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMER,INT_WDT,INT_UART2, | 107 | EXT0,EINT_G0,EINT_G1,EINT_G2,EINT_G3,INT_TIMER,INT_WDT,INT_UART2, |
104 | INT_UNK,INT_UNK,INT_DMA,INT_ALARM_RTC,INT_UART1,INT_UNK,INT_UNK,INT_USB_HOST, | 108 | INT_UNK,INT_UNK,INT_DMA,INT_ALARM_RTC,INT_UART1,INT_UNK,INT_UNK,INT_USB_HOST, |
105 | INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_CALM,INT_ATA,INT_UNK,INT_SPDIF_OUT,INT_ECC, | 109 | INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_CALM,INT_ATA,INT_UNK,INT_SPDIF_OUT,INT_ECC, |
106 | INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC | 110 | INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC |
@@ -117,8 +121,8 @@ static void (* const irqvector[])(void) = | |||
117 | 121 | ||
118 | #if CONFIG_CPU==S5L8701 | 122 | #if CONFIG_CPU==S5L8701 |
119 | static const char * const irqname[] = | 123 | static const char * const irqname[] = |
120 | { /* still 90% unverified and probably incorrect */ | 124 | { /* still 80% unverified and probably incorrect */ |
121 | "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMER","INT_WDT","INT_UART2", | 125 | "EXT0","EINT_G0","EINT_G1","EINT_G2","EINT_G3","INT_TIMER","INT_WDT","INT_UART2", |
122 | "INT_UNK1","INT_UNK2","INT_DMA","INT_ALARM_RTC","INT_UART1","INT_UNK3","INT_UNK4","INT_USB_HOST", | 126 | "INT_UNK1","INT_UNK2","INT_DMA","INT_ALARM_RTC","INT_UART1","INT_UNK3","INT_UNK4","INT_USB_HOST", |
123 | "INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_CALM","INT_ATA","INT_UNK5","INT_SPDIF_OUT","INT_ECC", | 127 | "INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_CALM","INT_ATA","INT_UNK5","INT_SPDIF_OUT","INT_ECC", |
124 | "INT_SDCI","INT_LCD","INT_WHEEL","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC" | 128 | "INT_SDCI","INT_LCD","INT_WHEEL","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC" |
diff --git a/firmware/target/arm/s5l8700/uart-s5l8701.c b/firmware/target/arm/s5l8700/uart-s5l8701.c index 00c9322e47..b9fb1632ac 100644 --- a/firmware/target/arm/s5l8700/uart-s5l8701.c +++ b/firmware/target/arm/s5l8700/uart-s5l8701.c | |||
@@ -68,7 +68,7 @@ static uint8_t clockgate_uartc[S5L8701_N_UARTC] = { | |||
68 | CLOCKGATE_UARTC0, CLOCKGATE_UARTC1, CLOCKGATE_UARTC2 }; | 68 | CLOCKGATE_UARTC0, CLOCKGATE_UARTC1, CLOCKGATE_UARTC2 }; |
69 | 69 | ||
70 | static int intmsk_uart[S5L8701_N_UARTC] = { | 70 | static int intmsk_uart[S5L8701_N_UARTC] = { |
71 | INTMSK_UART0, INTMSK_UART1, INTMSK_UART2 }; | 71 | INTMSK_EINTG0, INTMSK_UART1, INTMSK_UART2 }; |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * Device level functions specific to S5L8701 | 74 | * Device level functions specific to S5L8701 |
@@ -107,6 +107,7 @@ void uart_target_disable_gpio(int uart_id, int port_id) | |||
107 | void uart_target_enable_irq(int uart_id, int port_id) | 107 | void uart_target_enable_irq(int uart_id, int port_id) |
108 | { | 108 | { |
109 | (void) port_id; | 109 | (void) port_id; |
110 | if (uart_id == 0) GPIOIC_INTEN(0) = 0x200; | ||
110 | INTMSK |= intmsk_uart[uart_id]; | 111 | INTMSK |= intmsk_uart[uart_id]; |
111 | } | 112 | } |
112 | 113 | ||
@@ -114,11 +115,13 @@ void uart_target_disable_irq(int uart_id, int port_id) | |||
114 | { | 115 | { |
115 | (void) port_id; | 116 | (void) port_id; |
116 | INTMSK &= ~intmsk_uart[uart_id]; | 117 | INTMSK &= ~intmsk_uart[uart_id]; |
118 | if (uart_id == 0) GPIOIC_INTEN(0) = 0; | ||
117 | } | 119 | } |
118 | 120 | ||
119 | void uart_target_clear_irq(int uart_id, int port_id) | 121 | void uart_target_clear_irq(int uart_id, int port_id) |
120 | { | 122 | { |
121 | (void) port_id; | 123 | (void) port_id; |
124 | if (uart_id == 0) GPIOIC_INTSTAT(0) = 0x200; | ||
122 | SRCPND |= intmsk_uart[uart_id]; | 125 | SRCPND |= intmsk_uart[uart_id]; |
123 | } | 126 | } |
124 | 127 | ||
@@ -135,10 +138,20 @@ void uart_target_disable_clocks(int uart_id) | |||
135 | /* | 138 | /* |
136 | * ISRs | 139 | * ISRs |
137 | */ | 140 | */ |
138 | void ICODE_ATTR INT_UART0(void) | 141 | |
142 | /* On Nano2G, PORT0 interrupts are not used when iAP is disabled */ | ||
143 | #if !defined(IPOD_NANO2G) || defined(IPOD_ACCESSORY_PROTOCOL) | ||
144 | /* | ||
145 | * UART0 IRQ is connected to EINTG0, this is a quick patch, a "real" | ||
146 | * EINT handler will be needed if in future we use more than one IRQ | ||
147 | * on this group. | ||
148 | */ | ||
149 | void ICODE_ATTR EINT_G0(void) | ||
139 | { | 150 | { |
151 | GPIOIC_INTSTAT(0) = 0x200; /* clear external IRQ */ | ||
140 | uartc_callback(&s5l8701_uartc0, 0); | 152 | uartc_callback(&s5l8701_uartc0, 0); |
141 | } | 153 | } |
154 | #endif | ||
142 | 155 | ||
143 | /* UARTC1,2 not used on Nano2G */ | 156 | /* UARTC1,2 not used on Nano2G */ |
144 | #ifndef IPOD_NANO2G | 157 | #ifndef IPOD_NANO2G |