diff options
-rw-r--r-- | firmware/export/s5l8700.h | 36 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/system-s5l8700.c | 29 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/uart-s5l8700.c | 129 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/uart-s5l8701.c | 160 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/uart-target.h | 38 |
5 files changed, 380 insertions, 12 deletions
diff --git a/firmware/export/s5l8700.h b/firmware/export/s5l8700.h index 420212ff3b..e8497ff337 100644 --- a/firmware/export/s5l8700.h +++ b/firmware/export/s5l8700.h | |||
@@ -118,6 +118,13 @@ | |||
118 | #define PLLLOCK (*(REG32_PTR_T)(0x3C500020)) /* PLL lock status register */ | 118 | #define PLLLOCK (*(REG32_PTR_T)(0x3C500020)) /* PLL lock status register */ |
119 | #define PLLCON (*(REG32_PTR_T)(0x3C500024)) /* PLL control register */ | 119 | #define PLLCON (*(REG32_PTR_T)(0x3C500024)) /* PLL control register */ |
120 | #define PWRCON (*(REG32_PTR_T)(0x3C500028)) /* Clock power control register */ | 120 | #define PWRCON (*(REG32_PTR_T)(0x3C500028)) /* Clock power control register */ |
121 | #if CONFIG_CPU==S5L8701 | ||
122 | #define CLOCKGATE_UARTC0 8 | ||
123 | #define CLOCKGATE_UARTC1 9 | ||
124 | #define CLOCKGATE_UARTC2 13 | ||
125 | #else /* S5L8700 */ | ||
126 | #define CLOCKGATE_UARTC 8 | ||
127 | #endif | ||
121 | #define PWRMODE (*(REG32_PTR_T)(0x3C50002C)) /* Power mode control register */ | 128 | #define PWRMODE (*(REG32_PTR_T)(0x3C50002C)) /* Power mode control register */ |
122 | #define SWRCON (*(REG32_PTR_T)(0x3C500030)) /* Software reset control register */ | 129 | #define SWRCON (*(REG32_PTR_T)(0x3C500030)) /* Software reset control register */ |
123 | #define RSTSR (*(REG32_PTR_T)(0x3C500034)) /* Reset status register */ | 130 | #define RSTSR (*(REG32_PTR_T)(0x3C500034)) /* Reset status register */ |
@@ -136,11 +143,16 @@ | |||
136 | #define INTMSK_TIMERD (1<<5) | 143 | #define INTMSK_TIMERD (1<<5) |
137 | #define INTMSK_ECC (1<<19) | 144 | #define INTMSK_ECC (1<<19) |
138 | #define INTMSK_USB_OTG (1<<16) | 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) | ||
139 | #else | 149 | #else |
140 | #define INTMSK_TIMERA (1<<5) | 150 | #define INTMSK_TIMERA (1<<5) |
141 | #define INTMSK_TIMERB (1<<7) | 151 | #define INTMSK_TIMERB (1<<7) |
142 | #define INTMSK_TIMERC (1<<8) | 152 | #define INTMSK_TIMERC (1<<8) |
143 | #define INTMSK_TIMERD (1<<9) | 153 | #define INTMSK_TIMERD (1<<9) |
154 | #define INTMSK_UART0 (1<<22) | ||
155 | #define INTMSK_UART1 (1<<14) | ||
144 | #endif | 156 | #endif |
145 | #define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */ | 157 | #define PRIORITY (*(REG32_PTR_T)(0x39C0000C)) /* IRQ priority control register */ |
146 | #define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */ | 158 | #define INTPND (*(REG32_PTR_T)(0x39C00010)) /* Indicates the interrupt request status. */ |
@@ -577,6 +589,29 @@ | |||
577 | #define PCON_SDRAM (*(REG32_PTR_T)(0x3CF000F4)) /* Configures the pins of port sdram */ | 589 | #define PCON_SDRAM (*(REG32_PTR_T)(0x3CF000F4)) /* Configures the pins of port sdram */ |
578 | 590 | ||
579 | /* 25. UART */ | 591 | /* 25. UART */ |
592 | #if CONFIG_CPU==S5L8701 | ||
593 | /* s5l8701 UC870X HW: 3 UARTC, 1 port per UARTC */ | ||
594 | #define S5L8701_N_UARTC 3 | ||
595 | #define S5L8701_N_PORTS 3 | ||
596 | |||
597 | #define UARTC0_BASE_ADDR 0x3CC00000 | ||
598 | #define UARTC0_N_PORTS 1 | ||
599 | #define UARTC0_PORT_OFFSET 0x0 | ||
600 | #define UARTC1_BASE_ADDR 0x3CC08000 | ||
601 | #define UARTC1_N_PORTS 1 | ||
602 | #define UARTC1_PORT_OFFSET 0x0 | ||
603 | #define UARTC2_BASE_ADDR 0x3CC0C000 | ||
604 | #define UARTC2_N_PORTS 1 | ||
605 | #define UARTC2_PORT_OFFSET 0x0 | ||
606 | |||
607 | #else | ||
608 | /* s5l8700 UC870X HW: 1 UARTC, 2 ports */ | ||
609 | #define S5L8700_N_UARTC 1 | ||
610 | #define S5L8700_N_PORTS 2 | ||
611 | |||
612 | #define UARTC_BASE_ADDR 0x3CC00000 | ||
613 | #define UARTC_N_PORTS 2 | ||
614 | #define UARTC_PORT_OFFSET 0x8000 | ||
580 | 615 | ||
581 | /* UART 0 */ | 616 | /* UART 0 */ |
582 | #define ULCON0 (*(REG32_PTR_T)(0x3CC00000)) /* Line Control Register */ | 617 | #define ULCON0 (*(REG32_PTR_T)(0x3CC00000)) /* Line Control Register */ |
@@ -603,6 +638,7 @@ | |||
603 | #define UTXH1 (*(REG32_PTR_T)(0x3CC08020)) /* Transmit Buffer Register */ | 638 | #define UTXH1 (*(REG32_PTR_T)(0x3CC08020)) /* Transmit Buffer Register */ |
604 | #define URXH1 (*(REG32_PTR_T)(0x3CC08024)) /* Receive Buffer Register */ | 639 | #define URXH1 (*(REG32_PTR_T)(0x3CC08024)) /* Receive Buffer Register */ |
605 | #define UBRDIV1 (*(REG32_PTR_T)(0x3CC08028)) /* Baud Rate Divisor Register */ | 640 | #define UBRDIV1 (*(REG32_PTR_T)(0x3CC08028)) /* Baud Rate Divisor Register */ |
641 | #endif | ||
606 | 642 | ||
607 | /* 26. LCD INTERFACE CONTROLLER */ | 643 | /* 26. LCD INTERFACE CONTROLLER */ |
608 | #if CONFIG_CPU==S5L8700 | 644 | #if CONFIG_CPU==S5L8700 |
diff --git a/firmware/target/arm/s5l8700/system-s5l8700.c b/firmware/target/arm/s5l8700/system-s5l8700.c index 601955fbac..728fea0432 100644 --- a/firmware/target/arm/s5l8700/system-s5l8700.c +++ b/firmware/target/arm/s5l8700/system-s5l8700.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "storage.h" | 27 | #include "storage.h" |
28 | #include "pmu-target.h" | 28 | #include "pmu-target.h" |
29 | #endif | 29 | #endif |
30 | #include "uart-target.h" | ||
30 | 31 | ||
31 | /* MIUSDPARA_BOOST taken from OF (see crt0.S). MIUSDPARA_UNBOOST is derived | 32 | /* MIUSDPARA_BOOST taken from OF (see crt0.S). MIUSDPARA_UNBOOST is derived |
32 | * from MIUSDPARA_BOOST due to the fact that the minimum allowed DRAM timings | 33 | * from MIUSDPARA_BOOST due to the fact that the minimum allowed DRAM timings |
@@ -63,7 +64,7 @@ default_interrupt(INT_DMA); | |||
63 | default_interrupt(INT_ALARM_RTC); | 64 | default_interrupt(INT_ALARM_RTC); |
64 | default_interrupt(INT_PRI_RTC); | 65 | default_interrupt(INT_PRI_RTC); |
65 | default_interrupt(RESERVED1); | 66 | default_interrupt(RESERVED1); |
66 | default_interrupt(INT_UART); | 67 | default_interrupt(INT_UART1); |
67 | default_interrupt(INT_USB_HOST); | 68 | default_interrupt(INT_USB_HOST); |
68 | default_interrupt(INT_USB_FUNC); | 69 | default_interrupt(INT_USB_FUNC); |
69 | default_interrupt(INT_LCDC_0); | 70 | default_interrupt(INT_LCDC_0); |
@@ -81,9 +82,10 @@ default_interrupt(RESERVED2); | |||
81 | default_interrupt(INT_MSTICK); | 82 | default_interrupt(INT_MSTICK); |
82 | default_interrupt(INT_ADC_WAKEUP); | 83 | default_interrupt(INT_ADC_WAKEUP); |
83 | default_interrupt(INT_ADC); | 84 | default_interrupt(INT_ADC); |
84 | default_interrupt(INT_UNK1); | 85 | #if CONFIG_CPU==S5L8701 |
85 | default_interrupt(INT_UNK2); | 86 | default_interrupt(INT_UNK); |
86 | default_interrupt(INT_UNK3); | 87 | default_interrupt(INT_UART2); |
88 | #endif | ||
87 | 89 | ||
88 | 90 | ||
89 | void INT_TIMER(void) | 91 | void INT_TIMER(void) |
@@ -98,16 +100,16 @@ void INT_TIMER(void) | |||
98 | #if CONFIG_CPU==S5L8701 | 100 | #if CONFIG_CPU==S5L8701 |
99 | static void (* const irqvector[])(void) = | 101 | static void (* const irqvector[])(void) = |
100 | { /* still 90% unverified and probably incorrect */ | 102 | { /* still 90% unverified and probably incorrect */ |
101 | EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMER,INT_WDT,INT_UNK1, | 103 | EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMER,INT_WDT,INT_UART2, |
102 | INT_UNK2,INT_UNK3,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST, | 104 | INT_UNK,INT_UNK,INT_DMA,INT_ALARM_RTC,INT_UART1,INT_UNK,INT_UNK,INT_USB_HOST, |
103 | INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_CALM,INT_ATA,INT_UART0,INT_SPDIF_OUT,INT_ECC, | 105 | INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_CALM,INT_ATA,INT_UNK,INT_SPDIF_OUT,INT_ECC, |
104 | INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC | 106 | INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC |
105 | }; | 107 | }; |
106 | #else | 108 | #else |
107 | static void (* const irqvector[])(void) = | 109 | static void (* const irqvector[])(void) = |
108 | { | 110 | { |
109 | EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMERA,INT_WDT,INT_TIMERB, | 111 | EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMERA,INT_WDT,INT_TIMERB, |
110 | INT_TIMERC,INT_TIMERD,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST, | 112 | INT_TIMERC,INT_TIMERD,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART1,INT_USB_HOST, |
111 | INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_ECC,INT_CALM,INT_ATA,INT_UART0,INT_SPDIF_OUT, | 113 | INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_ECC,INT_CALM,INT_ATA,INT_UART0,INT_SPDIF_OUT, |
112 | INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC | 114 | INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC |
113 | }; | 115 | }; |
@@ -116,16 +118,16 @@ static void (* const irqvector[])(void) = | |||
116 | #if CONFIG_CPU==S5L8701 | 118 | #if CONFIG_CPU==S5L8701 |
117 | static const char * const irqname[] = | 119 | static const char * const irqname[] = |
118 | { /* still 90% unverified and probably incorrect */ | 120 | { /* still 90% unverified and probably incorrect */ |
119 | "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMER","INT_WDT","INT_UNK1", | 121 | "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMER","INT_WDT","INT_UART2", |
120 | "INT_UNK2","INT_UNK3","INT_DMA","INT_ALARM_RTC","INT_PRI_RTC","Reserved","INT_UART","INT_USB_HOST", | 122 | "INT_UNK1","INT_UNK2","INT_DMA","INT_ALARM_RTC","INT_UART1","INT_UNK3","INT_UNK4","INT_USB_HOST", |
121 | "INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_CALM","INT_ATA","INT_UART0","INT_SPDIF_OUT","INT_ECC", | 123 | "INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_CALM","INT_ATA","INT_UNK5","INT_SPDIF_OUT","INT_ECC", |
122 | "INT_SDCI","INT_LCD","INT_WHEEL","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC" | 124 | "INT_SDCI","INT_LCD","INT_WHEEL","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC" |
123 | }; | 125 | }; |
124 | #else | 126 | #else |
125 | static const char * const irqname[] = | 127 | static const char * const irqname[] = |
126 | { | 128 | { |
127 | "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMERA","INT_WDT","INT_TIMERB", | 129 | "EXT0","EXT1","EXT2","EINT_VBUS","EINTG","INT_TIMERA","INT_WDT","INT_TIMERB", |
128 | "INT_TIMERC","INT_TIMERD","INT_DMA","INT_ALARM_RTC","INT_PRI_RTC","Reserved","INT_UART","INT_USB_HOST", | 130 | "INT_TIMERC","INT_TIMERD","INT_DMA","INT_ALARM_RTC","INT_PRI_RTC","Reserved","INT_UART1","INT_USB_HOST", |
129 | "INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_ECC","INT_CALM","INT_ATA","INT_UART0","INT_SPDIF_OUT", | 131 | "INT_USB_FUNC","INT_LCDC_0","INT_LCDC_1","INT_ECC","INT_CALM","INT_ATA","INT_UART0","INT_SPDIF_OUT", |
130 | "INT_SDCI","INT_LCD","INT_WHEEL","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC" | 132 | "INT_SDCI","INT_LCD","INT_WHEEL","INT_IIC","Reserved","INT_MSTICK","INT_ADC_WAKEUP","INT_ADC" |
131 | }; | 133 | }; |
@@ -172,6 +174,9 @@ void system_init(void) | |||
172 | #ifdef IPOD_NANO2G | 174 | #ifdef IPOD_NANO2G |
173 | pmu_init(); | 175 | pmu_init(); |
174 | #endif | 176 | #endif |
177 | #ifdef HAVE_SERIAL | ||
178 | uart_init(); | ||
179 | #endif | ||
175 | } | 180 | } |
176 | 181 | ||
177 | void system_reboot(void) | 182 | void system_reboot(void) |
diff --git a/firmware/target/arm/s5l8700/uart-s5l8700.c b/firmware/target/arm/s5l8700/uart-s5l8700.c new file mode 100644 index 0000000000..80207e94df --- /dev/null +++ b/firmware/target/arm/s5l8700/uart-s5l8700.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2014 by Cástor Muñoz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <stdint.h> | ||
22 | #include <stdbool.h> | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "system.h" | ||
26 | |||
27 | #include "s5l8700.h" | ||
28 | #include "uc870x.h" | ||
29 | |||
30 | |||
31 | /* | ||
32 | * XXX: This code is based on datasheets and NEVER TESTED !!! | ||
33 | */ | ||
34 | |||
35 | |||
36 | /* | ||
37 | * s5l8700 UC870X HW: 1 UARTC, 2 ports | ||
38 | */ | ||
39 | static struct uartc_port *uartc_port_l[UARTC_N_PORTS]; | ||
40 | const struct uartc s5l8700_uartc = | ||
41 | { | ||
42 | .id = 0, | ||
43 | .baddr = UARTC_BASE_ADDR, | ||
44 | .port_off = UARTC_PORT_OFFSET, | ||
45 | .n_ports = UARTC_N_PORTS, | ||
46 | .port_l = uartc_port_l, | ||
47 | }; | ||
48 | |||
49 | static int intmsk_uart[S5L8700_N_PORTS] = { INTMSK_UART0, INTMSK_UART1 }; | ||
50 | |||
51 | /* | ||
52 | * Device level functions specific to S5L8700 | ||
53 | */ | ||
54 | void uart_target_enable_gpio(int uart_id, int port_id) | ||
55 | { | ||
56 | (void) uart_id; | ||
57 | switch (port_id) { | ||
58 | /* configure UARTx Tx/Rx GPIO ports */ | ||
59 | case 0: | ||
60 | PCON0 = (PCON0 & 0x0fff) | 0xa000; | ||
61 | break; | ||
62 | case 1: | ||
63 | PCON6 = (PCON6 & 0xfff00fff) | 0x00044000; | ||
64 | break; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | void uart_target_disable_gpio(int uart_id, int port_id) | ||
69 | { | ||
70 | (void) uart_id; | ||
71 | switch (port_id) { | ||
72 | /* configure default reset values */ | ||
73 | case 0: | ||
74 | PCON0 = (PCON0 & 0x0fff) | 0x0000; | ||
75 | break; | ||
76 | case 1: | ||
77 | PCON6 = (PCON6 & 0xfff00fff) | 0x00000000; | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | void uart_target_enable_irq(int uart_id, int port_id) | ||
83 | { | ||
84 | (void) uart_id; | ||
85 | INTMSK |= intmsk_uart[port_id]; | ||
86 | } | ||
87 | |||
88 | void uart_target_disable_irq(int uart_id, int port_id) | ||
89 | { | ||
90 | (void) uart_id; | ||
91 | INTMSK &= ~intmsk_uart[port_id]; | ||
92 | } | ||
93 | |||
94 | void uart_target_clear_irq(int uart_id, int port_id) | ||
95 | { | ||
96 | (void) uart_id; | ||
97 | SRCPND |= intmsk_uart[port_id]; | ||
98 | } | ||
99 | |||
100 | void uart_target_enable_clocks(int uart_id) | ||
101 | { | ||
102 | (void) uart_id; | ||
103 | PWRCON &= ~(1 << CLOCKGATE_UARTC); | ||
104 | } | ||
105 | |||
106 | void uart_target_disable_clocks(int uart_id) | ||
107 | { | ||
108 | (void) uart_id; | ||
109 | PWRCON |= (1 << CLOCKGATE_UARTC); | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * ISRs | ||
114 | */ | ||
115 | void ICODE_ATTR INT_UART0(void) | ||
116 | { | ||
117 | uartc_callback(&s5l8700_uartc, 0); | ||
118 | } | ||
119 | |||
120 | void ICODE_ATTR INT_UART1(void) | ||
121 | { | ||
122 | uartc_callback(&s5l8700_uartc, 1); | ||
123 | } | ||
124 | |||
125 | /* Main init */ | ||
126 | void uart_init(void) | ||
127 | { | ||
128 | uartc_open(&s5l8700_uartc); | ||
129 | } | ||
diff --git a/firmware/target/arm/s5l8700/uart-s5l8701.c b/firmware/target/arm/s5l8700/uart-s5l8701.c new file mode 100644 index 0000000000..00c9322e47 --- /dev/null +++ b/firmware/target/arm/s5l8700/uart-s5l8701.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2014 by Cástor Muñoz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <stdint.h> | ||
22 | #include <stdbool.h> | ||
23 | |||
24 | #include "config.h" | ||
25 | #include "system.h" | ||
26 | |||
27 | #include "s5l8700.h" | ||
28 | #include "uc870x.h" | ||
29 | |||
30 | |||
31 | /* | ||
32 | * s5l8701 UC870X HW: 3 UARTC, 1 port per UARTC | ||
33 | */ | ||
34 | static struct uartc_port *uartc0_port_l[UARTC0_N_PORTS]; | ||
35 | const struct uartc s5l8701_uartc0 = | ||
36 | { | ||
37 | .id = 0, | ||
38 | .baddr = UARTC0_BASE_ADDR, | ||
39 | .port_off = UARTC0_PORT_OFFSET, | ||
40 | .n_ports = UARTC0_N_PORTS, | ||
41 | .port_l = uartc0_port_l, | ||
42 | }; | ||
43 | |||
44 | /* UARTC1,2 not used on Nano2G */ | ||
45 | #ifndef IPOD_NANO2G | ||
46 | static struct uartc_port *uartc1_port_l[UARTC1_N_PORTS]; | ||
47 | const struct uartc s5l8701_uartc1 = | ||
48 | { | ||
49 | .id = 1, | ||
50 | .baddr = UARTC1_BASE_ADDR, | ||
51 | .port_off = UARTC1_PORT_OFFSET, | ||
52 | .n_ports = UARTC1_N_PORTS, | ||
53 | .port_l = uartc1_port_l, | ||
54 | }; | ||
55 | |||
56 | static struct uartc_port *uartc2_port_l[UARTC2_N_PORTS]; | ||
57 | const struct uartc s5l8701_uartc2 = | ||
58 | { | ||
59 | .id = 2, | ||
60 | .baddr = UARTC2_BASE_ADDR, | ||
61 | .port_off = UARTC2_PORT_OFFSET, | ||
62 | .n_ports = UARTC2_N_PORTS, | ||
63 | .port_l = uartc2_port_l, | ||
64 | }; | ||
65 | #endif | ||
66 | |||
67 | static uint8_t clockgate_uartc[S5L8701_N_UARTC] = { | ||
68 | CLOCKGATE_UARTC0, CLOCKGATE_UARTC1, CLOCKGATE_UARTC2 }; | ||
69 | |||
70 | static int intmsk_uart[S5L8701_N_UARTC] = { | ||
71 | INTMSK_UART0, INTMSK_UART1, INTMSK_UART2 }; | ||
72 | |||
73 | /* | ||
74 | * Device level functions specific to S5L8701 | ||
75 | */ | ||
76 | void uart_target_enable_gpio(int uart_id, int port_id) | ||
77 | { | ||
78 | (void) port_id; | ||
79 | switch (uart_id) { | ||
80 | /* configure UARTx Tx/Rx GPIO ports */ | ||
81 | case 0: | ||
82 | PCON1 = (PCON1 & 0xffffff00) | 0x00000044; | ||
83 | break; | ||
84 | case 1: | ||
85 | case 2: | ||
86 | /* unknown */ | ||
87 | default: | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void uart_target_disable_gpio(int uart_id, int port_id) | ||
93 | { | ||
94 | (void) port_id; | ||
95 | switch (uart_id) { | ||
96 | /* configure minimal power consumption */ | ||
97 | case 0: | ||
98 | PCON1 = (PCON1 & 0xffffff00) | 0x00000011; | ||
99 | break; | ||
100 | case 1: | ||
101 | case 2: | ||
102 | default: | ||
103 | break; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | void uart_target_enable_irq(int uart_id, int port_id) | ||
108 | { | ||
109 | (void) port_id; | ||
110 | INTMSK |= intmsk_uart[uart_id]; | ||
111 | } | ||
112 | |||
113 | void uart_target_disable_irq(int uart_id, int port_id) | ||
114 | { | ||
115 | (void) port_id; | ||
116 | INTMSK &= ~intmsk_uart[uart_id]; | ||
117 | } | ||
118 | |||
119 | void uart_target_clear_irq(int uart_id, int port_id) | ||
120 | { | ||
121 | (void) port_id; | ||
122 | SRCPND |= intmsk_uart[uart_id]; | ||
123 | } | ||
124 | |||
125 | void uart_target_enable_clocks(int uart_id) | ||
126 | { | ||
127 | PWRCON &= ~(1 << clockgate_uartc[uart_id]); | ||
128 | } | ||
129 | |||
130 | void uart_target_disable_clocks(int uart_id) | ||
131 | { | ||
132 | PWRCON |= (1 << clockgate_uartc[uart_id]); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * ISRs | ||
137 | */ | ||
138 | void ICODE_ATTR INT_UART0(void) | ||
139 | { | ||
140 | uartc_callback(&s5l8701_uartc0, 0); | ||
141 | } | ||
142 | |||
143 | /* UARTC1,2 not used on Nano2G */ | ||
144 | #ifndef IPOD_NANO2G | ||
145 | void ICODE_ATTR INT_UART1(void) | ||
146 | { | ||
147 | uartc_callback(&s5l8701_uartc1, 0); | ||
148 | } | ||
149 | |||
150 | void ICODE_ATTR INT_UART2(void) | ||
151 | { | ||
152 | uartc_callback(&s5l8701_uartc2, 0); | ||
153 | } | ||
154 | #endif | ||
155 | |||
156 | /* Main init */ | ||
157 | void uart_init(void) | ||
158 | { | ||
159 | uartc_open(&s5l8701_uartc0); | ||
160 | } | ||
diff --git a/firmware/target/arm/s5l8700/uart-target.h b/firmware/target/arm/s5l8700/uart-target.h new file mode 100644 index 0000000000..d6d45b9073 --- /dev/null +++ b/firmware/target/arm/s5l8700/uart-target.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2014 by Cástor Muñoz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef __UART_TARGET_H__ | ||
22 | #define __UART_TARGET_H__ | ||
23 | |||
24 | /* Define this to show debug data on "View HW Info" */ | ||
25 | /* #define UC870X_DEBUG */ | ||
26 | |||
27 | void uart_init(void); | ||
28 | |||
29 | /* s5l870x low level routines */ | ||
30 | void uart_target_enable_clocks(int uart_id); | ||
31 | void uart_target_disable_clocks(int uart_id); | ||
32 | void uart_target_enable_irq(int uart_id, int port_id); | ||
33 | void uart_target_disable_irq(int uart_id, int port_id); | ||
34 | void uart_target_clear_irq(int uart_id, int port_id); | ||
35 | void uart_target_enable_gpio(int uart_id, int port_id); | ||
36 | void uart_target_disable_gpio(int uart_id, int port_id); | ||
37 | |||
38 | #endif /* __UART_TARGET_H__ */ | ||