SIMpad kernel 2.4.25 serial patches
Till Harbaum <[email protected]> Fri, 24 Sep 2004 17:27:01 +0200
| Newsgroups | gmane.comp.handhelds.openembedded,gmane.comp.handhelds.simpad.linux |
|---|---|
| Organization | BeeCon GmbH |
| Message-ID | <[email protected]> |
Hi all, although this patch does not have the effect i hoped (allowing bluetooth > 230kbit/s and simultaneous blitter operation) i'd like to get it included anyway. This patch adds full serial support for both the internal (dect/bluetooth) and external rs232. The patch enables the control signals CTS/RTS/DCD/DSR and DTR. It should only have minor influences on current setups. These are e.g. the fact, that linux now closes a serial session whenever the rs232 connector is pulled (since it now detects, that dcd drops). Furthermore this patch fixes a severe bug in the mq200fb driver that affected all gpio pins (except the one it was meant to). Can anyone please apply this patch and my last one? Both do not break existing interfaces or the like. Ciao, Till -- Dr.-Ing. Till Harbaum Tel.: +49 721 4998963 BeeCon GmbH Fax: +49 721 4998962 Haid-und-Neu Strasse 7, 76131 Karlsruhe Mobil: +49 179 9087904 [email protected] http://www.beecon.de _______________________________________________ Oe mailing list [email protected] https://handhelds.org/mailman/listinfo/oe
kernel-simpad-serial.patch
(text/x-diff, 7.4 KB)
--- include/asm-arm/arch-sa1100/simpad.h.orig 2004-09-23 14:28:07.000000000 +0200
+++ include/asm-arm/arch-sa1100/simpad.h 2004-09-23 19:33:33.000000000 +0200
@@ -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
--- arch/arm/mach-sa1100/simpad.c.orig 2004-09-24 17:15:46.000000000 +0200
+++ arch/arm/mach-sa1100/simpad.c 2004-09-24 17:09:52.000000000 +0200
@@ -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;
}
@@ -102,18 +104,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)
@@ -124,13 +278,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);
--- drivers/video/mq200fb.c~ 2004-09-21 16:11:48.000000000 +0200
+++ drivers/video/mq200fb.c 2004-09-24 13:58:21.000000000 +0200
@@ -699,7 +699,7 @@
#ifdef CONFIG_SA1100_SIMPAD
GPDR |= (1<<3);
- GAFR |= ~(1<<3);
+ GAFR &= ~(1<<3);
GPSR |= (1<<3);
#endif