diff options
Diffstat (limited to 'recipes/linux/opensimpad/simpad-serial.patch')
-rw-r--r-- | recipes/linux/opensimpad/simpad-serial.patch | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/recipes/linux/opensimpad/simpad-serial.patch b/recipes/linux/opensimpad/simpad-serial.patch new file mode 100644 index 0000000000..e54c682a06 --- /dev/null +++ b/recipes/linux/opensimpad/simpad-serial.patch @@ -0,0 +1,267 @@ + +# +# Patch managed by http://www.holgerschurig.de/patcher.html +# + +--- linux-2.4.27/include/asm-arm/arch-sa1100/simpad.h~simpad-serial ++++ linux-2.4.27/include/asm-arm/arch-sa1100/simpad.h +@@ -16,7 +16,7 @@ + #error "include <asm/hardware.h> instead" + #endif + +-#define GPIO_UART1_RTS GPIO_GPIO14 ++#define GPIO_UART1_RTS GPIO_GPIO9 + #define GPIO_UART1_DTR GPIO_GPIO7 + #define GPIO_UART1_CTS GPIO_GPIO8 + #define GPIO_UART1_DCD GPIO_GPIO23 +@@ -31,12 +31,12 @@ + #define GPIO_POWER_BUTTON GPIO_GPIO0 + #define GPIO_UCB1300_IRQ GPIO_GPIO (22) /* UCB GPIO and touchscreen */ + +-#define IRQ_UART1_CTS IRQ_GPIO15 +-#define IRQ_UART1_DCD GPIO_GPIO23 +-#define IRQ_UART1_DSR GPIO_GPIO6 +-#define IRQ_UART3_CTS GPIO_GPIO13 +-#define IRQ_UART3_DCD GPIO_GPIO18 +-#define IRQ_UART3_DSR GPIO_GPIO17 ++#define IRQ_GPIO_UART1_CTS IRQ_GPIO8 ++#define IRQ_GPIO_UART1_DCD IRQ_GPIO23 ++#define IRQ_GPIO_UART1_DSR IRQ_GPIO6 ++#define IRQ_GPIO_UART3_CTS IRQ_GPIO13 ++#define IRQ_GPIO_UART3_DCD IRQ_GPIO18 ++#define IRQ_GPIO_UART3_DSR IRQ_GPIO17 + + #define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22 + #define IRQ_GPIO_POWER_BUTTON IRQ_GPIO0 +--- linux-2.4.27/arch/arm/mach-sa1100/simpad.c~simpad-serial ++++ linux-2.4.27/arch/arm/mach-sa1100/simpad.c +@@ -22,9 +22,11 @@ + + #include "generic.h" + ++#undef SIMPAD_UART_USE_IRQ // irq handling on CTS/DCD doesn't work yet ++ + long cs3_shadow; + +-long get_cs3_shadow() ++long get_cs3_shadow(void) + { + return cs3_shadow; + } +@@ -107,18 +109,170 @@ + LAST_DESC + }; + ++#define SER_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg) ++ ++static void simpad_uart_set_mctrl(struct uart_port *port, u_int mctrl) ++{ ++ if (port->mapbase == _Ser1UTCR0) { ++ /* internal serial port (ttySA1, DECT/Bluetooth) */ ++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART1_RTS; ++ else GPSR = GPIO_UART1_RTS; ++ ++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART1_DTR; ++ else GPSR = GPIO_UART1_DTR; ++ } ++ ++ else if (port->mapbase == _Ser3UTCR0) { ++ /* external serial port (ttySA0, RS232) */ ++ if (mctrl & TIOCM_RTS) GPCR = GPIO_UART3_RTS; ++ else GPSR = GPIO_UART3_RTS; ++ ++ if (mctrl & TIOCM_DTR) GPCR = GPIO_UART3_DTR; ++ else GPSR = GPIO_UART3_DTR; ++ } ++} ++ ++static u_int simpad_uart_get_mctrl(struct uart_port *port) ++{ ++ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; ++ ++ if (port->mapbase == _Ser1UTCR0) { ++ /* internal serial port (ttySA1, DECT/Bluetooth) */ ++ int gplr = GPLR; ++ if (gplr & GPIO_UART1_DCD) ret &= ~TIOCM_CD; ++ if (gplr & GPIO_UART1_CTS) ret &= ~TIOCM_CTS; ++ if (gplr & GPIO_UART1_DSR) ret &= ~TIOCM_DSR; ++ } ++ ++ else if (port->mapbase == _Ser3UTCR0) { ++ /* external serial port (ttySA0, RS232) */ ++ int gplr = GPLR; ++ if (gplr & GPIO_UART3_DCD) ret &= ~TIOCM_CD; ++ if (gplr & GPIO_UART3_CTS) ret &= ~TIOCM_CTS; ++ if (gplr & GPIO_UART3_DSR) ret &= ~TIOCM_DSR; ++ } ++ return ret; ++} ++ + static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate) + { +- if (port->mapbase == (u_int)&Ser1UTCR0) { ++ if (port->mapbase == (u_int)&Ser3UTCR0) { + if (state) + clear_cs3_bit(RS232_ON); + else + set_cs3_bit(RS232_ON); + } + } ++/* ++ * Enable/Disable wake up events for this serial port. ++ * Obviously, we only support this on the normal COM port. ++ */ ++static int simpad_uart_set_wake(struct uart_port *port, u_int enable) ++{ ++ int err = -EINVAL; ++ ++#if 0 // TODO: port management ++ if (port->mapbase == _Ser3UTCR0) { ++ if (enable) ++ PWER |= PWER_GPIO23 | PWER_GPIO25 ; /* DCD and CTS */ ++ else ++ PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */ ++ err = 0; ++ } ++#endif ++ ++ return err; ++} ++ ++#ifdef SIMPAD_UART_USE_IRQ ++static void simpad_uart1_dcd_intr(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ struct uart_port *port = dev_id; ++ /* Note: should only call this if something has changed */ ++ uart_handle_dcd_change(port, !(GPLR & GPIO_UART1_DCD)); ++} ++ ++static void simpad_uart1_cts_intr(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ struct uart_port *port = dev_id; ++ /* Note: should only call this if something has changed */ ++ uart_handle_cts_change(port, !(GPLR & GPIO_UART1_CTS)); ++} ++ ++static void simpad_uart3_dcd_intr(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ struct uart_port *port = dev_id; ++ /* Note: should only call this if something has changed */ ++ uart_handle_dcd_change(port, !(GPLR & GPIO_UART3_DCD)); ++} ++ ++static void simpad_uart3_cts_intr(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ struct uart_port *port = dev_id; ++ /* Note: should only call this if something has changed */ ++ uart_handle_cts_change(port, !(GPLR & GPIO_UART3_CTS)); ++} ++#endif ++ ++static int simpad_uart_open(struct uart_port *port) ++{ ++ int ret = 0; ++#ifdef SIMPAD_UART_USE_IRQ ++ if (port->mapbase == _Ser1UTCR0) { ++ set_GPIO_IRQ_edge(GPIO_UART1_DCD|GPIO_UART1_CTS, ++ GPIO_BOTH_EDGES); ++ ++ ret = request_irq(IRQ_GPIO_UART1_DCD, simpad_uart1_dcd_intr, ++ 0, "UART1 DCD", port); ++ if (ret) ++ return ret; ++ ++ ret = request_irq(IRQ_GPIO_UART1_CTS, simpad_uart1_cts_intr, ++ 0, "UART1 CTS", port); ++ if (ret) ++ free_irq(IRQ_GPIO_UART1_DCD, port); ++ } ++ ++ else if (port->mapbase == _Ser3UTCR0) { ++ set_GPIO_IRQ_edge(GPIO_UART3_DCD|GPIO_UART3_CTS, ++ GPIO_BOTH_EDGES); ++ ++ ret = request_irq(IRQ_GPIO_UART3_DCD, simpad_uart3_dcd_intr, ++ 0, "UART3 DCD", port); ++ if (ret) ++ return ret; ++ ++ ret = request_irq(IRQ_GPIO_UART3_CTS, simpad_uart3_cts_intr, ++ 0, "UART3 CTS", port); ++ if (ret) ++ free_irq(IRQ_GPIO_UART3_DCD, port); ++ } ++#endif ++ return ret; ++} ++ ++static void simpad_uart_close(struct uart_port *port) ++{ ++#ifdef SIMPAD_UART_USE_IRQ ++ if (port->mapbase == _Ser1UTCR0) { ++ free_irq(IRQ_GPIO_UART1_DCD, port); ++ free_irq(IRQ_GPIO_UART1_CTS, port); ++ } ++ ++ else if (port->mapbase == _Ser3UTCR0) { ++ free_irq(IRQ_GPIO_UART3_DCD, port); ++ free_irq(IRQ_GPIO_UART3_CTS, port); ++ } ++#endif ++} + + static struct sa1100_port_fns simpad_port_fns __initdata = { +- .pm = simpad_uart_pm, ++ .set_mctrl = simpad_uart_set_mctrl, ++ .get_mctrl = simpad_uart_get_mctrl, ++ .pm = simpad_uart_pm, ++ .set_wake = simpad_uart_set_wake, ++ .open = simpad_uart_open, ++ .close = simpad_uart_close, + }; + + static void __init simpad_map_io(void) +@@ -129,13 +283,32 @@ + set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | + ENABLE_5V | nRESET_SIMCARD); + ++ sa1100_register_uart_fns(&simpad_port_fns); ++ + //It is only possible to register 3 UART in serial_sa1100.c + sa1100_register_uart(0, 3); + sa1100_register_uart(1, 1); + ++ // txd and rxd use their alternate function + GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD); ++ ++ // the control lines are gpio ++ GAFR &= ~(GPIO_UART1_RTS | GPIO_UART1_CTS | GPIO_UART1_DCD); ++ GAFR &= ~(GPIO_UART1_DSR | GPIO_UART1_DTR); ++ GAFR &= ~(GPIO_UART3_RTS | GPIO_UART3_CTS | GPIO_UART3_DCD); ++ GAFR &= ~(GPIO_UART3_DSR | GPIO_UART3_DTR); ++ ++ // txd, rts and dtr are outputs + GPDR |= GPIO_UART_TXD; ++ GPDR |= GPIO_UART1_RTS | GPIO_UART3_RTS; ++ GPDR |= GPIO_UART1_DTR | GPIO_UART3_DTR; ++ ++ // cts, dcd, dsr and rxd are inputs ++ GPDR &= ~(GPIO_UART1_CTS | GPIO_UART3_CTS); ++ GPDR &= ~(GPIO_UART1_DCD | GPIO_UART3_DCD); ++ GPDR &= ~(GPIO_UART1_DSR | GPIO_UART3_DSR); + GPDR &= ~GPIO_UART_RXD; ++ + PPAR |= PPAR_UPR; + + set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE); +--- linux-2.4.27/drivers/video/mq200fb.c~simpad-serial ++++ linux-2.4.27/drivers/video/mq200fb.c +@@ -672,7 +672,7 @@ + + #ifdef CONFIG_SA1100_SIMPAD + GPDR |= (1<<3); +- GAFR |= ~(1<<3); ++ GAFR &= ~(1<<3); + GPSR |= (1<<3); + #endif + |