From 8fb67f48ab57770c3233352de17846a8a773192a Mon Sep 17 00:00:00 2001 From: Cástor Muñoz Date: Thu, 12 May 2016 06:47:38 +0200 Subject: 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 --- firmware/target/arm/s5l8702/uart-s5l8702.c | 155 +++++++++++++++++------------ 1 file changed, 89 insertions(+), 66 deletions(-) (limited to 'firmware/target/arm/s5l8702/uart-s5l8702.c') 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 @@ * KIND, either express or implied. * ****************************************************************************/ - -/* Include Standard files */ -#include -#include -#include +#include +#include #include "config.h" #include "cpu.h" #include "system.h" -#include "kernel.h" #include "s5l8702.h" -#include "uc8702.h" -#include "uart-s5l8702.h" +#include "uc870x.h" -/* s5l8702 UART configuration */ -struct uartc s5l8702_uart = { - .baddr = S5L8702_UART_BASE +/* + * s5l8702 UC870X HW: 1 UARTC, 4 ports + */ +static struct uartc_port *uartc_port_l[UARTC_N_PORTS]; +const struct uartc s5l8702_uartc = +{ + .id = 0, + .baddr = UARTC_BASE_ADDR, + .port_off = UARTC_PORT_OFFSET, + .n_ports = UARTC_N_PORTS, + .port_l = uartc_port_l, }; /* * Device level functions specific to S5L8702 */ -void uart_gpio_control(int port_id, bool onoff) +void uart_target_enable_gpio(int uart_id, int port_id) { - if (onoff) { - switch (port_id) { - case 0: - /* configure UART0 Tx/Rx GPIO ports */ - PCON0 = (PCON0 & 0xff00ffff) | 0x00220000; - break; - case 1: - /* configure UART1 GPIO ports, including RTS/CTS signals */ - PCOND = (PCOND & 0xff0000ff) | 0x00222200; - break; - case 2: - case 3: - /* unknown, probably UART3/4 not routed on s5l8702 */ - default: - break; - } + (void) uart_id; + switch (port_id) { + case 0: + /* configure UART0 Tx/Rx GPIO ports */ + PCON0 = (PCON0 & 0xff00ffff) | 0x00220000; + break; + case 1: + /* configure UART1 GPIO ports, including RTS/CTS signals */ + PCOND = (PCOND & 0xff0000ff) | 0x00222200; + break; + case 2: + case 3: + /* unknown */ + default: + break; } - else { +} + +void uart_target_disable_gpio(int uart_id, int port_id) +{ + (void) uart_id; + switch (port_id) { /* configure minimal power consumption */ - switch (port_id) { - case 0: - PCON0 = (PCON0 & 0xff00ffff) | 0x00ee0000; - break; - case 1: - PCOND = (PCOND & 0xff0000ff) | 0x00eeee00; - break; - case 2: - case 3: - default: - break; - } + case 0: + PCON0 = (PCON0 & 0xff00ffff) | 0x00ee0000; + break; + case 1: + PCOND = (PCOND & 0xff0000ff) | 0x00eeee00; + break; + case 2: + case 3: + default: + break; } } -/* reset s5l8702 uart related hardware */ -static void s5l8702_uart_hw_init(void) +void uart_target_enable_irq(int uart_id, int port_id) { - for (int id = 0; id < S5L8702_UART_PORT_MAX; id++) { - VIC0INTENCLEAR = 1 << IRQ_UART(id); /* mask INT */ - uart_gpio_control(id, 0); - } + (void) uart_id; + VIC0INTENABLE = 1 << IRQ_UART(port_id); } -void uart_init(void) +void uart_target_disable_irq(int uart_id, int port_id) { - s5l8702_uart_hw_init(); - PWRCON(1) &= ~(1 << (CLOCKGATE_UART - 32)); /* on */ - uartc_open(&s5l8702_uart); + (void) uart_id; + VIC0INTENCLEAR = 1 << IRQ_UART(port_id); } -void uart_close(void) +void uart_target_clear_irq(int uart_id, int port_id) { - uartc_close(&s5l8702_uart); - PWRCON(1) |= (1 << (CLOCKGATE_UART - 32)); /* off */ - s5l8702_uart_hw_init(); + (void) uart_id; + (void) port_id; } -void uart_port_init(struct uartc_port *port) +void uart_target_enable_clocks(int uart_id) { - uart_gpio_control(port->id, 1); - uartc_port_open(port); - VIC0INTENABLE = 1 << IRQ_UART(port->id); /* unmask INT */ + (void) uart_id; + PWRCON(1) &= ~(1 << (CLOCKGATE_UARTC - 32)); } -void uart_port_close(struct uartc_port *port) +void uart_target_disable_clocks(int uart_id) { - VIC0INTENCLEAR = 1 << IRQ_UART(port->id); /* mask INT */ - uartc_port_close(port); - uart_gpio_control(port->id, 0); + (void) uart_id; + PWRCON(1) |= (1 << (CLOCKGATE_UARTC - 32)); } -/* ISRs */ +/* + * ISRs + */ + +/* On Classic, PORT0 interrupts are not used when iAP is disabled */ +#if !defined(IPOD_6G) || defined(IPOD_ACCESSORY_PROTOCOL) void ICODE_ATTR INT_UART0(void) { - uartc_callback(&s5l8702_uart, 0); + uartc_callback(&s5l8702_uartc, 0); } +#endif +/* PORT1,2,3 not used on Classic */ +#ifndef IPOD_6G void ICODE_ATTR INT_UART1(void) { - uartc_callback(&s5l8702_uart, 1); + uartc_callback(&s5l8702_uartc, 1); +} + +void ICODE_ATTR INT_UART2(void) +{ + uartc_callback(&s5l8702_uartc, 2); +} + +void ICODE_ATTR INT_UART3(void) +{ + uartc_callback(&s5l8702_uartc, 3); +} +#endif + +/* Main init */ +void uart_init(void) +{ + uartc_open(&s5l8702_uartc); } -- cgit v1.2.3