diff -Nur linux-2.6.24.vanilla/arch/arm/mach-sa1100/simpad.c linux-2.6.24/arch/arm/mach-sa1100/simpad.c --- linux-2.6.24.vanilla/arch/arm/mach-sa1100/simpad.c 2008-10-04 21:47:24.000000000 +0200 +++ linux-2.6.24/arch/arm/mach-sa1100/simpad.c 2008-10-04 22:01:20.000000000 +0200 @@ -1,5 +1,15 @@ /* * linux/arch/arm/mach-sa1100/simpad.c + * + * 2007/04/11 mrdata: + * - insert simpad_uart_set_mctrl() + * simpad_uart_get_mctrl() + * - internal RS232/DECT/Bluetooth + * works again (based on 2.4 simpad-serial.patch) + * - added cs3_ro + * + * 2007/04/12 Bernhard Guillon: + * -added gpio_keys (based on h3000.c from hh.org) */ #include @@ -9,6 +19,9 @@ #include #include #include + +#include + #include #include #include @@ -27,12 +40,21 @@ #include #include +#include +#include #include #include "generic.h" +long cs3_ro; long cs3_shadow; +long get_cs3_ro(void) +{ + cs3_ro = *(CS3BUSTYPE *)(CS3_BASE); + return cs3_ro; +} + long get_cs3_shadow(void) { return cs3_shadow; @@ -55,9 +77,12 @@ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow; } +EXPORT_SYMBOL(get_cs3_ro); +EXPORT_SYMBOL(get_cs3_shadow); EXPORT_SYMBOL(set_cs3_bit); EXPORT_SYMBOL(clear_cs3_bit); + static struct map_desc simpad_io_desc[] __initdata = { { /* MQ200 */ .virtual = 0xf2800000, @@ -73,23 +98,71 @@ }; +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 (state) - { - clear_cs3_bit(RS232_ON); - clear_cs3_bit(DECT_POWER_ON); - }else - { - set_cs3_bit(RS232_ON); - set_cs3_bit(DECT_POWER_ON); - } - } + if (port->mapbase == (u_int)&Ser3UTCR0) { + if (state) + { + clear_cs3_bit(RS232_ON); + /* clear_cs3_bit(DECT_POWER_ON); */ + }else + { + set_cs3_bit(RS232_ON); + /* set_cs3_bit(DECT_POWER_ON); */ + } + } } + 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, }; @@ -135,7 +208,6 @@ }; - static void __init simpad_map_io(void) { sa1100_map_io(); @@ -144,23 +216,45 @@ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON); - - + sa1100_register_uart_fns(&simpad_port_fns); sa1100_register_uart(0, 3); /* serial interface */ sa1100_register_uart(1, 1); /* DECT */ - // Reassign UART 1 pins + /* Reassign UART 1 pins */ + /* TEST SOME OLD KERNEL STUFF INSTEAD GAFR |= GPIO_UART_TXD | GPIO_UART_RXD; GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15; GPDR &= ~GPIO_UART_RXD; PPAR |= PPAR_UPR; + */ + + // 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 up registers for sleep mode. */ - PWER = PWER_GPIO0| PWER_RTC; PGSR = 0x818; PCFR = 0; @@ -171,9 +265,10 @@ sa11x0_set_mcp_data(&simpad_mcp_data); } + static void simpad_power_off(void) { - local_irq_disable(); // was cli + local_irq_disable(); /* was cli */ set_cs3(0x800); /* only SD_MEDIAQ */ /* disable internal oscillator, float CS lines */ @@ -191,31 +286,52 @@ while(1); local_irq_enable(); /* we won't ever call it */ +} -} +/* + * gpio_keys +*/ + +static struct gpio_keys_button simpad_button_table[] = { + { KEY_POWER, IRQ_GPIO_POWER_BUTTON, 1, "power button" }, +}; + +static struct gpio_keys_platform_data simpad_keys_data = { + .buttons = simpad_button_table, + .nbuttons = ARRAY_SIZE(simpad_button_table), +}; + +static struct platform_device simpad_keys = { + .name = "gpio-keys", + .dev = { + .platform_data = &simpad_keys_data, + }, +}; /* * MediaQ Video Device */ + static struct platform_device simpad_mq200fb = { .name = "simpad-mq200", .id = 0, }; + static struct platform_device *devices[] __initdata = { - &simpad_mq200fb + &simpad_keys, + &simpad_mq200fb, }; - static int __init simpad_init(void) { int ret; pm_power_off = simpad_power_off; - + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if(ret) printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device"); diff -Nur linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h --- linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h 2008-10-04 21:47:17.000000000 +0200 +++ linux-2.6.27/arch/arm/mach-sa1100/include/mach/simpad.h 2008-10-04 22:00:57.000000000 +0200 @@ -12,11 +12,12 @@ #define __ASM_ARCH_SIMPAD_H -#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 #define GPIO_UART1_DSR GPIO_GPIO6 +#define GPIO_UART1_RI GPIO_GPIO19 #define GPIO_UART3_RTS GPIO_GPIO12 #define GPIO_UART3_DTR GPIO_GPIO16 @@ -48,9 +49,9 @@ #define GPIO_SMART_CARD GPIO_GPIO10 #define IRQ_GPIO_SMARD_CARD IRQ_GPIO10 -// CS3 Latch is write only, a shadow is necessary +// CS3 Latch is write only 16-bit , a shadow is necessary -#define CS3BUSTYPE unsigned volatile long +#define CS3BUSTYPE unsigned volatile long #define CS3_BASE 0xf1000000 #define VCC_5V_EN 0x0001 // For 5V PCMCIA @@ -70,43 +71,17 @@ #define ENABLE_5V 0x4000 // Enable 5V circuit #define RESET_SIMCARD 0x8000 -#define RS232_ENABLE 0x0440 -#define PCMCIAMASK 0x402f +// CS3 Latch is readable only 8-bit interest +#define PCMCIA_BVD1 0x0001 +#define PCMCIA_BVD2 0x0002 +#define PCMCIA_VS1 0x0004 // PCMCIA card voltage select +#define PCMCIA_VS2 0x0008 // PCMCIA card voltage select, if both are in high state -> 5V PCMCIA card +#define LOCK_IND 0x0010 +#define CHARGING_STATE 0x0020 // Ladestatus +#define PCMCIA_SHORT 0x0040 // low active -struct simpad_battery { - unsigned char ac_status; /* line connected yes/no */ - unsigned char status; /* battery loading yes/no */ - unsigned char percentage; /* percentage loaded */ - unsigned short life; /* life till empty */ -}; - -/* These should match the apm_bios.h definitions */ -#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00 -#define SIMPAD_AC_STATUS_AC_ONLINE 0x01 -#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */ -#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff - -/* These bitfields are rarely "or'd" together */ -#define SIMPAD_BATT_STATUS_HIGH 0x01 -#define SIMPAD_BATT_STATUS_LOW 0x02 -#define SIMPAD_BATT_STATUS_CRITICAL 0x04 -#define SIMPAD_BATT_STATUS_CHARGING 0x08 -#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10 -#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */ -#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */ -#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */ -#define SIMPAD_BATT_STATUS_NOBATT 0x80 -#define SIMPAD_BATT_STATUS_UNKNOWN 0xff - -extern int simpad_get_battery(struct simpad_battery* ); +#define RS232_ENABLE 0x0440 +#define PCMCIAMASK 0x402f #endif // __ASM_ARCH_SIMPAD_H - - - - - - - -