summaryrefslogtreecommitdiff
path: root/recipes/linux/opensimpad/simpad-serial.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes/linux/opensimpad/simpad-serial.patch')
-rw-r--r--recipes/linux/opensimpad/simpad-serial.patch267
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
+