diff options
Diffstat (limited to 'packages/linux/linux-ezx/ezx_core.patch')
-rw-r--r-- | packages/linux/linux-ezx/ezx_core.patch | 15352 |
1 files changed, 0 insertions, 15352 deletions
diff --git a/packages/linux/linux-ezx/ezx_core.patch b/packages/linux/linux-ezx/ezx_core.patch deleted file mode 100644 index 88867f621a..0000000000 --- a/packages/linux/linux-ezx/ezx_core.patch +++ /dev/null @@ -1,15352 +0,0 @@ -This is the core patch adding EZX support to the kernel - -Index: linux-2.6.16.5-a/arch/arm/boot/compressed/head-xscale.S -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/boot/compressed/head-xscale.S 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/boot/compressed/head-xscale.S 2006-05-04 17:07:04.000000000 +0200 -@@ -54,3 +54,6 @@ - str r1, [r0, #0x18] - #endif - -+#ifdef CONFIG_ARCH_EZX -+ mov r7, #MACH_TYPE_EZX -+#endif -Index: linux-2.6.16.5-a/arch/arm/boot/compressed/head.S -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/boot/compressed/head.S 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/boot/compressed/head.S 2006-05-04 17:07:04.000000000 +0200 -@@ -10,6 +10,7 @@ - #include <linux/config.h> - #include <linux/linkage.h> - -+#define DEBUG - /* - * Debugging stuff - * -@@ -111,6 +112,11 @@ - mov r0, r0 - .endr - -+ inituart r10, r11 -+ -+ mov r1, #0x300 @ mach_id 0x363 is official EZX -+ orr r1, r1, #0x63 @ bootloader JUMP doesn't set r1 -+ - b 1f - .word 0x016f2818 @ Magic numbers to help the loader - .word start @ absolute load/run zImage address -@@ -137,6 +143,10 @@ - teqp pc, #0x0c000003 @ turn off interrupts - #endif - -+ addruart r11 -+ mov r10, #'d' -+ senduart r10, r11 -+ - /* - * Note that some cache flushing and other stuff may - * be needed here - is there an Angel SWI call for this? -Index: linux-2.6.16.5-a/arch/arm/kernel/apm.c -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/kernel/apm.c 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/kernel/apm.c 2006-05-04 17:07:04.000000000 +0200 -@@ -605,3 +605,7 @@ - wake_up_interruptible(&kapmd_wait); - } - EXPORT_SYMBOL(apm_queue_event); -+ -+void pm_do_poweroff(void) -+{ /* FIXME */ -+} -Index: linux-2.6.16.5-a/arch/arm/mach-pxa/Kconfig -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/mach-pxa/Kconfig 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/mach-pxa/Kconfig 2006-05-04 17:07:29.000000000 +0200 -@@ -1,5 +1,8 @@ - if ARCH_PXA - -+config PXA_EZX -+ bool -+ - menu "Intel PXA2xx Implementations" - - choice -@@ -30,6 +33,18 @@ - SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa) - handheld computer. - -+config PXA_EZX_E680 -+ bool "Motorola E680 GSM Phone" -+ select PXA27x -+ select IWMMXT -+ select PXA_EZX -+ -+config PXA_EZX_A780 -+ bool "Motorola A780 GSM Phone" -+ select PXA27x -+ select IWMMXT -+ select PXA_EZX -+ - endchoice - - if PXA_SHARPSL -Index: linux-2.6.16.5-a/arch/arm/mach-pxa/Makefile -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/mach-pxa/Makefile 2006-05-04 17:06:55.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/mach-pxa/Makefile 2006-05-04 17:07:04.000000000 +0200 -@@ -5,7 +5,7 @@ - # Common support (must be linked before board specific support) - obj-y += generic.o irq.o dma.o time.o - obj-$(CONFIG_PXA25x) += pxa25x.o --obj-$(CONFIG_PXA27x) += pxa27x.o -+obj-$(CONFIG_PXA27x) += pxa27x.o sram.o - - # Specific board support - obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o -@@ -16,6 +16,7 @@ - obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o - obj-$(CONFIG_MACH_POODLE) += poodle.o - obj-$(CONFIG_MACH_TOSA) += tosa.o -+obj-$(CONFIG_PXA_EZX) += ezx.o - - # Support for blinky lights - led-y := leds.o -Index: linux-2.6.16.5-a/arch/arm/mach-pxa/ezx-compat.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/arch/arm/mach-pxa/ezx-compat.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,24 @@ -+ -+int set_GPIO_IRQ_edge(int irq, int type) -+{ -+ int mytype; -+ -+ switch (type) { -+ case GPIO_FALLING_EDGE: -+ mytype = IRQT_FALLING; -+ break; -+ case GPIO_RISING_EDGE: -+ mytype = IRQT_RISING; -+ break; -+ case GPIO_BOTH_EDGES: -+ mytype = IRQT_BOTHEDGE; -+ break; -+ default: -+ return -EINVAL; -+ break; -+ } -+ -+ return set_irq_type(irq, mytype); -+} -+ -+ -Index: linux-2.6.16.5-a/arch/arm/mach-pxa/ezx.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/arch/arm/mach-pxa/ezx.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,567 @@ -+/* -+ * linux/arch/arm/mach-ezx/a780.c -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Zhuang Xiaofan -+ * Created: Nov 25, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/init.h> -+#include <linux/major.h> -+#include <linux/fs.h> -+#include <linux/interrupt.h> -+#include <linux/sched.h> -+#include <linux/bitops.h> -+#include <linux/mmc/host.h> -+#include <linux/fb.h> -+#include <linux/apm_bios.h> -+#include <linux/delay.h> -+#include <linux/platform_device.h> -+ -+#include <asm/types.h> -+#include <asm/setup.h> -+#include <asm/memory.h> -+#include <asm/mach-types.h> -+#include <asm/hardware.h> -+#include <asm/irq.h> -+ -+#include <asm/mach/arch.h> -+#include <asm/mach/map.h> -+#include <asm/mach/irq.h> -+ -+#include <asm/arch/irq.h> -+#include <asm/arch/mmc.h> -+#include <asm/arch/udc.h> -+#include <asm/arch/ohci.h> -+#include <asm/arch/pxafb.h> -+#include <asm/arch/pxa-regs.h> -+#include <asm/arch/ezx.h> -+ -+#include "generic.h" -+#include <linux/tty.h> -+#include <linux/apm_bios.h> -+ -+#include "../../../drivers/misc/ezx/ezx-emu.h" -+ -+#define FIRST_STEP 2 -+#define LAST_STEP 3 -+#define BP_RDY_TIMEOUT 0x000c0000 -+ -+extern void usb_send_readurb(void); -+extern void pm_do_poweroff(void); -+ -+ -+/* check power down condition */ -+inline void check_power_off(void) -+{ -+ if (!(GPIO_is_high(GPIO_BB_WDI2))) { -+#ifdef CONFIG_PM -+ pm_do_poweroff(); -+#endif -+ } -+} -+ -+/* OHCI Controller */ -+ -+static int ezx_ohci_init(struct device *dev) -+{ -+ /* for A780 support (connected with Neptune) */ -+ pxa_gpio_mode(GPIO30_USB_P3_2); /* GPIO30 - USB_P3_2/ICL_TXENB */ -+ pxa_gpio_mode(GPIO31_USB_P3_6); /* GPIO31 - USB_P3_6/ICL_VPOUT */ -+ pxa_gpio_mode(GPIO90_USB_P3_5); /* GPIO90 - USB_P3_5/ICL_VPIN */ -+ pxa_gpio_mode(GPIO91_USB_P3_1); /* GPIO91 - USB_P3_1/ICL_XRXD */ -+ pxa_gpio_mode(GPIO56_USB_P3_4); /* GPIO56 - USB_P3_4/ICL_VMOUT */ -+ pxa_gpio_mode(GPIO113_USB_P3_3);/* GPIO113 - USB_P3_3/ICL_VMIN */ -+ UP3OCR = 0x00000002; -+ -+ UHCHR = UHCHR & ~(UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); -+ -+ return 0; -+} -+ -+static struct pxaohci_platform_data ezx_ohci_platform_data = { -+ .port_mode = PMM_NPS_MODE, -+ .init = ezx_ohci_init, -+}; -+ -+/* MMC/SD Device */ -+ -+static struct pxamci_platform_data ezx_mci_platform_data; -+ -+static int ezx_mci_init(struct device *dev, -+ irqreturn_t (*ezx_detect_int)(int, void *, struct pt_regs *), -+ void *data) -+{ -+ int err; -+ printk("%s entered\n", __FUNCTION__); -+ -+ /* Setup GPIO for PXA27x MMC/SD controller */ -+ pxa_gpio_mode(GPIO32_MMCCLK_MD); -+ pxa_gpio_mode(GPIO112_MMCCMD_MD); -+ pxa_gpio_mode(GPIO92_MMCDAT0_MD); -+ pxa_gpio_mode(GPIO109_MMCDAT1_MD); -+ pxa_gpio_mode(GPIO110_MMCDAT2_MD); -+ pxa_gpio_mode(GPIO111_MMCDAT3_MD); -+ -+ SSP_PCAP_MMCSD_poweron(); -+ -+ ezx_mci_platform_data.detect_delay = msecs_to_jiffies(250); -+ -+ err = request_irq(0x49, ezx_detect_int, SA_INTERRUPT, -+ "MMC card detect", data); -+ if (err) { -+ printk(KERN_ERR "ezx_mci_detect: MMC/SD: can't request " -+ "MMC card detect IRQ\n"); -+ return -1; -+ } -+ -+ set_GPIO_IRQ_edge(0x0b, GPIO_BOTH_EDGES); -+ -+ return 0; -+} -+ -+static int ezx_mci_get_ro(struct device *dev) -+{ -+ printk("%s entered\n", __FUNCTION__); -+ return (GPLR3 & 0x800); -+ // return GPIO_is_high(96+4); -+ /* this is only e680, i guess */ -+} -+ -+static void ezx_mci_setpower(struct device *dev, unsigned int vdd) -+{ -+ printk("%s entered\n", __FUNCTION__); -+ /* FIXME: implement this */ -+ SSP_PCAP_MMCSD_poweron(); -+} -+ -+static void ezx_mci_exit(struct device *dev, void *data) -+{ -+ printk("%s entered\n", __FUNCTION__); -+ SSP_PCAP_MMCSD_poweroff(); -+ free_irq(0x49, data); -+} -+ -+static struct pxamci_platform_data ezx_mci_platform_data = { -+ .ocr_mask = MMC_VDD_27_28, //|MMC_VDD_32_33|MMC_VDD_33_34, -+ .init = ezx_mci_init, -+ .get_ro = ezx_mci_get_ro, -+ .setpower = ezx_mci_setpower, -+ .exit = ezx_mci_exit, -+}; -+ -+/* USB Device Controller */ -+ -+static int udc_connected_status; -+ -+static void ezx_udc_command(int cmd) -+{ -+ switch (cmd) { -+ case PXA2XX_UDC_CMD_DISCONNECT: -+ printk(KERN_NOTICE "USB cmd disconnect\n"); -+ pcap_switch_off_usb(); -+ udc_connected_status = 0; -+ break; -+ case PXA2XX_UDC_CMD_CONNECT: -+ printk(KERN_NOTICE "USB cmd connect\n"); -+ pcap_switch_on_usb(); -+ udc_connected_status = 1; -+ break; -+ } -+} -+ -+static int ezx_udc_is_connected(void) -+{ -+ return udc_connected_status; -+} -+ -+static struct pxa2xx_udc_mach_info ezx_udc_info __initdata = { -+ .udc_is_connected = ezx_udc_is_connected, -+ .udc_command = ezx_udc_command, -+}; -+ -+/* pxafb */ -+ -+#define BKLIGHT_PRESCALE 2 -+#define BKLIGHT_PERIOD 49 -+#define DEFAULT_DUTYCYCLE 25 -+#define MAX_DUTYCYCLE (BKLIGHT_PERIOD+1) -+#define MIN_DUTYCYCLE 0 -+ -+static void pxafb_backlight_power(int on) -+{ -+ if (on) { -+ CKEN |= CKEN0_PWM0; -+ PWM_CTRL0 = BKLIGHT_PRESCALE; -+ PWM_PERVAL0 = BKLIGHT_PERIOD; -+ PWM_PWDUTY0 = DEFAULT_DUTYCYCLE; -+ -+ GPDR0 |= 0x00010000; //PWM0 is GPIO16 -+ pxa_gpio_mode(GPIO16_PWM0_MD); -+ } else { -+#if 0 -+ PWM_PWDUTY0 = 0; -+ GAFR0_U &= -+#endif -+ } -+} -+ -+//#define mdelay(x) udelay((x)*1000) -+ -+static void pxafb_lcd_power(int on) -+{ -+ if (on) { -+ mdelay(1); -+ GPSR3 = 0x00100000; -+ mdelay(10); -+ GPCR3 = 0x00100000; -+ GPDR3 |= 0x00100000; -+ } else { -+#if 0 -+ GPSR3 = 0x00100000; -+ PGSR3 |= 0x00100000; -+ mdelay(41); -+#endif -+ } -+} -+ -+static struct pxafb_mach_info ezx_fb_info __initdata = { -+ .pixclock = 150000, -+ .xres = 240, -+ .yres = 320, -+ .bpp = 16, -+ -+ .hsync_len = 10, -+ .left_margin = 20, -+ .right_margin = 10, -+ -+ .vsync_len = 2, -+ .upper_margin = 3, -+ .lower_margin = 2, -+ -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ -+ .lccr0 = 0x002008F8, -+ .lccr3 = 0x0430FF09, -+ -+ .pxafb_backlight_power = &pxafb_backlight_power, -+ .pxafb_lcd_power = &pxafb_lcd_power, -+}; -+ -+ -+/* backlight */ -+/* keyboard */ -+/* touch screen */ -+ -+/* SSP device */ -+ -+struct platform_device ezx_ssp_pcap_device = { -+ .name = "ezx-ssp-pcap", -+ .dev = { -+ //.parent = , -+ }, -+ .id = -1, -+}; -+ -+ -+static int step = FIRST_STEP; -+void handshake(void) -+{ -+ /* step 1: check MCU_INT_SW or BP_RDY is low (now it is checked in apboot) */ -+ if (step == 1) { -+ int timeout = BP_RDY_TIMEOUT; -+ -+ /* config MCU_INT_SW, BP_RDY as input */ -+ GPDR(GPIO_MCU_INT_SW) &= ~GPIO_bit(GPIO_MCU_INT_SW); -+ GPDR(GPIO_BP_RDY) &= ~GPIO_bit(GPIO_BP_RDY); -+ -+ while ( timeout -- ) { -+ if ( (!(GPIO_is_high(GPIO_MCU_INT_SW))) -+ || (!(GPIO_is_high(GPIO_BP_RDY))) ) { -+ step ++; -+ break; -+ } -+ -+ check_power_off(); -+ } -+ } -+ -+ /* step 2: wait BP_RDY is low */ -+ if (step == 2) { -+ if (!(GPIO_is_high(GPIO_BP_RDY))) { -+ -+ /* config MCU_INT_SW as output */ -+ pxa_gpio_mode(GPIO_MCU_INT_SW | GPIO_OUT); -+ clr_GPIO(GPIO_MCU_INT_SW); -+ -+ step ++; -+ } -+ } -+ -+ /* step 3: wait BP_RDY is high */ -+ if (step == 3) { -+ if (GPIO_is_high(GPIO_BP_RDY)) { -+ step ++; -+ //FIXME delay_bklight(); -+ set_GPIO(GPIO_MCU_INT_SW); -+ } -+ } -+} -+ -+#ifdef CONFIG_APM -+static unsigned long idle_limit = 0; -+int pm_handle_irq(int irq) -+{ -+ -+ //FIXME: extern unsigned long idle_limit; -+ //FIXME: extern int can_idle, can_sleep; -+ static unsigned long tmp_jiffy; /* for temporary store of jiffies */ -+ -+ /* -+ * if idle_limit is zero, never enter idle. -+ * if not OS timer, reset idle timer count -+ */ -+ if (idle_limit == 0) { -+ tmp_jiffy = jiffies; -+ return irq; -+ } -+#if 0 -+ if (irq != IRQ_OST0) { -+ tmp_jiffy = jiffies; -+ can_idle = 0; -+ can_sleep = 0; -+ } else if (jiffies > tmp_jiffy + idle_limit) { -+ -+ /* -+ * I think this is enough to prevent from reentering here -+ * due to jiffies will be stoped -+ */ -+ tmp_jiffy = jiffies; -+ -+ /* if pm idle timer expired, queue event */ -+ apm_queue_event(KRNL_PROC_INACT); -+ can_idle = 1; -+ } -+#endif -+ -+ return irq; -+} -+ -+irqreturn_t bp_wdi_intr(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ apm_queue_event(KRNL_BP_WDI); -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction bp_wdi_irq = { -+ .name = "BP wdi", -+ .handler = &bp_wdi_intr, -+}; -+#endif -+ -+int handshake_pass(void) -+{ -+ return (step > LAST_STEP); -+} -+ -+static irqreturn_t bp_rdy_intr(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ static int usbipc_ready = 0; -+ -+ if (!usbipc_ready) { -+ handshake(); -+ if (handshake_pass()) { -+ disable_irq(IRQ_GPIO(GPIO_BB_WDI2)); -+ -+ /* set bp_rdy handle for usb ipc */ -+ set_GPIO_IRQ_edge(GPIO_BP_RDY, GPIO_FALLING_EDGE); -+ usbipc_ready = 1; -+ } -+ } else -+ // FIXME usb_send_readurb(); -+ {} -+ -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction bp_rdy_irq = { -+ .name = "BP rdy", -+ .handler = bp_rdy_intr, -+}; -+ -+static irqreturn_t bp_wdi2_intr(int irq, void *dev_id, struct pt_regs *regs) -+{ -+#ifdef CONFIG_PM -+ pm_do_poweroff(); -+#endif -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction bp_wdi2_irq = { -+ .name = "BP wdi2", -+ .handler = bp_wdi2_intr, -+}; -+ -+ -+static struct resource ezx_bp_resources[] = { -+ [0] = { -+ .start = GPIO_BP_RDY, -+ .end = GPIO_BP_RDY, -+ .flags = IORESOURCE_IRQ, -+ }, -+ [1] = { -+ .start = GPIO_BB_WDI2, -+ .end = GPIO_BB_WDI2, -+ .flags = IORESOURCE_IRQ, -+ }, -+#ifdef CONFIG_APM -+ [2] = { -+ .start = GPIO_BB_WDI, -+ .end = GPIO_BB_WDI, -+ .flags = IORESOURCE_IRQ, -+ }, -+#endif -+}; -+ -+static struct platform_device ezx_bp_device = { -+ .name = "ezx-bp", -+ .dev = { -+ //.parent = -+ //.platform_data = -+ }, -+ .id = -1, -+ .num_resources = ARRAY_SIZE(ezx_bp_resources), -+ .resource = ezx_bp_resources, -+}; -+ -+static void __init ezx_init_gpio_irq(void) -+{ -+#ifdef CONFIG_APM -+ set_GPIO_IRQ_edge(GPIO_BB_WDI, GPIO_FALLING_EDGE); -+ setup_irq(IRQ_GPIO(GPIO_BB_WDI), &bp_wdi_irq); -+#endif -+ set_GPIO_IRQ_edge(GPIO_BP_RDY, GPIO_BOTH_EDGES); -+ setup_irq(IRQ_GPIO(GPIO_BP_RDY), &bp_rdy_irq); -+ -+ set_GPIO_IRQ_edge(GPIO_BB_WDI2, GPIO_FALLING_EDGE); -+ setup_irq(IRQ_GPIO(GPIO_BB_WDI2), &bp_wdi2_irq); -+} -+ -+static void __init a780_init_irq(void) -+{ -+ pxa_init_irq(); -+ -+ /* init ezx specfic gpio irq */ -+ ezx_init_gpio_irq(); -+ -+ check_power_off(); -+ handshake(); -+ if (handshake_pass()) { -+ disable_irq(IRQ_GPIO(GPIO_BP_RDY)); -+ disable_irq(IRQ_GPIO(GPIO_BB_WDI2)); -+ } -+} -+ -+static struct platform_device *devices[] __initdata = { -+ &ezx_bp_device, -+ &ezx_ssp_pcap_device, -+}; -+ -+static void __init -+fixup_a780(struct machine_desc *desc, struct tag *tag, -+ char **cmdline, struct meminfo *mi) -+{ -+ screen_info.orig_video_cols = 30; -+ screen_info.orig_video_lines = 80; -+} -+ -+static void __init a780_init(void) -+{ -+ CKEN = CKEN9_OSTIMER | CKEN22_MEMC | CKEN5_STUART; -+ -+ /* set BB_RESET PIN out put high */ -+ pxa_gpio_mode(GPIO_BB_RESET|GPIO_OUT); -+ set_GPIO(GPIO_BB_RESET); -+ -+ pxa_gpio_mode(GPIO_ICL_FFRXD_MD); -+ pxa_gpio_mode(GPIO_ICL_FFTXD_MD); -+ pxa_gpio_mode(GPIO_ICL_FFCTS_MD); -+ pxa_gpio_mode(GPIO_ICL_FFRTS_MD); -+ -+ pxa_gpio_mode(GPIO42_BTRXD_MD); -+ pxa_gpio_mode(GPIO43_BTTXD_MD); -+ pxa_gpio_mode(GPIO44_BTCTS_MD); -+ pxa_gpio_mode(GPIO45_BTRTS_MD); -+ -+ /* clear EMU MUX1/MUX2 (low) to close the audio path to EMU */ -+ pxa_gpio_mode(GPIO_EMU_MUX1|GPIO_OUT); -+ clr_GPIO(GPIO_EMU_MUX1); -+ pxa_gpio_mode(GPIO_EMU_MUX2|GPIO_OUT); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+#if defined(CONFIG_ARCH_EZX_E680) -+ pxa_gpio_mode(GPIO46_STRXD_MD); -+ pxa_gpio_mode(GPIO47_STTXD_MD); -+ -+ /* setup sleep mode values */ -+ PWER = 0xc000f803; // disable usb 0xdc00f803; -+ PFER = 0x0000f803; -+ PRER = 0x00001802; -+ // keypad wakeup (PKWR,PGSR3) should be in keypad.c -+ PGSR0 = 0x00000010; -+ PGSR1 = 0x02800000; -+ PGSR2 = 0x00040000; -+ PGSR3 = 0x00000000; -+ PCFR = PCFR_DC_EN | PCFR_FS | PCFR_FP | PCFR_OPDE; -+ PSLR = 0x05800f00; -+ -+#elif defined(CONFIG_ARCH_EZX_A780) -+ -+ /* Standard UART */ -+ pxa_gpio_mode(GPIO46_STRXD_MD); -+ pxa_gpio_mode(GPIO47_STTXD_MD); -+ -+ /* setup sleep mode values */ -+ PWER = 0xc0007803; // disable usb, GPIO15 NC -+ PFER = 0x00007803; -+ PRER = 0x00001802; -+ // keypad wakeup (PKWR,PGSR3) should be in keypad.c -+ PGSR0 = 0x00000010; -+ PGSR1 = 0x02800000; -+ PGSR2 = 0x00040000; -+ PGSR3 = 0x00000008; -+ PCFR = PCFR_DC_EN | PCFR_FS | PCFR_FP | PCFR_OPDE; -+ PSLR = 0x05800f00; -+ -+#endif -+ set_pxa_fb_info(&ezx_fb_info); -+ pxa_set_udc_info(&ezx_udc_info); -+ pxa_set_mci_info(&ezx_mci_platform_data); -+ pxa_set_ohci_info(&ezx_ohci_platform_data); -+ -+ ssp_pcap_init(); -+ -+ /* try to configure USB connector as FFUART */ -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ -+ platform_add_devices(devices, ARRAY_SIZE(devices)); -+} -+ -+MACHINE_START(EZX, "Motorola Ezx Platform") -+ /* Maintainer: Harald Welte <laforge@gnumonks.org> */ -+ .phys_ram = 0xa0000000, -+ .phys_io = 0x40000000, -+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, -+ .boot_params = 0xa0000100, -+ .fixup = fixup_a780, -+ .map_io = pxa_map_io, -+ .init_irq = a780_init_irq, -+ .timer = &pxa_timer, -+ .init_machine = a780_init, -+MACHINE_END -Index: linux-2.6.16.5-a/arch/arm/mach-pxa/irq.c -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/mach-pxa/irq.c 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/mach-pxa/irq.c 2006-05-04 17:07:04.000000000 +0200 -@@ -25,6 +25,8 @@ - #include "generic.h" - - -+#include "ezx-compat.c" -+ - /* - * This is for peripheral IRQs internal to the PXA chip. - */ -Index: linux-2.6.16.5-a/arch/arm/mach-pxa/sram.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/arch/arm/mach-pxa/sram.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,104 @@ -+/* -+ * linux/arch/arm/mach-wmmx/sram.c -+ * -+ * Bulverde Internal Memory stuff -+ * -+ * Created: Sep 05, 2003 -+ * Copyright: MontaVista Software Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/config.h> -+#include <linux/sched.h> -+#include <linux/kernel.h> -+#include <linux/errno.h> -+#include <linux/spinlock.h> -+ -+#include <asm/system.h> -+#include <asm/irq.h> -+#include <asm/hardware.h> -+#include <asm/arch-pxa/pxa-regs.h> -+ -+#define SRAM_MEM_VIRT io_p2v(SRAM_MEM_PHYS) -+ -+#define SRAM_DELAY_STANDBY_TIME 255 -+ -+static spinlock_t sram_spinlock; -+static volatile int sram_locked = 0; -+ -+static int __init sram_init (void) { -+ /* Enable clock */ -+ pxa_set_cken(CKEN20_IM, 1); -+ -+ /* All the banks are -+ * - Automatic wakeup enabled -+ * - Enter Stand-by after 255 ms -+ */ -+ IMPMCR = IMPMCR_PC3_AUTO_MODE | -+ IMPMCR_PC2_AUTO_MODE | -+ IMPMCR_PC1_AUTO_MODE | -+ IMPMCR_PC0_AUTO_MODE | -+ IMPMCR_AW3 | IMPMCR_AW2 | -+ IMPMCR_AW1 | IMPMCR_AW0 | -+ SRAM_DELAY_STANDBY_TIME; -+ -+ return 0; -+} -+ -+int sram_access_obtain(unsigned long *pmem, unsigned long *psize) { -+ -+ int flags; -+ -+ spin_lock_irqsave(&sram_spinlock, flags); -+ -+ if (sram_locked != 0) { -+ spin_unlock_irqrestore(&sram_spinlock, flags); -+ return -EAGAIN; -+ } -+ -+ sram_locked = 1; -+ -+ spin_unlock_irqrestore(&sram_spinlock, flags); -+ -+ *pmem = SRAM_MEM_VIRT; -+ *psize = SRAM_SIZE; -+ -+ return 0; -+} -+ -+int sram_access_release(unsigned long *pmem, unsigned long *psize) -+{ -+ if ((*pmem != SRAM_MEM_VIRT) || -+ (*psize != SRAM_SIZE)){ -+ return -EINVAL; -+ } -+ -+ *pmem = 0; -+ *psize = 0; -+ -+ sram_locked = 0; -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL(sram_access_obtain); -+EXPORT_SYMBOL(sram_access_release); -+ -+__initcall(sram_init); -+ -Index: linux-2.6.16.5-a/arch/arm/mm/init.c -=================================================================== ---- linux-2.6.16.5-a.orig/arch/arm/mm/init.c 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/arch/arm/mm/init.c 2006-05-04 17:07:04.000000000 +0200 -@@ -230,6 +230,10 @@ - #endif - if (res_size) - reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); -+#ifdef CONFIG_ARCH_EZX -+ /* reserve the first page memory for exiting sleep and user off */ -+ reserve_bootmem_node(pgdat, PHYS_OFFSET, PAGE_SIZE); -+#endif - } - - void __init build_mem_type_table(void); -Index: linux-2.6.16.5-a/include/asm-arm/arch-pxa/debug-macro.S -=================================================================== ---- linux-2.6.16.5-a.orig/include/asm-arm/arch-pxa/debug-macro.S 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/include/asm-arm/arch-pxa/debug-macro.S 2006-05-04 17:07:04.000000000 +0200 -@@ -14,15 +14,59 @@ - #include "hardware.h" - - .macro addruart,rx -- mrc p15, 0, \rx, c1, c0 -- tst \rx, #1 @ MMU enabled? -- moveq \rx, #0x40000000 @ physical -- movne \rx, #io_p2v(0x40000000) @ virtual -- orr \rx, \rx, #0x00100000 -+@ mrc p15, 0, \rx, c1, c0 -+@ tst \rx, #1 @ MMU enabled? -+ mov \rx, #0x40000000 @ physical -+@ moveq \rx, #0x40000000 @ physical -+@ movne \rx, #io_p2v(0x40000000) @ virtual -+ orr \rx, \rx, #0x00700000 -+ .endm -+ -+ .macro inituart,rd,rx -+ ldr \rd, =0x41300004 @ CKEN -+ ldr \rx, [\rd] -+ orr \rx, \rx, #0x20 -+ str \rx, [\rd] -+ -+ ldr \rd, =0x40E0005C -+ ldr \rx, [\rd] -+ bic \rx, \rx, #0xF0000000 @ clear GPIO46/47 config -+ orr \rx, \rx, #0x60000000 @ set GPIO46: AF2, GPIO47: AF1 -+ str \rx, [\rd] -+ ldr \rd, =0x40E00010 -+ ldr \rx, [\rd] -+ bic \rx, \rx, #0x0000c000 @ clear GPIO46/47 direction -+ orr \rx, \rx, #0x00008000 @ set GPIO 47 out, 46 in -+ str \rx, [\rd] -+ -+ addruart \rd -+ mov \rx, #0x83 @ DLAB = 1 -+ strb \rx, [\rd, #0x0c] -+ -+ mov \rx, #0x08 @ Divisor 8 => 115200 bps -+ strb \rx, [\rd, #0x00] -+ -+ mov \rx, #0x00 -+ strb \rx, [\rd, #0x04] @ Divisor high = 0 -+ -+ mov \rx, #0x03 -+ strb \rx, [\rd, #0x0c] @ DLAB = 0, n81 -+ -+ mov \rx, #0x00 -+ strb \rx, [\rd, #0x10] @ MCR = 0 -+ -+ mov \rx, #0x00 -+ strb \rx, [\rd, #0x28] @ disable autobaud -+ -+ mov \rx, #0x40 -+ strb \rx, [\rd, #0x04] @ IER UUE (UART Enable) - .endm - - .macro senduart,rd,rx -- str \rd, [\rx, #0] -+1000: ldr r12, [\rx, #0x14] -+ tst r12, #(1 << 6) -+ beq 1000b -+ strb \rd, [\rx, #0] - .endm - - .macro busyuart,rd,rx -Index: linux-2.6.16.5-a/include/asm-arm/arch-pxa/ezx-compat.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/include/asm-arm/arch-pxa/ezx-compat.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,14 @@ -+#ifndef _EZX_COMPAT_H -+#define _EZX_COMPAT_H -+ -+#define GPIO_is_high(x) (GPLR(x) & GPIO_bit(x)) -+#define set_GPIO(x) (GPSR(x) = GPIO_bit(x)) -+#define clr_GPIO(x) (GPCR(x) = GPIO_bit(x)) -+ -+#define GPIO_FALLING_EDGE 1 -+#define GPIO_RISING_EDGE 2 -+#define GPIO_BOTH_EDGES 3 -+ -+extern int set_GPIO_IRQ_edge(int irq, int type); -+ -+#endif -Index: linux-2.6.16.5-a/include/asm-arm/arch-pxa/ezx.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/include/asm-arm/arch-pxa/ezx.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,221 @@ -+/* -+ * linux/include/asm-arm/arch-pxa/ezx.h -+ * -+ * Specific macro defines for Motorola Ezx Development Platform -+ * -+ * Author: Zhuang Xiaofan -+ * Created: Nov 25, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+/* support E680 p3 and ealier PCB */ -+//#define E680_P3_AND_EARLY -+ -+/* -+ * Flags in memory for sleep use -+ */ -+#define FLAG_ADDR PHYS_OFFSET -+#define RESUME_ADDR (PHYS_OFFSET + 4) -+#define BPSIG_ADDR (PHYS_OFFSET + 8) -+ -+#define USER_OFF_FLAG 0x5a5a5a5a -+#define SLEEP_FLAG 0x6b6b6b6b -+#define OFF_FLAG 0x7c7c7c7c -+#define REFLASH_FLAG 0x0C1D2E3F -+#define PASS_THRU_FLAG 0x12345678 -+ -+#define WDI_FLAG 0xbb00dead -+#define NO_FLAG 0xaa00dead -+ -+/* -+ * GPIO control pin, have to change when hardware lock down -+ */ -+ -+#ifdef E680_P3_AND_EARLY -+ -+/* shakehand with BP's PIN */ -+#define GPIO_BP_RDY 0 /* BP_RDY */ -+#define GPIO_BB_WDI 13 /* BB_WDI */ -+#define GPIO_BB_WDI2 3 /* BB_WDI2 */ -+#define GPIO_BB_RESET 57 /* BB_RESET */ -+#define GPIO_MCU_INT_SW 115 /* MCU_INT_SW */ -+#define GPIO_TC_MM_EN 89 /* TC_MM_EN */ -+ -+/* control PCAP direct PIN */ -+#define GPIO_WDI_AP 4 /* WDI_AP */ -+#define GPIO_SYS_RESTART 55 /* restart PCAP power */ -+#define GPIO_AP_STANDBY 28 /* make pcap enter standby mode */ -+ -+/* communicate with PCAP's PIN */ -+#define GPIO_PCAP_SEC_INT 1 /* PCAP interrupt PIN to AP */ -+#define GPIO_SPI_CLK 23 /* PCAP SPI port clock */ -+#define GPIO_SPI_CE 24 /* PCAP SPI port SSPFRM */ -+#define GPIO_SPI_MOSI 25 /* PCAP SPI port SSPTXD */ -+#define GPIO_SPI_MISO 26 /* PCAP SPI port SSPRXD */ -+ -+/* blue tooth control PIN */ -+#define GPIO_BT_WAKEUP 2 /* AP wake up bluetooth module */ -+#define GPIO_BT_HOSTWAKE 14 /* bluetooth module wake up Ap module */ -+#define GPIO_BT_RESET 56 /* AP reset bluetooth module */ -+ -+/* control LCD high - OFF low -- ON */ -+#define GPIO_LCD_OFF 116 /* control LCD */ -+ -+/* FFUART PIN */ -+#define GPIO_ICL_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) -+#define GPIO_ICL_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -+#define GPIO_ICL_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -+#define GPIO_ICL_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) -+ -+#elif defined(A780_P1_AND_EARLY) -+ -+/* shakehand with BP's PIN */ -+#define GPIO_BP_RDY 0 /* BP_RDY */ -+#define GPIO_BB_WDI 13 /* BB_WDI */ -+#define GPIO_BB_WDI2 3 /* BB_WDI2 */ -+#define GPIO_BB_RESET 82 /* BB_RESET */ -+#define GPIO_MCU_INT_SW 57 /* MCU_INT_SW */ -+#define GPIO_TC_MM_EN 89 /* TC_MM_EN */ -+ -+/* control PCAP direct PIN */ -+#define GPIO_WDI_AP 4 /* WDI_AP */ -+#define GPIO_SYS_RESTART 55 /* restart PCAP power */ -+#define GPIO_AP_STANDBY 28 /* make pcap enter standby mode */ -+ -+/* communicate with PCAP's PIN */ -+#define GPIO_PCAP_SEC_INT 1 /* PCAP interrupt PIN to AP */ -+#define GPIO_SPI_CLK 29 /* PCAP SPI port clock */ -+#define GPIO_SPI_CE 24 /* PCAP SPI port SSPFRM */ -+#define GPIO_SPI_MOSI 25 /* PCAP SPI port SSPTXD */ -+#define GPIO_SPI_MISO 26 /* PCAP SPI port SSPRXD */ -+ -+/* blue tooth control PIN */ -+#define GPIO_BT_WAKEUP 2 /* AP wake up bluetooth module */ -+#define GPIO_BT_HOSTWAKE 14 /* bluetooth module wake up Ap module */ -+#define GPIO_BT_RESET 56 /* AP reset bluetooth module */ -+ -+/* control LCD high - OFF low -- ON */ -+#define GPIO_LCD_OFF 116 /* control LCD */ -+ -+/* FFUART PIN */ -+#define GPIO_ICL_FFRXD_MD (53 | GPIO_ALT_FN_1_IN) -+#define GPIO_ICL_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -+#define GPIO_ICL_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -+#define GPIO_ICL_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) -+ -+#else -+ -+/* shakehand with BP's PIN */ -+#define GPIO_BP_RDY 0 /* BP_RDY */ -+#define GPIO_BB_WDI 13 /* BB_WDI */ -+#define GPIO_BB_WDI2 3 /* BB_WDI2 */ -+#define GPIO_BB_RESET 82 /* BB_RESET */ -+#define GPIO_MCU_INT_SW 57 /* MCU_INT_SW */ -+#define GPIO_TC_MM_EN 99 /* TC_MM_EN */ -+ -+/* control PCAP direct PIN */ -+#define GPIO_WDI_AP 4 /* WDI_AP */ -+#define GPIO_SYS_RESTART 55 /* restart PCAP power */ -+//#define GPIO_AP_STANDBY 28 /* make pcap enter standby mode */ -+ -+/* communicate with PCAP's PIN */ -+#define GPIO_PCAP_SEC_INT 1 /* PCAP interrupt PIN to AP */ -+#define GPIO_SPI_CLK 29 /* PCAP SPI port clock */ -+#define GPIO_SPI_CE 24 /* PCAP SPI port SSPFRM */ -+#define GPIO_SPI_MOSI 25 /* PCAP SPI port SSPTXD */ -+#define GPIO_SPI_MISO 26 /* PCAP SPI port SSPRXD */ -+ -+/* blue tooth control PIN */ -+#define GPIO_BT_WAKEUP 28 /* AP wake up bluetooth module */ -+#define GPIO_BT_HOSTWAKE 14 /* AP wake up bluetooth module */ -+#define GPIO_BT_RESET 48 /* AP reset bluetooth module */ -+ -+/* control LCD high - OFF low -- ON */ -+#define GPIO_LCD_OFF 116 /* control LCD */ -+ -+/* FFUART PIN */ -+#define GPIO_ICL_FFRXD_MD (53 | GPIO_ALT_FN_1_IN) -+#define GPIO_ICL_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -+#define GPIO_ICL_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -+#define GPIO_ICL_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) -+ -+#endif -+/* -+ * ezx platform, wake up source edge detect bit -+ */ -+#define PEDR_INT_SEC 1 -+ -+#define GPIO_FLIP_PIN 12 -+/*E680 screen lock button*/ -+ -+#define GPIO_LOCK_SCREEN_PIN GPIO_FLIP_PIN -+ -+/* MMC interface */ -+#define GPIO_MMC_DETECT 11 -+#define GPIO_MMC_CLK 32 -+#define GPIO_MMC_DATA0 92 -+#define GPIO_MMC_WP 107 -+#define GPIO_MMC_DATA1 109 -+#define GPIO_MMC_DATA2 110 -+#define GPIO_MMC_DATA3 111 -+#define GPIO_MMC_CMD 112 -+ -+/* interface function */ -+#define GPIO_MMC_CLK_MD (GPIO_MMC_CLK | GPIO_ALT_FN_2_OUT) -+#define GPIO_MMC_DATA0_MD (GPIO_MMC_DATA0 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT) -+#define GPIO_MMC_DATA1_MD (GPIO_MMC_DATA1 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT) -+#define GPIO_MMC_DATA2_MD (GPIO_MMC_DATA2 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT) -+#define GPIO_MMC_DATA3_MD (GPIO_MMC_DATA3 | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT) -+ -+#define GPIO_MMC_CMD_MD (GPIO_MMC_CMD | GPIO_ALT_FN_1_IN | GPIO_ALT_FN_1_OUT) -+ -+/* EMU GPIO 119 ---MUX2 120 --- MUX1 */ -+#define GPIO_EMU_MUX1 120 -+#define GPIO_EMU_MUX2 119 -+#define GPIO_SNP_INT_CTL 86 -+#define GPIO_SNP_INT_IN 87 -+ -+ -+/* audio related pins */ -+#define AP_13MHZ_OUTPUT_PIN 9 -+ -+#ifdef CONFIG_ARCH_EZX_E680 -+#define GPIO_VA_SEL_BUL 79 -+#define GPIO_FLT_SEL_BUL 80 /* out filter select pin */ -+#define GPIO_MIDI_RESET 78 /* GPIO used by MIDI chipset */ -+#define GPIO_MIDI_CS 33 -+#define GPIO_MIDI_IRQ 15 -+#define GPIO_MIDI_NPWE 49 -+#define GPIO_MIDI_RDY 18 -+#endif -+ -+#ifdef CONFIG_ARCH_EZX_A780 -+#define GPIO_HW_ATTENUATE_A780 96 /* hw noise attenuation be used or bypassed, for receiver or louderspeaker mode */ -+#endif -+ -+ -+/* bp status pin */ -+#define GPIO_BP_STATE 41 -+ -+/* define usb related pin */ -+#define GPIO34_TXENB 34 -+#define GPIO35_XRXD 35 -+#define GPIO36_VMOUT 36 -+#define GPIO39_VPOUT 39 -+#define GPIO40_VPIN 40 -+#define GPIO53_VMIN 53 -+ -+/* USB client 6 pin defination */ -+#define GPIO34_TXENB_MD (GPIO34_TXENB | GPIO_ALT_FN_1_OUT) -+#define GPIO35_XRXD_MD (GPIO35_XRXD | GPIO_ALT_FN_2_IN ) -+#define GPIO36_VMOUT_MD (GPIO36_VMOUT | GPIO_ALT_FN_1_OUT) -+#define GPIO39_VPOUT_MD (GPIO39_VPOUT | GPIO_ALT_FN_1_OUT) -+#define GPIO40_VPIN_MD (GPIO40_VPIN | GPIO_ALT_FN_3_IN ) -+#define GPIO53_VMIN_MD (GPIO53_VMIN | GPIO_ALT_FN_2_IN ) -+ -+#define GPIO53_FFRXD_MD (53 | GPIO_ALT_FN_1_IN) -+ -Index: linux-2.6.16.5-a/include/asm-arm/arch-pxa/hardware.h -=================================================================== ---- linux-2.6.16.5-a.orig/include/asm-arm/arch-pxa/hardware.h 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/include/asm-arm/arch-pxa/hardware.h 2006-05-04 17:07:04.000000000 +0200 -@@ -62,6 +62,7 @@ - - #ifndef __ASSEMBLY__ - -+#include <asm/arch-pxa/ezx-compat.h> - /* - * Handy routine to set GPIO alternate functions - */ -Index: linux-2.6.16.5-a/include/asm-arm/arch-pxa/pxa-regs.h -=================================================================== ---- linux-2.6.16.5-a.orig/include/asm-arm/arch-pxa/pxa-regs.h 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/include/asm-arm/arch-pxa/pxa-regs.h 2006-05-04 17:07:04.000000000 +0200 -@@ -856,6 +856,8 @@ - #define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */ - #define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */ - -+#define UP3OCR __REG(0x40600024) /* USB Port 3 Output Control register */ -+ - #define UDCCSN(x) __REG2(0x40600100, (x) << 2) - #define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */ - #define UDCCSR0_SA (1 << 7) /* Setup Active */ -@@ -1259,6 +1261,7 @@ - #define GPIO33_nCS_5 33 /* chip select 5 */ - #define GPIO34_FFRXD 34 /* FFUART receive */ - #define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */ -+#define GPIO34_USB_P2_2 34 /* USB Port2 Pin 2 */ - #define GPIO35_FFCTS 35 /* FFUART Clear to send */ - #define GPIO36_FFDCD 36 /* FFUART Data carrier detect */ - #define GPIO37_FFDSR 37 /* FFUART data set ready */ -@@ -1382,22 +1385,29 @@ - #define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN) - #define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN) - #define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT) -+#define GPIO30_USB_P3_2 (30 | GPIO_ALT_FN_3_OUT) - #define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT) - #define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT) - #define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT) -+#define GPIO31_USB_P3_6 (31 | GPIO_ALT_FN_3_OUT) - #define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN) - #define GPIO32_SYSCLK_I2S_MD (32 | GPIO_ALT_FN_1_OUT) - #define GPIO32_MMCCLK_MD ( 32 | GPIO_ALT_FN_2_OUT) - #define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT) - #define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN) -+#define GPIO34_USB_P2_2_MD (34 | GPIO_ALT_FN_1_OUT) - #define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT) - #define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN) -+#define GPIO35_USB_P2_1_MD (35 | GPIO_ALT_FN_2_IN) - #define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN) -+#define GPIO36_USB_P2_4_MD (36 | GPIO_ALT_FN_1_OUT) - #define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN) - #define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN) - #define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT) - #define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT) -+#define GPIO39_USB_P2_6_MD (39 | GPIO_ALT_FN_1_OUT) - #define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT) -+#define GPIO40_USB_P2_5_MD (40 | GPIO_ALT_FN_3_IN) - #define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT) - #define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN) - #define GPIO42_HWRXD_MD (42 | GPIO_ALT_FN_3_IN) -@@ -1422,13 +1432,16 @@ - #define GPIO51_HWRTS_MD (51 | GPIO_ALT_FN_1_OUT) - #define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT) - #define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT) --#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) - #define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT) -+#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT) -+#define GPIO53_FFRXD_MD (53 | GPIO_ALT_FN_1_IN) -+#define GPIO53_USB_P2_3_MD (53 | GPIO_ALT_FN_2_IN) - #define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT) - #define GPIO54_nPCE_2_MD (54 | GPIO_ALT_FN_2_OUT) - #define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT) - #define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT) - #define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN) -+#define GPIO56_USB_P3_4 (56 | GPIO_ALT_FN_1_OUT) - #define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN) - #define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT) - #define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT) -@@ -1471,6 +1484,8 @@ - #define GPIO84_NSSP_TX (84 | GPIO_ALT_FN_1_OUT) - #define GPIO84_NSSP_RX (84 | GPIO_ALT_FN_2_IN) - #define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) -+#define GPIO90_USB_P3_5 (90 | GPIO_ALT_FN_2_IN) -+#define GPIO91_USB_P3_1 (91 | GPIO_ALT_FN_2_IN) - #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) - #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT) - #define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT) -@@ -1481,6 +1496,7 @@ - #define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) - #define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) - #define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) -+#define GPIO113_USB_P3_3 (113 | GPIO_ALT_FN_3_IN) - #define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) - #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) - -@@ -1496,6 +1512,7 @@ - #define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */ - #define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */ - #define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */ -+#define PGSR(x) (__REG(0x40F00020 + ((unsigned long)(x)/32 * 4))) - #define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */ - #define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */ - #define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */ -Index: linux-2.6.16.5-a/include/asm-arm/arch-pxa/uncompress.h -=================================================================== ---- linux-2.6.16.5-a.orig/include/asm-arm/arch-pxa/uncompress.h 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/include/asm-arm/arch-pxa/uncompress.h 2006-05-04 17:07:04.000000000 +0200 -@@ -14,12 +14,12 @@ - #define STUART ((volatile unsigned long *)0x40700000) - #define HWUART ((volatile unsigned long *)0x41600000) - --#define UART FFUART -+#define UART STUART - - - static __inline__ void putc(char c) - { -- while (!(UART[5] & 0x20)); -+ while (!(UART[5] & 0x40)); - UART[0] = c; - } - -Index: linux-2.6.16.5-a/drivers/misc/ezx/ssp_pcap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ssp_pcap.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,673 @@ -+/* (c) Copyright Motorola Beijing 2002 all rights reserved. -+ -+ Project Name : EZX -+ Project No. : -+ Title : -+ File Name : -+ Description : -+ -+ ************** REVISION HISTORY ********************************************** -+ Date Author Reference -+ ======== ========== ========================== -+ 2002-07-01 weiqiang lin create -+*/ -+#ifndef SSP_PCAP_H -+#define SSP_PCAP_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define SSP_vibrate_start_command() SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_EN); \ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_EN) -+ -+#define SSP_vibrate_stop_command() SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_EN); \ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_EN) -+ -+#define SSP_PCAP_REGISTER_VALUE_LENGTH 16 -+ -+#define SSP_PCAP_REGISTER_WRITE_OP_BIT 0x80000000 -+#define SSP_PCAP_REGISTER_READ_OP_BIT 0x00000000 -+ -+#define SSP_PCAP_REGISTER_VALUE_UP_WORD_MASK 0xffff0000 -+#define SSP_PCAP_REGISTER_VALUE_DOWN_WORD_MASK 0x0000ffff -+ -+#define SSP_PCAP_REGISTER_VALUE_MASK 0x01ffffff -+#define SSP_PCAP_REGISTER_VALUE_MASK 0x01ffffff -+#define SSP_PCAP_REGISTER_ADDRESS_MASK 0x7c000000 -+#define SSP_PCAP_REGISTER_ADDRESS_SHIFT 26 -+#define SSP_PCAP_REGISTER_NUMBER 32 -+ -+#define SSP_PCAP_ADC_START_VALUE_SET_MASK 0xfffffc00 -+#define SSP_PCAP_ADC_START_VALUE 0x000001dd -+ -+ -+#define SSP_PCAP_PHONE_CDC_CLOCK_MASK 0x000001c0 -+#define SSP_PCAP_STEREO_SAMPLE_RATE_MASK 0x00000f00 -+#define SSP_PCAP_STEREO_BCLK_TIME_SLOT_MASK 0x00018000 -+#define SSP_PCAP_STEREO_CLOCK_MASK 0x0000001c -+#define SSP_PCAP_DIGITAL_AUDIO_MODE_MASK 0x00006000 -+#define SSP_PCAP_TOUCH_PANEL_POSITION_DETECT_MODE_MASK 0x000e0000 -+#define SSP_PCAP_MONO_PGA_MASK 0x00180000 -+ -+#define SSP_PCAP_VIBRATOR_VOLTAGE_LEVEL_MASK 0x00300000 -+ -+#define SSP_PCAP_AUDIO_IN_GAIN_MASK 0x0000001f -+#define SSP_PCAP_AUDIO_IN_GAIN_SHIFT 0 -+#define SSP_PCAP_AUDIO_OUT_GAIN_MASK 0x0001e000 -+#define SSP_PCAP_AUDIO_OUT_GAIN_SHIFT 13 -+ -+ -+#define SSP_PCAP_ADD1_VALUE_MASK 0x000003ff -+#define SSP_PCAP_ADD1_VALUE_SHIFT 0 -+#define SSP_PCAP_ADD2_VALUE_MASK 0x000ffc00 -+#define SSP_PCAP_ADD2_VALUE_SHIFT 10 -+ -+ -+#define PCAP_AUDIO_IN_GAIN_MAX_VALUE 31 -+#define PCAP_AUDIO_OUT_GAIN_MAX_VALUE 15 -+ -+#define PCAP_CLEAR_INTERRUPT_REGISTER 0x00141fdf -+#define PCAP_MASK_ALL_INTERRUPT 0x0013ffff -+ -+#define SSP_PCAP_TS_KEEPER_TIMER 100 /* 1 second */ -+#define START_ADC_DELAY_TIMER 1991 /* 540 us */ -+ -+#define SSP_SEND_PM_ALART_INTERVAL 1000 *HZ/1000 /* 1 second */ -+#define SSP_SEND_MSG_USB_ACCESSORY_INFO_DEBOUNCE 200 *HZ/1000 /* 200ms */ -+ -+struct ssp_interrupt_info -+{ -+ u32 type; -+ u32 status; -+ void* privdata; -+}; -+ -+#ifndef U8 -+#define U8 unsigned char -+#endif -+ -+#ifndef U32 -+#define U32 unsigned long -+#endif -+ -+#ifndef U16 -+#define U16 unsigned short -+#endif -+ -+#ifndef P_U16 -+#define P_U16 U16* -+#endif -+ -+#ifndef P_U32 -+#define P_U32 U32* -+#endif -+ -+#define SSP_SELECT_BUFFER (volatile unsigned long *)(0xf4000000) -+ -+#define SSP_SR_RNE 0x00000008 -+#define SSP_PCAP_BASE 0x00001000 -+/************************ STRUCTURES, ENUMS, AND TYPEDEFS **************************/ -+typedef enum accessoryStatus -+{ -+ ACCESSORY_DEVICE_STATUS_DETACHED = 0, -+ ACCESSORY_DEVICE_STATUS_ATTACHED , -+ ACCESSORY_DEVICE_STATUS_UNKNOW =0x000000ff -+}ACCESSORY_DEVICE_STATUS; -+ -+typedef enum accessoryType -+{ -+ ACCESSORY_DEVICE_NONE = 0, -+ ACCESSORY_DEVICE_SERIAL_PORT , -+ ACCESSORY_DEVICE_USB_PORT , -+ ACCESSORY_DEVICE_UNKNOW =0x000000ff -+}ACCESSORY_TYPE; -+ -+typedef enum pcapReturnStatus -+{ -+ SSP_PCAP_SUCCESS = 0, -+ SSP_PCAP_ERROR_REGISTER = SSP_PCAP_BASE+1, -+ SSP_PCAP_ERROR_VALUE = SSP_PCAP_BASE+2, -+ -+ SSP_PCAP_NOT_RUN = SSP_PCAP_BASE+0xff -+}SSP_PCAP_STATUS; -+ -+typedef enum pcapPortType -+{ -+ SSP_PCAP_SERIAL_PORT = 0x00000000, -+ SSP_PCAP_LOW_USB_PORT = 0x00000001, -+ SSP_PCAP_HIGH_USB_PORT = 0x00000002, -+ SSP_PCAP_UNKNOW_PORT = 0x000000ff -+}SSP_PCAP_PORT_TYPE; -+ -+typedef enum pcapInitDriverType -+{ -+ SSP_PCAP_TS_OPEN = 0x00000000, -+ SSP_PCAP_AUDIO_OPEN = 0x00000001, -+ SSP_PCAP_UNKNOW_DRIVER_OPEN = 0x000000ff -+}SSP_PCAP_INIT_DRIVER_TYPE; -+ -+ -+typedef enum pcapReturnBitStatus -+{ -+ SSP_PCAP_BIT_ZERO = 0x00000000, -+ SSP_PCAP_BIT_ONE = 0x00000001, -+ SSP_PCAP_BIT_ERROR = 0xff000000 -+}SSP_PCAP_BIT_STATUS; -+ -+typedef enum pcapCDCClkType -+{ -+ PCAP_CDC_CLK_IN_13M0 = 0x00000000, -+ PCAP_CDC_CLK_IN_15M36 = 0x00000040, -+ PCAP_CDC_CLK_IN_16M8 = 0x00000080, -+ PCAP_CDC_CLK_IN_19M44 = 0x000000c0, -+ PCAP_CDC_CLK_IN_26M0 = 0x00000100 -+}PHONE_CDC_CLOCK_TYPE; -+ -+typedef enum pcapST_SR -+{ -+ PCAP_ST_SAMPLE_RATE_8K = 0x00000000, -+ PCAP_ST_SAMPLE_RATE_11K = 0x00000100, -+ PCAP_ST_SAMPLE_RATE_12K = 0x00000200, -+ PCAP_ST_SAMPLE_RATE_16K = 0x00000300, -+ PCAP_ST_SAMPLE_RATE_22K = 0x00000400, -+ PCAP_ST_SAMPLE_RATE_24K = 0x00000500, -+ PCAP_ST_SAMPLE_RATE_32K = 0x00000600, -+ PCAP_ST_SAMPLE_RATE_44K = 0x00000700, -+ PCAP_ST_SAMPLE_RATE_48K = 0x00000800 -+}ST_SAMPLE_RATE_TYPE; -+ -+typedef enum pcapST_BCLK -+{ -+ PCAP_ST_BCLK_SLOT_16 = 0x00000000, -+ PCAP_ST_BCLK_SLOT_8 = 0x00008000, -+ PCAP_ST_BCLK_SLOT_4 = 0x00010000, -+ PCAP_ST_BCLK_SLOT_2 = 0x00018000, -+}ST_BCLK_TIME_SLOT_TYPE; -+ -+typedef enum pcapST_CLK -+{ -+ PCAP_ST_CLK_PLL_CLK_IN_13M0 = 0x00000000, -+ PCAP_ST_CLK_PLL_CLK_IN_15M36 = 0x00000004, -+ PCAP_ST_CLK_PLL_CLK_IN_16M8 = 0x00000008, -+ PCAP_ST_CLK_PLL_CLK_IN_19M44 = 0x0000000c, -+ PCAP_ST_CLK_PLL_CLK_IN_26M0 = 0x00000010, -+ PCAP_ST_CLK_PLL_CLK_IN_EXT_MCLK = 0x00000014, -+ PCAP_ST_CLK_PLL_CLK_IN_FSYNC = 0x00000018, -+ PCAP_ST_CLK_PLL_CLK_IN_BITCLK = 0x0000001c -+}ST_CLK_TYPE; -+ -+typedef enum pcapDigitalAudioInterfaceMode -+{ -+ PCAP_DIGITAL_AUDIO_INTERFACE_NORMAL = 0x00000000, -+ PCAP_DIGITAL_AUDIO_INTERFACE_NETWORK = 0x00002000, -+ PCAP_DIGITAL_AUDIO_INTERFACE_I2S = 0x00004000 -+}DIG_AUD_MODE_TYPE; -+ -+typedef enum pcapMono -+{ -+ PCAP_MONO_PGA_R_L_STEREO = 0x00000000, -+ PCAP_MONO_PGA_RL = 0x00080000, -+ PCAP_MONO_PGA_RL_3DB = 0x00100000, -+ PCAP_MONO_PGA_RL_6DB = 0x00180000 -+}MONO_TYPE; -+ -+typedef enum pcapVibratorVoltageLevel -+{ -+ PCAP_VIBRATOR_VOLTAGE_LEVEL0 = 0x00000000, -+ PCAP_VIBRATOR_VOLTAGE_LEVEL1 = 0x00100000, -+ PCAP_VIBRATOR_VOLTAGE_LEVEL2 = 0x00200000, -+ PCAP_VIBRATOR_VOLTAGE_LEVEL3 = 0x00300000 -+}VibratorVoltageLevel_TYPE; -+ -+typedef enum pcapTouchScreenMode -+{ -+ PCAP_TS_POSITION_X_MEASUREMENT = 0x00000000, -+ PCAP_TS_POSITION_XY_MEASUREMENT = 0x00020000, -+ PCAP_TS_PRESSURE_MEASUREMENT = 0x00040000, -+ PCAP_TS_PLATE_X_MEASUREMENT = 0x00060000, -+ PCAP_TS_PLATE_Y_MEASUREMENT = 0x00080000, -+ PCAP_TS_STANDBY_MODE = 0x000a0000, -+ PCAP_TS_NONTS_MODE = 0x000c0000 -+}TOUCH_SCREEN_DETECT_TYPE; -+ -+typedef enum pcapADJRegister -+{ -+ SSP_PCAP_ADJ_ISR_REGISTER = 0x00, -+ SSP_PCAP_ADJ_MSR_REGISTER = 0x01, -+ SSP_PCAP_ADJ_PSTAT_REGISTER = 0x02, -+ SSP_PCAP_ADJ_VREG2_REGISTER = 0x06, -+ SSP_PCAP_ADJ_AUX_VREG_REGISTER = 0x07, -+ SSP_PCAP_ADJ_BATT_DAC_REGISTER = 0x08, -+ SSP_PCAP_ADJ_ADC1_REGISTER = 0x09, -+ SSP_PCAP_ADJ_ADC2_REGISTER = 0x0a, -+ SSP_PCAP_ADJ_AUD_CODEC_REGISTER = 0x0b, -+ SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER = 0x0c, -+ SSP_PCAP_ADJ_ST_DAC_REGISTER = 0x0d, -+ SSP_PCAP_ADJ_BUSCTRL_REGISTER = 0x14, -+ SSP_PCAP_ADJ_PERIPH_REGISTER = 0x15, -+ SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER = 0x18, -+ SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER = 0x1a, -+ SSP_PCAP_ADJ_GP_REG_REGISTER = 0x1b -+}SSP_PCAP_SECONDARY_PROCESSOR_REGISTER; -+ -+typedef enum pcapADJBit_SetType -+{ -+ SSP_PCAP_ADJ_BIT_ISR_ADCDONEI = 0x00000001, -+ SSP_PCAP_ADJ_BIT_ISR_TSI = 0x00000002, -+ SSP_PCAP_ADJ_BIT_ISR_1HZI = 0x00000004, -+ SSP_PCAP_ADJ_BIT_ISR_WHI = 0x00000008, -+ SSP_PCAP_ADJ_BIT_ISR_WLI = 0x00000010, -+ SSP_PCAP_ADJ_BIT_ISR_TODAI = 0x00000020, -+ SSP_PCAP_ADJ_BIT_ISR_USB4VI = 0x00000040, -+ SSP_PCAP_ADJ_BIT_ISR_ONOFFI = 0x00000080, -+ SSP_PCAP_ADJ_BIT_ISR_ONOFF2I = 0x00000100, -+ SSP_PCAP_ADJ_BIT_ISR_USB1VI = 0x00000200, -+ SSP_PCAP_ADJ_BIT_ISR_MOBPORTI = 0x00000400, -+ SSP_PCAP_ADJ_BIT_ISR_MB2I = 0x00000800, -+ SSP_PCAP_ADJ_BIT_ISR_A1I = 0x00001000, -+ SSP_PCAP_ADJ_BIT_ISR_STI = 0x00002000, -+ SSP_PCAP_ADJ_BIT_ISR_PCI = 0x00004000, -+ SSP_PCAP_ADJ_BIT_ISR_WARMI = 0x00008000, -+ SSP_PCAP_ADJ_BIT_ISR_EOLI = 0x00010000, -+ SSP_PCAP_ADJ_BIT_ISR_CLKI = 0x00020000, -+ SSP_PCAP_ADJ_BIT_ISR_SYS_RSTI = 0x00040000, -+ SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I = 0x00100000, -+ SSP_PCAP_ADJ_BIT_ISR_SOFT_RESETI = 0x00200000, -+ SSP_PCAP_ADJ_BIT_ISR_MNEXBI = 0x00400000, -+ -+ SSP_PCAP_ADJ_BIT_MSR_ADCDONEM = 0x04000001, -+ SSP_PCAP_ADJ_BIT_MSR_TSM = 0x04000002, -+ SSP_PCAP_ADJ_BIT_MSR_1HZM = 0x04000004, -+ SSP_PCAP_ADJ_BIT_MSR_WHM = 0x04000008, -+ SSP_PCAP_ADJ_BIT_MSR_WLM = 0x04000010, -+ SSP_PCAP_ADJ_BIT_MSR_TODAM = 0x04000020, -+ SSP_PCAP_ADJ_BIT_MSR_USB4VM = 0x04000040, -+ SSP_PCAP_ADJ_BIT_MSR_ONOFFM = 0x04000080, -+ SSP_PCAP_ADJ_BIT_MSR_ONOFF2M = 0x04000100, -+ SSP_PCAP_ADJ_BIT_MSR_USB1VM = 0x04000200, -+ SSP_PCAP_ADJ_BIT_MSR_MOBPORTM = 0x04000400, -+ SSP_PCAP_ADJ_BIT_MSR_MB2M = 0x04000800, -+ SSP_PCAP_ADJ_BIT_MSR_A1M = 0x04001000, -+ SSP_PCAP_ADJ_BIT_MSR_STM = 0x04002000, -+ SSP_PCAP_ADJ_BIT_MSR_PCM = 0x04004000, -+ SSP_PCAP_ADJ_BIT_MSR_WARMM = 0x04008000, -+ SSP_PCAP_ADJ_BIT_MSR_EOLM = 0x04010000, -+ SSP_PCAP_ADJ_BIT_MSR_CLKM = 0x04020000, -+ SSP_PCAP_ADJ_BIT_MSR_SYS_RSTM = 0x04040000, -+ SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M = 0x04100000, -+ SSP_PCAP_ADJ_BIT_MSR_SOFT_RESETM = 0x04200000, -+ SSP_PCAP_ADJ_BIT_MSR_MNEXBM = 0x04400000, -+ -+ SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V = 0x08000040, -+ SSP_PCAP_ADJ_BIT_PSTAT_ONOFFSNS = 0x08000080, -+ SSP_PCAP_ADJ_BIT_PSTAT_ONOFFSNS2 = 0x08000100, -+ SSP_PCAP_ADJ_BIT_PSTAT_USBDET_1V = 0x08000200, -+ SSP_PCAP_ADJ_BIT_PSTAT_MOBSENSB = 0x08000400, -+ SSP_PCAP_ADJ_BIT_PSTAT_MB2SNS = 0x08000800, -+ SSP_PCAP_ADJ_BIT_PSTAT_A1SNS = 0x08001000, -+ SSP_PCAP_ADJ_BIT_PSTAT_MSTB = 0x08002000, -+ SSP_PCAP_ADJ_BIT_PSTAT_EOL_STAT = 0x08010000, -+ SSP_PCAP_ADJ_BIT_PSTAT_CLK_STAT = 0x08020000, -+ SSP_PCAP_ADJ_BIT_PSTAT_SYS_RST = 0x08040000, -+ SSP_PCAP_ADJ_BIT_PSTAT_BATTFBSNS = 0x08080000, -+ SSP_PCAP_ADJ_BIT_PSTAT_BATT_DET_IN_SNS = 0x08200000, -+ SSP_PCAP_ADJ_BIT_PSTAT_MNEXBSNS = 0x08400000, -+ SSP_PCAP_ADJ_BIT_PSTAT_WARM_SYS_RST = 0x08800000, -+ -+ SSP_PCAP_ADJ_BIT_VREG2_V1_STBY = 0x18000001, -+ SSP_PCAP_ADJ_BIT_VREG2_V2_STBY = 0x18000002, -+ SSP_PCAP_ADJ_BIT_VREG2_V3_STBY = 0x18000004, -+ SSP_PCAP_ADJ_BIT_VREG2_V4_STBY = 0x18000008, -+ SSP_PCAP_ADJ_BIT_VREG2_V5_STBY = 0x18000010, -+ SSP_PCAP_ADJ_BIT_VREG2_V6_STBY = 0x18000020, -+ SSP_PCAP_ADJ_BIT_VREG2_V7_STBY = 0x18000040, -+ SSP_PCAP_ADJ_BIT_VREG2_V8_STBY = 0x18000080, -+ SSP_PCAP_ADJ_BIT_VREG2_V9_STBY = 0x18000100, -+ SSP_PCAP_ADJ_BIT_VREG2_V10_STBY = 0x18000200, -+ SSP_PCAP_ADJ_BIT_VREG2_V1_LOWPWR = 0x18000400, -+ SSP_PCAP_ADJ_BIT_VREG2_V2_LOWPWR = 0x18000800, -+ SSP_PCAP_ADJ_BIT_VREG2_V3_LOWPWR = 0x18001000, -+ SSP_PCAP_ADJ_BIT_VREG2_V4_LOWPWR = 0x18002000, -+ SSP_PCAP_ADJ_BIT_VREG2_V5_LOWPWR = 0x18004000, -+ SSP_PCAP_ADJ_BIT_VREG2_V6_LOWPWR = 0x18008000, -+ SSP_PCAP_ADJ_BIT_VREG2_V7_LOWPWR = 0x18010000, -+ SSP_PCAP_ADJ_BIT_VREG2_V8_LOWPWR = 0x18020000, -+ SSP_PCAP_ADJ_BIT_VREG2_V9_LOWPWR = 0x18040000, -+ SSP_PCAP_ADJ_BIT_VREG2_V10_LOWPWR = 0x18080000, -+ -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX1_EN = 0x1c000002, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX1_0 = 0x1c000004, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX1_1 = 0x1c000008, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_EN = 0x1c000010, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_0 = 0x1c000020, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_1 = 0x1c000040, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX3_EN = 0x1c000080, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX3_0 = 0x1c000100, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX3_1 = 0x1c000200, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX3_2 = 0x1c000400, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX3_3 = 0x1c000800, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX4_EN = 0x1c001000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX4_0 = 0x1c002000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX4_1 = 0x1c004000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VSIM2_EN = 0x1c010000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VSIM_EN = 0x1c020000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VSIM_0 = 0x1c040000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_EN = 0x1c080000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_0 = 0x1c100000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_V_VIB_1 = 0x1c200000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX1_STBY = 0x1c400000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX1_LOWPWR = 0x1c800000, -+ SSP_PCAP_ADJ_BIT_AUX_VREG_SW3_STBY = 0x1d000000, -+ -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC0 = 0x20000001, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC1 = 0x20000002, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC2 = 0x20000004, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC3 = 0x20000008, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC4 = 0x20000010, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC5 = 0x20000020, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC6 = 0x20000040, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_DAC7 = 0x20000080, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_B_FDBK = 0x20000100, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_EXT_ISENSE = 0x20000200, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_V_COIN0 = 0x20000400, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_V_COIN1 = 0x20000800, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_V_COIN2 = 0x20001000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_V_COIN3 = 0x20002000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_I_COIN = 0x20004000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_COIN_CH_EN = 0x20008000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_EOL_SEL0 = 0x20020000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_EOL_SEL1 = 0x20040000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_EOL_SEL2 = 0x20080000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_EOL_CMP_EN = 0x20100000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_BATT_DET_EN = 0x20200000, -+ SSP_PCAP_ADJ_BIT_BATT_DAC_THERMBIAS_CTRL = 0x20400000, -+ -+ SSP_PCAP_ADJ_BIT_ADC1_ADEN = 0x24000001, -+ SSP_PCAP_ADJ_BIT_ADC1_RAND = 0x24000002, -+ SSP_PCAP_ADJ_BIT_ADC1_AD_SEL1 = 0x24000004, -+ SSP_PCAP_ADJ_BIT_ADC1_AD_SEL2 = 0x24000008, -+ SSP_PCAP_ADJ_BIT_ADC1_ADA10 = 0x24000010, -+ SSP_PCAP_ADJ_BIT_ADC1_ADA11 = 0x24000020, -+ SSP_PCAP_ADJ_BIT_ADC1_ADA12 = 0x24000040, -+ SSP_PCAP_ADJ_BIT_ADC1_ADA20 = 0x24000080, -+ SSP_PCAP_ADJ_BIT_ADC1_ADA21 = 0x24000100, -+ SSP_PCAP_ADJ_BIT_ADC1_ADA22 = 0x24000200, -+ SSP_PCAP_ADJ_BIT_ADC1_ATO0 = 0x24000400, -+ SSP_PCAP_ADJ_BIT_ADC1_ATO1 = 0x24000800, -+ SSP_PCAP_ADJ_BIT_ADC1_ATO2 = 0x24001000, -+ SSP_PCAP_ADJ_BIT_ADC1_ATO3 = 0x24002000, -+ SSP_PCAP_ADJ_BIT_ADC1_ATOX = 0x24004000, -+ SSP_PCAP_ADJ_BIT_ADC1_MTR1 = 0x24008000, -+ SSP_PCAP_ADJ_BIT_ADC1_MTR2 = 0x24010000, -+ SSP_PCAP_ADJ_BIT_ADC1_TS_M0 = 0x24020000, -+ SSP_PCAP_ADJ_BIT_ADC1_TS_M1 = 0x24040000, -+ SSP_PCAP_ADJ_BIT_ADC1_TS_M2 = 0x24080000, -+ SSP_PCAP_ADJ_BIT_ADC1_TS_REF_LOWPWR = 0x24100000, -+ SSP_PCAP_ADJ_BIT_ADC1_TS_REFENB = 0x24200000, -+ SSP_PCAP_ADJ_BIT_ADC1_BATT_I_POLARITY = 0x24400000, -+ SSP_PCAP_ADJ_BIT_ADC1_BATT_I_ADC = 0x24800000, -+ -+ SSP_PCAP_ADJ_BIT_ADC2_ADD10 = 0x28000001, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD11 = 0x28000002, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD12 = 0x28000004, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD13 = 0x28000008, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD14 = 0x28000010, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD15 = 0x28000020, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD16 = 0x28000040, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD17 = 0x28000080, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD18 = 0x28000100, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD19 = 0x28000200, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD20 = 0x28000400, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD21 = 0x28000800, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD22 = 0x28001000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD23 = 0x28002000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD24 = 0x28004000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD25 = 0x28008000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD26 = 0x28010000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD27 = 0x28020000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD28 = 0x28040000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADD29 = 0x28080000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADINC1 = 0x28100000, -+ SSP_PCAP_ADJ_BIT_ADC2_ADINC2 = 0x28200000, -+ SSP_PCAP_ADJ_BIT_ADC2_ASC = 0x28400000, -+ -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_AUDIHPF = 0x2c000001, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_SMB = 0x2c000002, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_AUDOHPF = 0x2c000004, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CD_TS = 0x2c000008, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_DLM = 0x2c000010, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_ADITH = 0x2c000020, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CDC_CLK0 = 0x2c000040, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CDC_CLK1 = 0x2c000080, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CDC_CLK2 = 0x2c000100, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CLK_INV = 0x2c000200, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_FS_INV = 0x2c000400, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_DF_RESET = 0x2c000800, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CDC_EN = 0x2c001000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CDC_CLK_EN = 0x2c002000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_FS_8K_16K = 0x2c004000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_DIG_AUD_IN = 0x2c008000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CLK_IN_SEL = 0x2c010000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2_MUX = 0x2c020000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2IG0 = 0x2c040000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2IG1 = 0x2c080000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2IG2 = 0x2c100000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2IG3 = 0x2c200000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2IG4 = 0x2c400000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_MIC2IG_PRI_ADJ = 0x2c800000, -+ SSP_PCAP_ADJ_BIT_AUD_CODEC_CDC_PRI_ADJ = 0x2c200000, -+ -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_A1_EN = 0x30000001, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_A2_EN = 0x30000002, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_A4_EN = 0x30000010, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_ARIGHT_EN = 0x30000020, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_ALEFT_EN = 0x30000040, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_CD_BYP = 0x30000080, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_CDC_SW = 0x30000100, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_ST_DAC_SW = 0x30000200, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_PGA_IN_SW = 0x30000400, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_PGA_R_EN = 0x30000800, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_PGA_L_EN = 0x30001000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_AUDOG0 = 0x30002000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_AUDOG1 = 0x30004000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_AUDOG2 = 0x30008000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_AUDOG3 = 0x30010000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_A1CTRL = 0x30020000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_MONO0 = 0x30080000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_MONO1 = 0x30100000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_AUDOG_PRI_ADJ = 0x30200000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_MONO_PRI_ADJ = 0x30400000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_RX_PRI_ADJ0 = 0x30800000, -+ SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_RX_PRI_ADJ1 = 0x31000000, -+ -+ SSP_PCAP_ADJ_BIT_ST_DAC_SMB_ST_DAC = 0x34000001, -+ SSP_PCAP_ADJ_BIT_ST_DAC_STDET_EN = 0x34000002, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_CLK0 = 0x34000004, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_CLK1 = 0x34000008, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_CLK2 = 0x34000010, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_CLK_EN = 0x34000020, -+ SSP_PCAP_ADJ_BIT_ST_DAC_DF_RESET_ST_DAC = 0x34000040, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_DAC_EN = 0x34000080, -+ SSP_PCAP_ADJ_BIT_ST_DAC_SR0 = 0x34000100, -+ SSP_PCAP_ADJ_BIT_ST_DAC_SR1 = 0x34000200, -+ SSP_PCAP_ADJ_BIT_ST_DAC_SR2 = 0x34000400, -+ SSP_PCAP_ADJ_BIT_ST_DAC_SR3 = 0x34000800, -+ SSP_PCAP_ADJ_BIT_ST_DAC_DIG_AUD_IN_ST_DAC = 0x34001000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_DIG_AUD_FS0 = 0x34002000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_DIG_AUD_FS1 = 0x34004000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_BCLK0 = 0x34008000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_BCLK1 = 0x34010000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_CLK_INV = 0x34020000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_FS_INV = 0x34040000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_DAC_CLK_IN_SEL = 0x34080000, -+ SSP_PCAP_ADJ_BIT_ST_DAC_ST_DAC_PRI_ADJ = 0x35000000, -+ -+ SSP_PCAP_ADJ_BIT_BUSCTRL_FSENB = 0x50000001, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_USB_SUSPEND = 0x50000002, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU = 0x50000004, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PD = 0x50000008, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN = 0x50000010, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PS = 0x50000020, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_MSTR_EN = 0x50000040, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_VBUS_PD_ENB = 0x50000080, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_CURRLIM = 0x50000100, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB = 0x50000200, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_RS232_DIR = 0x50000400, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_SE0_CONN = 0x50000800, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PDM = 0x50001000, -+ SSP_PCAP_ADJ_BIT_BUSCTRL_BUS_PRI_ADJ = 0x51000000, -+ -+ SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL0 = 0x54000001, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL1 = 0x54000002, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL2 = 0x54000004, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL3 = 0x54000008, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL4 = 0x54000010, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_EN = 0x54000020, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_EN = 0x54000040, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_CTRL0 = 0x54000080, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_CTRL1 = 0x54000100, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_CTRL2 = 0x54000200, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_CTRL3 = 0x54000400, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_CTRL0 = 0x54000800, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_CTRL1 = 0x54001000, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_CTRL2 = 0x54002000, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_CTRL3 = 0x54004000, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_I0 = 0x54008000, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDR_I1 = 0x54010000, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_I0 = 0x54020000, -+ SSP_PCAP_ADJ_BIT_PERIPH_LEDG_I1 = 0x54040000, -+ SSP_PCAP_ADJ_BIT_PERIPH_SKIP = 0x54080000, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL0 = 0x54100000, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL1 = 0x54200000, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL2 = 0x54400000, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL3 = 0x54800000, -+ SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL4 = 0x55000000, -+ -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX2_STBY = 0x60000001, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX2_LOWPWR = 0x60000002, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX3_STBY = 0x60000004, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX3_LOWPWR = 0x60000008, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX4_STBY = 0x60000010, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX4_LOWPWR = 0x60000020, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VSIM_LOWPWR = 0x60000040, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VSIM2_LOWPWR = 0x60000080, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE00 = 0x60000100, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE01 = 0x60000200, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE10 = 0x60000400, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE11 = 0x60000800, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW10_DVS = 0x60001000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW11_DVS = 0x60002000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW12_DVS = 0x60004000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW13_DVS = 0x60008000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW2_MODE00 = 0x60010000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW2_MODE01 = 0x60020000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW2_MODE10 = 0x60040000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW2_MODE11 = 0x60080000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW20_DVS = 0x60100000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW21_DVS = 0x60200000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW22_DVS = 0x60400000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW23_DVS = 0x60800000, -+ SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VC_STBY = 0x61000000, -+ -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIG0 = 0x68000001, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIG1 = 0x68000002, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIG2 = 0x68000004, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIG3 = 0x68000008, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIG4 = 0x68000010, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A3_EN = 0x68000020, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A3_MUX = 0x68000040, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A5_EN = 0x68000080, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A5_MUX = 0x68000100, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_EXT_MIC_MUX = 0x68000200, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_MB_ON2 = 0x68000400, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_MB_ON1 = 0x68000800, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A1ID_TX = 0x68001000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A1_CONFIG = 0x68002000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AHS_CONFIG = 0x68004000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_A2_CONFIG = 0x68008000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIO_LOWPWR = 0x68080000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIO_STBY = 0x68100000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_V2_EN_2 = 0x68200000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_AUDIG_PRI_ADJ = 0x68400000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_TX_PRI_ADJ0 = 0x68800000, -+ SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_TX_PRI_ADJ1 = 0x69000000, -+ -+ SSP_PCAP_ADJ_BIT_SYS_RST_CLR = 0x6c000001, -+ SSP_PCAP_ADJ_BIT_SYS_RST_MODE0 = 0x6c000002, -+ SSP_PCAP_ADJ_BIT_SYS_RST_MODE1 = 0x6c000004, -+ SSP_PCAP_ADJ_BIT_SYS_VFLASH_0 = 0x6c000008, -+ SSP_PCAP_ADJ_BIT_SYS_VFLASH_1 = 0x6c000010, -+ SSP_PCAP_ADJ_BIT_SYS_MID_SELECT = 0x6c000020, -+ SSP_PCAP_ADJ_BIT_SYS_MID_FET = 0x6c000040, -+ SSP_PCAP_ADJ_BIT_SYS_MAIN_LOW = 0x6c000080, -+ SSP_PCAP_ADJ_BIT_SYS_BATTFB_DIS = 0x6c000100, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG9 = 0x6c000200, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG10 = 0x6c000400, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG11 = 0x6c000800, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG12 = 0x6c001000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG13 = 0x6c002000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG14 = 0x6c004000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG15 = 0x6c008000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG16 = 0x6c010000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG17 = 0x6c020000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG18 = 0x6c040000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG19 = 0x6c080000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG20 = 0x6c100000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG21 = 0x6c200000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG22 = 0x6c400000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG23 = 0x6c800000, -+ SSP_PCAP_ADJ_BIT_SYS_GP_REG24 = 0x6d000000 -+ -+}SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE; -+ -+/************************ FUNCTION PROTOTYPES **************************************/ -+extern void ssp_pcap_init(void); -+extern void ssp_pcap_release(void); -+ -+extern void ssp_pcap_open(SSP_PCAP_INIT_DRIVER_TYPE portType); -+extern void ssp_pcap_close(void); -+ -+extern void ssp_pcap_intoSleep_callBack(void); -+extern void ssp_pcap_wakeUp_callBack(void); -+ -+ -+extern SSP_PCAP_STATUS SSP_PCAP_write_data_to_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER ssp_pcap_register,U32 ssp_pcap_register_value); -+extern SSP_PCAP_STATUS SSP_PCAP_read_data_from_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER ssp_pcap_register,P_U32 p_ssp_pcap_register_value); -+ -+extern SSP_PCAP_STATUS SSP_PCAP_bit_set(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+extern SSP_PCAP_STATUS SSP_PCAP_bit_clean(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+extern SSP_PCAP_BIT_STATUS SSP_PCAP_get_bit_from_buffer(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+extern SSP_PCAP_BIT_STATUS SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+extern U32 SSP_PCAP_get_register_value_from_buffer(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER ssp_pcap_register ) ; -+ -+extern SSP_PCAP_STATUS SSP_PCAP_TSI_mode_set(TOUCH_SCREEN_DETECT_TYPE mode_Type ); -+extern SSP_PCAP_STATUS SSP_PCAP_TSI_start_XY_read(void); -+extern SSP_PCAP_STATUS SSP_PCAP_TSI_get_XY_value(P_U16 p_x,P_U16 p_y); -+extern SSP_PCAP_STATUS SSP_PCAP_CDC_CLK_set(PHONE_CDC_CLOCK_TYPE clkType); -+ -+extern SSP_PCAP_STATUS SSP_PCAP_CDC_SR_set(ST_SAMPLE_RATE_TYPE srType); -+extern SSP_PCAP_STATUS SSP_PCAP_BCLK_set(ST_BCLK_TIME_SLOT_TYPE bclkType); -+extern SSP_PCAP_STATUS SSP_PCAP_STCLK_set(ST_CLK_TYPE stClkType); -+extern SSP_PCAP_STATUS SSP_PCAP_DIG_AUD_FS_set(DIG_AUD_MODE_TYPE fsType); -+extern SSP_PCAP_STATUS SSP_PCAP_AUDIG_set(U32 audioInGain); -+extern SSP_PCAP_STATUS SSP_PCAP_MONO_set(MONO_TYPE monoType); -+extern SSP_PCAP_STATUS SSP_PCAP_AUDOG_set(U32 audioOutGain); -+ -+extern SSP_PCAP_STATUS SSP_PCAP_V_VIB_level_set(VibratorVoltageLevel_TYPE VIBLevelType); -+extern SSP_PCAP_STATUS SSP_PCAP_configure_USB_UART_transeiver(SSP_PCAP_PORT_TYPE portType); -+extern SSP_PCAP_BIT_STATUS SSP_PCAP_get_audio_in_status(void); -+ -+/* for log */ -+extern void pcap_log_add_pure_data(u8* pData,u32 len); -+extern void pcap_log_add_data(u8* pData,u32 len); -+ -+/* screen lock on/off handler */ -+extern void ssp_pcap_screenlock_lock(u32 data); -+extern void ssp_pcap_screenlock_unlock(u32 data); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -Index: linux-2.6.16.5-a/drivers/misc/ezx/ssp_pcap_main.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ssp_pcap_main.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,2568 @@ -+/* (c) Copyright Motorola 2002, All rights reserved. -+ Motorola Confidential Proprietary -+ Contains confidential proprietary information of Motorola, Inc. -+ Reverse engineering is prohibited. -+ The copyright notice does not imply publication. -+ -+ Project Name : EZX -+ Project No. : -+ Title : -+ File Name : -+ Description : -+ -+ ************** REVISION HISTORY ********************************************** -+ Date Author Reference -+ ======== ========== ========================== -+ 2002-07-02 weiqiang lin create -+ 2004-02-09 weiqiang lin update PM for Bulverde OS libdd74345. -+ 2004-04-13 weiqiang lin update accessory usb attach and detach -+ 2004-04-27 weiqiang lin send the USB accessory detach/attach information to PM -+ 2004-05-11 weiqiang lin after sleep TC_MM_EN will be high else will be low -+ 2004-06-24 Cheng Xuefeng remove the SSP_PCAP_configure_USB_UART_transeiver() -+ 2004-08-19 weiqiang lin after sleep set SW1 output 1.3V and low power mode and when headset button press/release, send an event to PM -+ 2004-08-31 weiqiang lin remove the headset button press/release event to PM. -+*/ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/errno.h> -+#include <linux/string.h> -+#include <linux/interrupt.h> -+#include <linux/slab.h> -+#include <linux/fb.h> -+#include <linux/delay.h> -+#include <linux/pm.h> -+#include <linux/init.h> -+#include <linux/apm_bios.h> -+ -+#include <asm/hardware.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+ -+#include <asm/arch/pxa-regs.h> -+#include <asm/arch/ezx.h> -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#include "ssp_pcap.h" -+//#define SSP_PCAP_OPERATE_WITH_SPI -+ -+static u32 ssp_pcap_operate_pin_with_inverter; -+static u32 ssp_pcap_rxd_pin_with_inverter; -+//#define SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ -+#ifdef _DEBUG_BOARD -+#define SSP_PCAP_DEBUG_BOARD -+#endif -+ -+/* 0 -- unlock 1- lock */ -+static u32 ssp_pcap_screenlock_status; -+static struct timer_list ssp_pcap_screenlock_timer; -+static void ssp_pcap_screenlock_lockhandler(u32 data); -+ -+static struct timer_list ssp_start_adc_timer; -+static struct timer_list ssp_tsi_timer; -+static struct timer_list ssp_usb_accessory_debounce_timer; -+ -+static U32 ssp_pcap_status = 0; -+static U32 ssp_pcap_registerValue[SSP_PCAP_REGISTER_NUMBER] = {0}; -+ -+SSP_PCAP_BIT_STATUS SSP_PCAP_get_audio_in_status(void); -+SSP_PCAP_STATUS SSP_PCAP_write_data_to_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER ssp_pcap_register,U32 ssp_pcap_register_value); -+SSP_PCAP_STATUS SSP_PCAP_read_data_from_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER ssp_pcap_register,P_U32 p_ssp_pcap_register_value); -+ -+SSP_PCAP_STATUS SSP_PCAP_bit_set(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+SSP_PCAP_STATUS SSP_PCAP_bit_clean(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+SSP_PCAP_BIT_STATUS SSP_PCAP_get_bit_from_buffer(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+SSP_PCAP_BIT_STATUS SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE ssp_pcap_bit ) ; -+U32 SSP_PCAP_get_register_value_from_buffer(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER ssp_pcap_register ) ; -+ -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+static wait_queue_head_t ssp_pcap_send_wait; -+static U32 ssp_pcap_readValue; -+static void ssp_interrupt_routine(int irq, void *dev_id, struct pt_regs *regs ); -+void ssp_put_intoData(U32 pcapValue); -+#endif -+ -+static spinlock_t pcapoperation_lock = SPIN_LOCK_UNLOCKED; -+static void ssp_pcap_interrupt_routine(int irq, void *dev_id, struct pt_regs *regs ); -+//static U32 ssp_pcapRegisterReadOut = 0; -+ -+//static void usb_hardware_switch(void); -+ -+//static struct timer_list usb_switch_timer; -+ -+void ssp_pcap_init(void); -+void ssp_pcap_release(void); -+void ssp_pcap_clear_int(void); -+void ssp_pcap_intoSleepCallBack(void); -+void ssp_pcap_wakeUpCallBack(void); -+ -+extern int usb_gpio_init(void); -+extern int stop_usb(void); -+static void ssp_tsi_keeper(u32 data); -+static void ssp_usb_accessory_debounce_handler(u32 data); -+ -+extern void ezx_ts_dataReadok_interrupt(int irq,void* dev_id, struct pt_regs *regs); -+extern void ezx_ts_touch_interrupt(int irq,void* dev_id, struct pt_regs *regs); -+void (*headjack_change_interrupt_routine)(int ch,void *dev_id,struct pt_regs *regs); -+void (*mic_change_interrupt_routine)(int ch,void *dev_id,struct pt_regs *regs); -+//extern u8 pxafb_ezx_getLCD_status(void); -+ -+int (*cable_hotplug_attach)(ACCESSORY_DEVICE_STATUS status); -+static struct ssp_interrupt_info sspUsbAccessoryInfo; -+ -+void SSP_PCAP_MMCSD_poweroff(void) -+{ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_EN); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_EN); -+} -+EXPORT_SYMBOL(SSP_PCAP_MMCSD_poweroff); -+ -+void SSP_PCAP_MMCSD_poweron(void) -+{ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_EN); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_EN); -+} -+EXPORT_SYMBOL(SSP_PCAP_MMCSD_poweron); -+ -+static void accessory_bus_detect_handler(ACCESSORY_TYPE type,ACCESSORY_DEVICE_STATUS status,void* privdata ) -+{ -+ sspUsbAccessoryInfo.type = (u32)type; -+ sspUsbAccessoryInfo.status = (u32)status; -+ sspUsbAccessoryInfo.privdata = privdata; -+ del_timer(&ssp_usb_accessory_debounce_timer); -+ ssp_usb_accessory_debounce_timer.data = ( unsigned long ) &sspUsbAccessoryInfo; -+ /* 2 seconds protect timer */ -+ ssp_usb_accessory_debounce_timer.expires = jiffies + SSP_SEND_MSG_USB_ACCESSORY_INFO_DEBOUNCE; -+ add_timer(&ssp_usb_accessory_debounce_timer); -+ return; -+} -+ -+static void ssp_usb_accessory_debounce_handler(u32 data) -+{ -+ struct ssp_interrupt_info * pMyInfo; -+ ACCESSORY_TYPE type; -+ ACCESSORY_DEVICE_STATUS status; -+ -+ pMyInfo = (struct ssp_interrupt_info *)data; -+ type = ( ACCESSORY_TYPE) pMyInfo->type; -+ status = ( ACCESSORY_DEVICE_STATUS) pMyInfo->status; -+ -+ switch(type) -+ { -+ case ACCESSORY_DEVICE_USB_PORT: -+ if (cable_hotplug_attach) -+ (*cable_hotplug_attach)(status); -+ switch(status) -+ { -+ case ACCESSORY_DEVICE_STATUS_DETACHED: -+ apm_queue_event(KRNL_ACCS_DETACH); -+ break; -+ case ACCESSORY_DEVICE_STATUS_ATTACHED: -+ apm_queue_event(KRNL_ACCS_ATTACH); -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ return; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: log system stored in buffer. it can output via FFUART. also you can change a little to other output mode. -+ -+ INPUTS: none. -+ -+ -+ OUTPUTS: none. -+ -+ -+ IMPORTANT NOTES: the macro PCAP_LOG_FFUART_OUT is a switch. -+ it is auto-output to FFUART every PCAP_LOG_OUTPUT_TIMER seconds -+ -+ -+---------------------------------------------------------------------------*/ -+/* record log system by linwq */ -+//#define PCAP_LOG_FFUART_OUT -+ -+#ifdef PCAP_LOG_FFUART_OUT -+static struct timer_list pcap_outlog_timer; -+ -+#define PCAP_LOG_OUTPUT_TIMER 60 -+#define PCAP_LOG_RECORD_LENGTH 50000 -+ -+unsigned char pcap_log_data[PCAP_LOG_RECORD_LENGTH]; -+ -+u8* pcap_log_now_address = pcap_log_data; -+#define PCAP_LOG_START_ADDRESS pcap_log_data -+#define PCAP_LOG_END_ADDRESS pcap_log_data + PCAP_LOG_RECORD_LENGTH -+u32 pcap_log_len = 0; -+ -+void pcap_log_add_pure_data(u8* pData,u32 len) -+{ -+ u32 i; -+ if ((pData ==NULL)|| len == 0) -+ return; -+ for(i = 0;i<len;i++) -+ { -+ *pcap_log_now_address ++ = pData[i]; -+ if( PCAP_LOG_END_ADDRESS == pcap_log_now_address ) -+ pcap_log_now_address = PCAP_LOG_START_ADDRESS; -+ pcap_log_len++; -+ if(pcap_log_len >= PCAP_LOG_RECORD_LENGTH) -+ pcap_log_len = PCAP_LOG_RECORD_LENGTH; -+ } -+ return; -+} -+ -+void pcap_log_add_data(u8* pData,u32 len) -+{ -+ u32 i; -+ u8 temp[20]; -+ if ((pData ==NULL)|| len == 0) -+ return; -+ sprintf(temp,"\n <%d MS>",(int)(OSCR/3686)); -+ for(i = 0;i<(u32)strlen(temp);i++) -+ { -+ *pcap_log_now_address ++ = temp[i]; -+ if( PCAP_LOG_END_ADDRESS == pcap_log_now_address ) -+ pcap_log_now_address = PCAP_LOG_START_ADDRESS; -+ pcap_log_len++; -+ if(pcap_log_len >= PCAP_LOG_RECORD_LENGTH) -+ pcap_log_len = PCAP_LOG_RECORD_LENGTH; -+ } -+ -+ for(i = 0;i<len;i++) -+ { -+ *pcap_log_now_address ++ = pData[i]; -+ if( PCAP_LOG_END_ADDRESS == pcap_log_now_address ) -+ pcap_log_now_address = PCAP_LOG_START_ADDRESS; -+ pcap_log_len++; -+ if(pcap_log_len >= PCAP_LOG_RECORD_LENGTH) -+ pcap_log_len = PCAP_LOG_RECORD_LENGTH; -+ } -+ return; -+} -+ -+static void pcap_log_output_from_ffuart(void) -+{ -+ u32 i; -+ u32 ssp_ffuart_dll,ssp_ffuart_dlh; -+ u8 ssp_ffuart_cken = 1,ssp_ffuart_en = 1; -+ if(0 == pcap_log_len) -+ return; -+ -+ /* if cable in NOT UART cable, should return */ -+ printk("\n *********log out ************* \n <%d jiffies>log:",(int)jiffies); -+ local_irq_disable(); -+ if(!(CKEN&CKEN6_FFUART)) -+ { -+ ssp_ffuart_cken = 0; -+ CKEN |= CKEN6_FFUART; -+ pcap_log_add_data("FFUART CLK not ENABLE!",strlen("FFUART CLK not ENABLE!")); -+ } -+ -+ FFLCR = (FFLCR&0xff)|0x80; -+ ssp_ffuart_dll = FFDLL&0xff; -+ ssp_ffuart_dlh = FFDLH&0xff; -+ FFLCR = FFLCR&0x7f; -+ -+ if((0x08 !=ssp_ffuart_dll)||(0x00 != ssp_ffuart_dlh)) -+ { -+ FFLCR = 0x83; -+ FFDLL = 0x08; -+ FFDLH = 0; -+ FFLCR = 0x03; -+ } -+ -+ if(!(FFIER&0x00000040)) -+ { -+ ssp_ffuart_en = 0; -+ FFIER |= 0x00000040; -+ pcap_log_add_data("FFUART model not ENABLE!",strlen("FFUART model not ENABLE!")); -+ } -+ -+ for(i=0;i<pcap_log_len;i++) -+ { -+ while((FFLSR &0x40) == 0); -+ FFTHR = pcap_log_data[i]; -+ } -+ if(!ssp_ffuart_cken) -+ { -+ CKEN &= ~CKEN6_FFUART; -+ } -+ -+ -+ if((0x08 !=ssp_ffuart_dll)||(0x00 != ssp_ffuart_dlh)) -+ { -+ FFLCR = 0x83; -+ FFDLL = ssp_ffuart_dll; -+ FFDLH = ssp_ffuart_dlh; -+ FFLCR = 0x03; -+ } -+ -+ if(!ssp_ffuart_en) -+ { -+ CKEN &= ~CKEN6_FFUART; -+ } -+ local_irq_enable(); -+ -+ printk("\n ********* log end ************ \n"); -+} -+ -+static void pcap_log_output_from_stuart(void) -+{ -+ u32 i; -+ u32 ssp_stuart_dll,ssp_stuart_dlh; -+ u8 ssp_stuart_cken = 1,ssp_stuart_en = 1; -+ if(0 == pcap_log_len) -+ return; -+ -+ /* if cable in NOT UART cable, should return */ -+ printk("\n *********log out ************* \n <%d jiffies>log:",(int)jiffies); -+ local_irq_disable(); -+ if(!(CKEN&CKEN5_STUART)) -+ { -+ ssp_stuart_cken = 0; -+ CKEN |= CKEN5_STUART; -+ pcap_log_add_data("STUART CLK not ENABLE!",strlen("STUART CLK not ENABLE!")); -+ } -+ -+ STLCR = (STLCR&0xff)|0x80; -+ ssp_stuart_dll = STDLL&0xff; -+ ssp_stuart_dlh = STDLH&0xff; -+ STLCR &= 0x7f; -+ -+ if((0x08 !=ssp_stuart_dll)||(0x00 != ssp_stuart_dlh)) -+ { -+ STLCR = 0x83; -+ STDLL = 0x08; -+ STDLH = 0; -+ STLCR = 0x03; -+ } -+ -+ if(!(STIER&0x00000040)) -+ { -+ ssp_stuart_en = 0; -+ STIER |= 0x00000040; -+ pcap_log_add_data("STUART model not ENABLE!",strlen("STUART model not ENABLE!")); -+ }ACCESSORY_DEVICE_STATUS -+ -+ for(i=0;i<pcap_log_len;i++) -+ { -+ while((STLSR &0x40) == 0); -+ STTHR = pcap_log_data[i]; -+ } -+ if(!ssp_stuart_cken) -+ { -+ CKEN &= ~CKEN5_STUART; -+ } -+ -+ -+ if((0x08 !=ssp_stuart_dll)||(0x00 != ssp_stuart_dlh)) -+ { -+ STLCR = 0x83; -+ STDLL = ssp_stuart_dll; -+ STDLH = ssp_stuart_dlh; -+ STLCR = 0x03; -+ } -+ -+ if(!ssp_stuart_en) -+ { -+ CKEN &= ~CKEN5_STUART; -+ } -+ local_irq_enable(); -+ -+ printk("\n ********* log end ************ \n"); -+} -+ -+ -+static void pcap_output_log_handler( u32 data) -+{ -+ pcap_log_output_from_stuart(); -+ -+ pcap_outlog_timer.function = pcap_output_log_handler; -+ pcap_outlog_timer.expires = (jiffies + PCAP_LOG_OUTPUT_TIMER * HZ); -+ add_timer(&pcap_outlog_timer); -+} -+ -+static void pcap_output_log_init(void) -+{ -+ init_timer(&pcap_outlog_timer); -+ pcap_outlog_timer.function = pcap_output_log_handler; -+ pcap_outlog_timer.expires = (jiffies + 2*PCAP_LOG_OUTPUT_TIMER * HZ); -+ add_timer(&pcap_outlog_timer); -+} -+/* record log end */ -+#else -+void pcap_log_add_pure_data(u8* pData,u32 len) -+{ -+ return; -+} -+ -+void pcap_log_add_data(u8* pData,u32 len) -+{ -+ return; -+} -+#endif -+ -+void ssp_pcap_screenlock_lock(u32 data) -+{ -+ u32 flags; -+ save_flags(flags); -+ local_irq_disable(); -+ del_timer(&ssp_tsi_timer); -+ ssp_pcap_clear_int(); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ ssp_pcap_screenlock_status = 1 ; -+ restore_flags(flags); -+} -+ -+void ssp_pcap_screenlock_unlock(u32 data) -+{ -+ u32 flags; -+ save_flags(flags); -+ local_irq_disable(); -+ del_timer(&ssp_pcap_screenlock_timer); -+ ssp_pcap_clear_int(); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ ssp_pcap_screenlock_status = 0 ; -+ restore_flags(flags); -+} -+ -+static void ssp_pcap_screenlock_lockhandler(u32 data) -+{ -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("lockscreen timer arrived!",strlen("lockscreen timer arrived!")); -+#endif -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ return; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: GPIO init for operating PCAP via GPIO mode. -+ -+ INPUTS: none. -+ -+ -+ OUTPUTS: none. -+ -+ -+ IMPORTANT NOTES: auto-recognized pcap's CE signal. init PCAP's register. -+ -+ -+---------------------------------------------------------------------------*/ -+#ifndef SSP_PCAP_OPERATE_WITH_SPI -+ -+static u32 test_pcap_cs_rxd(void) -+{ -+ u32 ret = FALSE; -+ u32 temp; -+ /* write a data 0x0003ffff to IMR */ -+ SSP_PCAP_write_data_to_PCAP(1, 0x0003ffff); -+ SSP_PCAP_read_data_from_PCAP(1, &temp); -+ if( 0x0003ffff == temp) -+ ret = TRUE; -+ return ret; -+} -+ -+static void ssp_pcap_gpioInit(void) -+{ -+ u32 i; -+ u32 tempValue; -+ u32 ret; -+ /* stop SPI port work mode disable SPI clock */ -+ SSCR0 = 0x00000000; -+ CKEN &= ~CKEN23_SSP1; -+ -+ /* the four PIN as GPIO mode */ -+ pxa_gpio_mode(GPIO_SPI_CLK|GPIO_OUT); -+ pxa_gpio_mode(GPIO_SPI_CE|GPIO_OUT); -+ pxa_gpio_mode(GPIO_SPI_MOSI|GPIO_OUT); -+ pxa_gpio_mode(GPIO_SPI_MISO|GPIO_IN); -+ -+ /* test pcap's CE with inverter??? */ -+ ssp_pcap_operate_pin_with_inverter = 0; -+ ssp_pcap_rxd_pin_with_inverter = 0; -+ -+ /* deassert SEC_CE */ -+ GPCR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ for(i=0;i<500;i++); -+ ret = test_pcap_cs_rxd(); -+ -+ if (FALSE == ret) -+ { -+ ssp_pcap_operate_pin_with_inverter = 0; -+ ssp_pcap_rxd_pin_with_inverter = 1; -+ /* deassert SEC_CE */ -+ GPCR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ for(i=0;i<500;i++); -+ ret = test_pcap_cs_rxd(); -+ } -+ -+ if (FALSE == ret) -+ { -+ ssp_pcap_operate_pin_with_inverter = 1; -+ ssp_pcap_rxd_pin_with_inverter = 0; -+ /* deassert SEC_CE */ -+ GPSR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ for(i=0;i<500;i++); -+ ret = test_pcap_cs_rxd(); -+ } -+ -+ -+ if (FALSE == ret) -+ { -+ ssp_pcap_operate_pin_with_inverter = 1; -+ ssp_pcap_rxd_pin_with_inverter = 1; -+ /* deassert SEC_CE */ -+ GPSR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ for(i=0;i<500;i++); -+ ret = test_pcap_cs_rxd(); -+ } -+ -+ if (FALSE == ret ) -+ { -+ printk("\n Bulverde can not communicate with PCAP!!!!"); -+ return; -+ } -+ -+ SSP_PCAP_write_data_to_PCAP(1, 0x0013ffff); -+ -+ for(i=0; i<32 ;i++) -+ { -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_read_data_from_PCAP(i,&tempValue)) -+ { -+ ssp_pcap_registerValue[i] = tempValue; -+ } -+ else -+ { -+ ssp_pcap_registerValue[i] = 0; -+ } -+ } -+ return; -+} -+ -+ -+static void ssp_pcap_gpioClkControl(u32 bitValue) -+{ -+ if(bitValue) -+ { -+ GPSR(GPIO_SPI_CLK) = GPIO_bit(GPIO_SPI_CLK); -+ } -+ else -+ { -+ GPCR(GPIO_SPI_CLK) = GPIO_bit(GPIO_SPI_CLK); -+ } -+} -+ -+static void ssp_pcap_gpioFrmControl(u32 bitValue) -+{ -+ if( ssp_pcap_operate_pin_with_inverter ) -+ { -+ if(bitValue) -+ { -+ GPCR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ } -+ else -+ { -+ GPSR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ } -+ } -+ else -+ { -+ if(bitValue) -+ { -+ GPSR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ } -+ else -+ { -+ GPCR(GPIO_SPI_CE) = GPIO_bit(GPIO_SPI_CE); -+ } -+ } -+} -+ -+static void ssp_pcap_gpioTxdControl(u32 bitValue) -+{ -+ if(bitValue) -+ { -+ GPSR(GPIO_SPI_MOSI) = GPIO_bit(GPIO_SPI_MOSI); -+ } -+ else -+ { -+ GPCR(GPIO_SPI_MOSI) = GPIO_bit(GPIO_SPI_MOSI); -+ } -+} -+ -+static u32 ssp_pcap_gpioRxdGetStatus(void) -+{ -+ if(ssp_pcap_rxd_pin_with_inverter) -+ { -+ if( GPLR(GPIO_SPI_MISO)&GPIO_bit(GPIO_SPI_MISO) ) -+ { -+ return SSP_PCAP_BIT_ZERO; -+ } -+ else -+ { -+ return SSP_PCAP_BIT_ONE; -+ } -+ } -+ else -+ { -+ if( GPLR(GPIO_SPI_MISO)&GPIO_bit(GPIO_SPI_MISO) ) -+ { -+ return SSP_PCAP_BIT_ONE; -+ } -+ else -+ { -+ return SSP_PCAP_BIT_ZERO; -+ } -+ } -+} -+ -+static void ssp_pcap_gpioWrite(u32 pcapValue) -+{ -+ u32 tempValue; -+ u32 loopValue = 0x80000000; -+ int i; -+ /* prepare for starting the frame */ -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ ssp_pcap_gpioFrmControl(SSP_PCAP_BIT_ZERO); -+ ssp_pcap_gpioTxdControl(SSP_PCAP_BIT_ZERO); -+ -+ /* start the data transfering frame */ -+ ssp_pcap_gpioFrmControl(SSP_PCAP_BIT_ONE); -+ for(i=0;i<32;i++) -+ { -+ tempValue = pcapValue&loopValue; -+ /* setup data bit to TXD line */ -+ ssp_pcap_gpioTxdControl(tempValue); -+ /* create clock */ -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ONE); -+ loopValue = loopValue/2; -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ } -+ /* end the frame */ -+ ssp_pcap_gpioFrmControl(SSP_PCAP_BIT_ZERO); -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( " \n Write END \n " ); -+#endif -+ return; -+} -+ -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+ -+static void ssp_pcap_gpioRead( u32 registerNumber,u32* pPcapValue) -+{ -+ int i; -+ u32 tempValue; -+ u32 loopValue = 0x80000000; -+ -+ /* prepare for starting the frame */ -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ ssp_pcap_gpioFrmControl(SSP_PCAP_BIT_ZERO); -+ ssp_pcap_gpioTxdControl(SSP_PCAP_BIT_ZERO); -+ -+ /* start the data transfering frame */ -+ ssp_pcap_gpioFrmControl(SSP_PCAP_BIT_ONE); -+ /* indictaor it's a read data command */ -+ ssp_pcap_gpioTxdControl(SSP_PCAP_BIT_ZERO); -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ONE); -+ loopValue = loopValue/2; -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ -+ for(i=0; i<5;i++) -+ { -+ /* here maybe can be optimized */ -+ tempValue = registerNumber&(loopValue/0x04000000); -+ ssp_pcap_gpioTxdControl(tempValue); -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ONE); -+ loopValue = loopValue/2; -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ } -+ -+ /* the dead bit */ -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ONE); -+ loopValue = loopValue/2; -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ -+ tempValue = 0; -+ for(i=0;i<25;i++) -+ { -+ tempValue |= loopValue*ssp_pcap_gpioRxdGetStatus(); -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ONE); -+ loopValue = loopValue/2; -+ ssp_pcap_gpioClkControl(SSP_PCAP_BIT_ZERO); -+ } -+ /* end the data frame */ -+ ssp_pcap_gpioFrmControl(SSP_PCAP_BIT_ZERO); -+ if(pPcapValue) -+ { -+ *pPcapValue = tempValue; -+ } -+ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk(" \n Read Data end \n"); -+#endif -+ return ; -+} -+ -+#endif -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ -+void SSPTest(void) -+{ -+ char string[80]; -+ u32 i,j,k; -+ u16 x,y; -+ u32 tempValue; -+ // ssp_pcap_init(); -+// ssp_pcap_open(); -+ printk(" \n ****************************** \n SSP TEST \n *****************\n "); -+// SSP_vibrate_start_command(); -+// for(i=0; i<100000000; i++); -+// SSP_vibrate_stop_command(); -+ SSP_PCAP_write_data_to_PCAP(3,0x0fffffff); -+ -+ SSP_PCAP_read_data_from_PCAP(0,&k); -+ SSP_PCAP_write_data_to_PCAP(0,k); -+ -+ for(i =0;i<32;i++) -+ { -+ SSP_PCAP_read_data_from_PCAP(i,&k); -+ sprintf(string,"pcap register %d = 0x%x! \n",i,k); -+ printk(string); -+ } -+ -+ SSP_PCAP_read_data_from_PCAP(0,&k); -+ SSP_PCAP_write_data_to_PCAP(0,k); -+ -+ -+// SSP_PCAP_write_data_to_PCAP(9,0x000a0000); -+ printk( "\n ************* \n test TS position start \n "); -+ -+ for(i=0;i<10000;i++) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ if(tempValue) -+ { -+ -+ sprintf(string, "GEDR0 = %x ICPR = %x ICMR= %x \n ",GEDR0,ICPR,ICMR ); -+ printk(string); -+ GEDR0 = GEDR0; -+ ICPR = ICPR; -+ -+ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ -+ SSP_PCAP_TSI_mode_set(PCAP_TS_PRESSURE_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ tempValue = 0 ; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ } -+ SSP_PCAP_TSI_get_XY_value(&x,&y); -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ -+ sprintf(string,"\n TS xy pressure X=%d y=%d \n",x,y); -+ printk(string); -+ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ -+ SSP_PCAP_TSI_mode_set(PCAP_TS_PRESSURE_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ tempValue = 0 ; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ } -+ SSP_PCAP_TSI_get_XY_value(&x,&y); -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ -+ sprintf(string,"\n TS xy pressure X=%d y=%d \n",x,y); -+ printk(string); -+ -+ -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ tempValue = 0 ; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ } -+ SSP_PCAP_TSI_get_XY_value(&x,&y); -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ -+ sprintf(string,"\n TS xy possition X=%d y=%d \n",x,y); -+ printk(string); -+ -+ SSP_PCAP_TSI_mode_set(PCAP_TS_PRESSURE_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ tempValue = 0 ; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ } -+ SSP_PCAP_TSI_get_XY_value(&x,&y); -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ -+ sprintf(string,"\n TS xy pressure X=%d y=%d \n",x,y); -+ printk(string); -+ -+ i = 0; -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M); -+ // SSP_PCAP_write_data_to_PCAP(9,0x000a0000); -+ -+ } -+ for(j=0;j<60000;j++); -+ } -+ printk(" TS pressure test start \n "); -+ -+ SSP_PCAP_TSI_mode_set(PCAP_TS_PRESSURE_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ tempValue = 0 ; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_ADCDONEI); -+ } -+ SSP_PCAP_TSI_get_XY_value(&x,&y); -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONEI); -+ -+ sprintf(string,"\n TS xy pressure X=%d y=%d \n",x,y); -+ printk(string); -+ -+ SSP_PCAP_read_data_from_PCAP(0,&tempValue); -+ -+ sprintf(string," before clean ISR = %x \n ", tempValue ); -+ printk(string); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_read_data_from_PCAP(0,&tempValue); -+ sprintf(string," after clean ISR = %x \n ", tempValue ); -+ printk(string); -+ GEDR0 = GEDR0; -+ ICPR = ICPR; -+ -+ tempValue = 0; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_TSI); -+ tempValue &= 0x00000001; -+ } -+ SSP_PCAP_read_data_from_PCAP(0,&tempValue); -+ SSP_PCAP_read_data_from_PCAP(1,&k); -+ sprintf(string, " MSR = %8x ISR= %8x, GEDR0 = %8x ICPR = %8x \n",k,tempValue,GEDR0,ICPR); -+ printk(string); -+ GEDR0 = GEDR0; -+ ICPR = ICPR; -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ SSP_PCAP_TSI_mode_set(PCAP_TS_PRESSURE_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ tempValue = 0; -+ while(!tempValue) -+ { -+ tempValue = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ tempValue &= 0x00000001; -+ } -+ for(i=0;i<60000;i++); -+ SSP_PCAP_read_data_from_PCAP(0,&tempValue); -+ sprintf(string," ISR =%8x GEDR0 =%8x ICPR = %8x \n",tempValue,GEDR0,ICPR); -+ printk(string); -+ SSP_PCAP_TSI_get_XY_value(&x,&y); -+ sprintf(string," TS pressure x = %d y= %d \n" ,x,y ); -+ printk(string); -+ return; -+} -+#endif -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+static int pcap_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ ssp_pcap_intoSleepCallBack(); -+ break; -+ case PM_RESUME: -+ ssp_pcap_wakeUpCallBack(); -+ break; -+ } -+ return 0; -+} -+static int ssp_pcap_init_is_ok = 0; -+void ssp_pcap_init(void) -+{ -+#ifdef SSP_PCAP_DEBUG_BOARD -+ U32 tempValue; -+#endif -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ char debugStr[100]; -+ sprintf(debugStr,"\n ***************** \n SSP init start \n"); -+ printk(debugStr); -+#endif -+ -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+ CKEN |= CKEN3_SSP; -+ pxa_gpio_mode(GPIO_SPI_CLK|(GPIO_SPI_CLK == GPIO23_SCLK? GPIO_ALT_FN_2_OUT:GPIO_ALT_FN_3_OUT); -+ pxa_gpio_mode(GPIO_SPI_CE|GPIO_ALT_FN_2_OUT); -+ pxa_gpio_mode(GPIO_SPI_MOSI|GPIO_ALT_FN_2_OUT); -+ pxa_gpio_mode(GPIO_SPI_MISO|GPIO_ALT_FN_1_IN); -+ -+ SSCR1 = 0x00000401; -+ SSCR0 = 0x00000000; -+ SSCR0 = 0x0000008f; -+ init_waitqueue_head(&ssp_pcap_send_wait); -+ request_irq(IRQ_SSP,ssp_interrupt_routine,0,"SSP received the data irq ",NULL); -+#else -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk(" \n ********************* \n SSP GPIO mode init \n"); -+#endif -+ if(!ssp_pcap_init_is_ok) -+ { -+ ssp_pcap_gpioInit(); -+ ssp_pcap_init_is_ok = 1; -+ } -+#endif -+ -+#ifdef SSP_PCAP_DEBUG_BOARD -+ printk("\n ********************* \n SSP DEBUG BOARD init \n "); -+ tempValue = GPDR2; -+ tempValue = tempValue&0x0001ffff; -+ tempValue |= 0x00010000; -+ GPDR2 = tempValue; -+ GAFR2_U = 0x00000002; -+#endif -+ pxa_gpio_mode(GPIO_PCAP_SEC_INT | GPIO_IN); -+ set_GPIO_IRQ_edge(GPIO_PCAP_SEC_INT,GPIO_RISING_EDGE); -+ -+ request_irq(IRQ_GPIO1,ssp_pcap_interrupt_routine,0,"PCAP request irq ",NULL); -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_output_log_init(); -+#endif -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk(" \n *********************** \n SSP init END \n "); -+#endif -+ init_timer(&ssp_tsi_timer); -+ ssp_tsi_timer.function = ssp_tsi_keeper; -+ -+ init_timer(&ssp_usb_accessory_debounce_timer); -+ ssp_usb_accessory_debounce_timer.function = ssp_usb_accessory_debounce_handler; -+ -+ ssp_pcap_screenlock_status = 0 ; -+ init_timer(&ssp_pcap_screenlock_timer); -+ ssp_pcap_screenlock_timer.function = ssp_pcap_screenlock_lockhandler; -+ -+ /* since in GPIO init, we have gotten the register's value. */ -+// SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_MSR_USB4VM ); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_ISR_USB4VI); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_USB4VM); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_ISR_USB1VI); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_USB1VM); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_A1CTRL); -+ SSP_PCAP_V_VIB_level_set(PCAP_VIBRATOR_VOLTAGE_LEVEL3); -+ SSP_PCAP_V_VIB_level_set(PCAP_VIBRATOR_VOLTAGE_LEVEL3); -+ -+ /* set SW1 sleep to keep SW1 1.3v in sync mode */ -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE10 ); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE11 ); -+ /* SW1 active in sync mode */ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE00 ); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW1_MODE01); -+ /* at SW1 -core voltage to 1.30V */ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW10_DVS); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW11_DVS); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW12_DVS); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_SW13_DVS); -+ -+ /* when STANDY2 PIN ACTIVE (high) set V3-- sram V8 -- pll off */ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_VREG2_V3_STBY); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_VREG2_V3_LOWPWR); -+ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_VREG2_V8_STBY); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_VREG2_V8_LOWPWR); -+ -+ /* when STANDY2 PIN ACTIVE (high) set V4-- lcd only for e680 V6 --- camera for e680 */ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_VREG2_V4_STBY); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_VREG2_V4_LOWPWR); -+ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_VREG2_V6_STBY); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_VREG2_V6_LOWPWR); -+ -+ /* set Vc to low power mode when AP sleep */ -+ //SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VC_STBY); -+ -+ /* set VAUX2 to voltage 2.775V and low power mode when AP sleep */ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_1); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_0); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX2_STBY); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_LOWPWR_CTRL_VAUX2_LOWPWR); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_AUX_VREG_VAUX2_EN ); -+ -+ PGSR(GPIO34_TXENB) |= GPIO_bit(GPIO34_TXENB); -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V )) -+ { -+ accessory_bus_detect_handler(ACCESSORY_DEVICE_USB_PORT,ACCESSORY_DEVICE_STATUS_ATTACHED,NULL); -+ } -+ else -+ { -+ accessory_bus_detect_handler(ACCESSORY_DEVICE_USB_PORT,ACCESSORY_DEVICE_STATUS_DETACHED,NULL); -+ } -+ /* register pm callback function */ -+ /* only for temp solution 2004-05-10 */ -+#ifdef PCAP2_V1.4_AND_BEFORE -+ pxa_gpio_mode(GPIO_TC_MM_EN | GPIO_OUT ); -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ PGSR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ /* the PM callback will move to apm.c */ -+// pcap_pm_dev = pm_register(PM_SYS_DEV,0,pcap_pm_callback); -+ return; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void pcap_switch_off_usb(void) -+{ -+ if(!ssp_pcap_init_is_ok) -+ { -+ ssp_pcap_gpioInit(); -+ ssp_pcap_init_is_ok = 1; -+ } -+ /* only for PST tool recognize the USB cable */ -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V )) -+ { -+ SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ } -+ return; -+} -+ -+void pcap_switch_on_usb(void) -+{ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V )) -+ { -+// stop_ffuart(); -+// usb_gpio_init(); -+ } -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void ssp_pcap_release(void) -+{ -+/* the PM callback will move to apm.c */ -+// pm_unregister(pcap_pm_dev); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void ssp_pcap_open(SSP_PCAP_INIT_DRIVER_TYPE portType) -+{ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ u32 i; -+ u32 tempValue; -+#endif -+#ifdef SSP_PCAP_DEBUG_BOARD -+ /* select the primary SPI of PCAP */ -+ *SSP_SELECT_BUFFER = 0x00000094; -+ SSP_PCAP_write_data_to_PCAP(3, 0x00100002); -+ SSP_PCAP_write_data_to_PCAP(20,0x010000a4); -+ SSP_PCAP_bit_set(0x58080000 ); -+ SSP_PCAP_TSI_mode_set(PCAP_TS_STANDBY_MODE); -+ *SSP_SELECT_BUFFER = 0x00000070; -+#endif -+ switch(portType) -+ { -+ case SSP_PCAP_TS_OPEN: -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk(" \n SSP TS open!!! "); -+#endif -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_TS_REFENB ); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I); -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC2_ADINC1); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC2_ADINC2); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_ATO0); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_ATO1); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_ATO2); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_ATO3); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_ATOX); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_MTR1); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ADC1_MTR2); -+ SSP_PCAP_TSI_mode_set(PCAP_TS_STANDBY_MODE); -+ /* send the usb accessory infomation to PM */ -+ if((ACCESSORY_TYPE) sspUsbAccessoryInfo.type == ACCESSORY_DEVICE_USB_PORT) -+ { -+ if( (ACCESSORY_DEVICE_STATUS )sspUsbAccessoryInfo.status == ACCESSORY_DEVICE_STATUS_ATTACHED ) -+ apm_queue_event(KRNL_ACCS_ATTACH); -+ else -+ apm_queue_event(KRNL_ACCS_DETACH); -+ } -+ break; -+ case SSP_PCAP_AUDIO_OPEN: -+ break; -+ default: -+ break; -+ } -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ for(i=0;i<32;i++) -+ { -+ SSP_PCAP_read_data_from_PCAP(i, &tempValue); -+ printk("\n PCAP register %d = 0x%x!",i,tempValue); -+ } -+#endif -+ return; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void ssp_pcap_close(void) -+{ -+ SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_MSR_REGISTER,PCAP_MASK_ALL_INTERRUPT); -+ return; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void ssp_pcap_intoSleepCallBack(void) -+{ -+ /* set TS_REF to low power mode */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ADC1_TS_REF_LOWPWR); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_MSR_MB2M); -+ /* set SPI_CLK as input PIN */; -+ GPDR(GPIO_SPI_CLK) &= ~GPIO_bit(GPIO_SPI_CLK); -+ /* set SPI_MOSI as input PIN */ -+ GPDR(GPIO_SPI_MOSI) &= ~GPIO_bit(GPIO_SPI_MOSI); -+ /* set PCAP's CE pin to dessert signal SPI_CE must be in range of 0~31 PIN */ -+ if(ssp_pcap_operate_pin_with_inverter) -+ { -+ PGSR0 |= GPIO_bit(GPIO_SPI_CE); -+ } -+ else -+ { -+ PGSR0 &= ~GPIO_bit(GPIO_SPI_CE); -+ } -+} -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void ssp_pcap_wakeUpCallBack(void) -+{ -+#ifdef PCAP2_V1.4_AND_BEFORE -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ /* set SPI_CLK to output PIN */; -+ GPDR(GPIO_SPI_CLK) |= GPIO_bit(GPIO_SPI_CLK) ; -+ /* set SPI_MOSI to output PIN */ -+ GPDR(GPIO_SPI_MOSI) |= GPIO_bit(GPIO_SPI_MOSI); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_ADC1_TS_REF_LOWPWR); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_MSR_MB2M); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_configure_USB_UART_transeiver(SSP_PCAP_PORT_TYPE portType) -+{ -+ SSP_PCAP_STATUS ret = SSP_PCAP_SUCCESS; -+ switch(portType) -+ { -+ case SSP_PCAP_SERIAL_PORT: -+ /* according to HW requirement, do not clear VUSB_EN 2004-05-11 */ -+ //ret = SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ if(SSP_PCAP_SUCCESS == ret) -+ { -+ ret = SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ } -+ break; -+ case SSP_PCAP_LOW_USB_PORT: -+ ret = SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ if(SSP_PCAP_SUCCESS == ret) -+ { -+ ret = SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_FSENB); -+ } -+ if(SSP_PCAP_SUCCESS == ret) -+ { -+ ret = SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ } -+ break; -+ case SSP_PCAP_HIGH_USB_PORT: -+ ret = SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ if(SSP_PCAP_SUCCESS == ret) -+ { -+ ret = SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_FSENB); -+ } -+ if(SSP_PCAP_SUCCESS == ret) -+ { -+ ret = SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ } -+ break; -+ default: -+ ret = SSP_PCAP_NOT_RUN ; -+ break; -+ } -+ return ret; -+} -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+ -+SSP_PCAP_STATUS SSP_PCAP_TSI_mode_set(TOUCH_SCREEN_DETECT_TYPE mode_Type ) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_ADC1_REGISTER]&(~SSP_PCAP_TOUCH_PANEL_POSITION_DETECT_MODE_MASK); -+ tempValue = tempValue|mode_Type; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ADC1_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_TSI_start_XY_read(void) -+{ -+ SSP_PCAP_STATUS ret = SSP_PCAP_SUCCESS; -+ U32 tempValue; -+#ifdef PCAP2_V1.4_AND_BEFORE -+ /* invert the TC_MM_EN pin to alert BP */ -+ u32 i; -+ if(GPLR(GPIO_TC_MM_EN)&GPIO_bit(GPIO_TC_MM_EN)) -+ { -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ } -+ else -+ { -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ } -+ for(i=0;i<0x00002000;i++); -+ if(GPLR(GPIO_TC_MM_EN)&GPIO_bit(GPIO_TC_MM_EN)) -+ { -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ } -+ else -+ { -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ } -+#endif -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_ADC1_REGISTER]&SSP_PCAP_ADC_START_VALUE_SET_MASK; -+ tempValue |= SSP_PCAP_ADC_START_VALUE; -+ SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ADC1_REGISTER,tempValue); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ADC2_ASC); -+ return ret; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: y reads TSX1's ADC value in ADD2 register, x reads TSY1's ADC value in ADD1 register. -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_TSI_get_XY_value(P_U16 p_x,P_U16 p_y) -+{ -+ U32 tempValue; -+ SSP_PCAP_STATUS ret = SSP_PCAP_read_data_from_PCAP(SSP_PCAP_ADJ_ADC2_REGISTER,&tempValue); -+ if( SSP_PCAP_SUCCESS != ret) -+ return ret; -+ if(ssp_pcap_screenlock_status) -+ { -+ *p_x = 0; -+ *p_y = 0; -+ SSP_PCAP_TSI_mode_set(PCAP_TS_STANDBY_MODE); -+ mod_timer(&ssp_pcap_screenlock_timer,jiffies + SSP_PCAP_TS_KEEPER_TIMER); -+ return ret; -+ } -+ if(tempValue&0x00400000) -+ return SSP_PCAP_ERROR_VALUE; -+ if(p_x) -+ { -+ *p_x = (U16)(tempValue&SSP_PCAP_ADD1_VALUE_MASK); -+ } -+ if(p_y) -+ { -+ *p_y = (U16)((tempValue&SSP_PCAP_ADD2_VALUE_MASK)>>SSP_PCAP_ADD2_VALUE_SHIFT); -+ } -+ SSP_PCAP_TSI_mode_set(PCAP_TS_STANDBY_MODE); -+ return ret; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+ -+SSP_PCAP_STATUS SSP_PCAP_CDC_CLK_set(PHONE_CDC_CLOCK_TYPE clkType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_AUD_CODEC_REGISTER]&(~SSP_PCAP_PHONE_CDC_CLOCK_MASK); -+ tempValue = tempValue|clkType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_AUD_CODEC_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_V_VIB_level_set(VibratorVoltageLevel_TYPE VIBLevelType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_AUX_VREG_REGISTER]&(~SSP_PCAP_VIBRATOR_VOLTAGE_LEVEL_MASK); -+ tempValue = tempValue|VIBLevelType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_AUX_VREG_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_CDC_SR_set(ST_SAMPLE_RATE_TYPE srType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_ST_DAC_REGISTER]&(~SSP_PCAP_STEREO_SAMPLE_RATE_MASK); -+ tempValue = tempValue|srType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ST_DAC_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_BCLK_set(ST_BCLK_TIME_SLOT_TYPE bclkType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_ST_DAC_REGISTER]&(~SSP_PCAP_STEREO_BCLK_TIME_SLOT_MASK); -+ tempValue = tempValue|bclkType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ST_DAC_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_STCLK_set(ST_CLK_TYPE stClkType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_ST_DAC_REGISTER]&(~SSP_PCAP_STEREO_CLOCK_MASK); -+ tempValue = tempValue|stClkType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ST_DAC_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_DIG_AUD_FS_set(DIG_AUD_MODE_TYPE fsType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_ST_DAC_REGISTER]&(~SSP_PCAP_DIGITAL_AUDIO_MODE_MASK); -+ tempValue = tempValue|fsType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ST_DAC_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_AUDIG_set(U32 audioInGain) -+{ -+ U32 tempValue; -+ if (audioInGain > PCAP_AUDIO_IN_GAIN_MAX_VALUE) -+ return SSP_PCAP_ERROR_VALUE; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER]&(~SSP_PCAP_AUDIO_IN_GAIN_MASK); -+ -+ /* shoulb be better like this tempValue |= audioInGain <<SSP_PCAP_AUDIO_IN_GAIN_SHIFT; */ -+ tempValue = tempValue|audioInGain; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_MONO_set(MONO_TYPE monoType) -+{ -+ U32 tempValue; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER]&(~SSP_PCAP_MONO_PGA_MASK); -+ tempValue = tempValue|monoType; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER,tempValue); -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_AUDOG_set(U32 audioOutGain) -+{ -+ U32 tempValue; -+ if (audioOutGain > PCAP_AUDIO_OUT_GAIN_MAX_VALUE) -+ return SSP_PCAP_ERROR_VALUE; -+ tempValue = ssp_pcap_registerValue[SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER]&(~SSP_PCAP_AUDIO_OUT_GAIN_MASK); -+ tempValue |= audioOutGain <<SSP_PCAP_AUDIO_OUT_GAIN_SHIFT; -+ return SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER,tempValue); -+} -+ -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+/* ssp has received 2 bytes, the function will be invoked. */ -+static void ssp_interrupt_routine(int irq, void *dev_id, struct pt_regs *regs ) -+{ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk("\n SSP INTERRUPT WAS CALLED \n "); -+#endif -+ if(SSSR&SSP_SR_RNE) -+ { -+ ssp_pcap_readValue = (SSDR&SSP_PCAP_REGISTER_VALUE_DOWN_WORD_MASK)<<16; -+ if(SSSR&SSP_SR_RNE) -+ { -+ ssp_pcap_readValue += (SSDR&SSP_PCAP_REGISTER_VALUE_DOWN_WORD_MASK); -+ if(SSSR&SSP_SR_RNE) -+ { -+ while(SSSR&SSP_SR_RNE) -+ { -+ ssp_pcap_readValue = (SSDR&SSP_PCAP_REGISTER_VALUE_DOWN_WORD_MASK); -+ } -+ ssp_pcap_readValue = 0; -+ } -+ } -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk("\n SSP INTERRUPT send wakeup info \n "); -+#endif -+ wake_up(&ssp_pcap_send_wait); -+ } -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk("\n SSP INTERRUPT EXIT \n "); -+#endif -+ return; -+} -+ -+#endif -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+ -+static void ssp_tsi_keeper(u32 data) -+{ -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("TS timer arrived!",strlen("TS timer arrived!")); -+#endif -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_MSR_TSM)) -+ { -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_ISR_TSI); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ } -+ return; -+} -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+void ssp_pcap_clear_int(void) -+{ -+ U32 tempValue; -+ U32 tempClearInterrupt; -+ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n ************************ \n SSP interrupt by GPIO from sleep. "); -+#endif -+ /* should care the return value */ -+ SSP_PCAP_read_data_from_PCAP( SSP_PCAP_ADJ_ISR_REGISTER,&tempValue); -+ tempClearInterrupt = tempValue&(SSP_PCAP_ADJ_BIT_ISR_MB2I|SSP_PCAP_ADJ_BIT_ISR_STI|SSP_PCAP_ADJ_BIT_ISR_A1I|SSP_PCAP_ADJ_BIT_ISR_USB1VI|SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I|SSP_PCAP_ADJ_BIT_ISR_TSI|SSP_PCAP_ADJ_BIT_ISR_USB4VI); -+ -+ /* send the data to ISR register to clear the interrupt flag */ -+ SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ISR_REGISTER,tempClearInterrupt); -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I&tempValue) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n SSP ADC interrupt should be discarded." ); -+#endif -+ } -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_TSI&tempValue) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n SSP TSI should be discarded. "); -+#endif -+ } -+ -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_USB4VI&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_USB4VM)) -+ { -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V)) -+ { -+ /* maybe we can support low speed USB how to do??? */ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n SSP USB4VI need handle. "); -+#endif -+ accessory_bus_detect_handler(ACCESSORY_DEVICE_USB_PORT,ACCESSORY_DEVICE_STATUS_ATTACHED,NULL); -+ } -+ } -+ } -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_USB1VI&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_USB1VM)) -+ { -+ if(SSP_PCAP_BIT_ONE != SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_1V)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n SSP USB_VBUS less than 1V! need handle."); -+#endif -+ accessory_bus_detect_handler(ACCESSORY_DEVICE_USB_PORT,ACCESSORY_DEVICE_STATUS_DETACHED,NULL); -+ } -+ } -+ } -+ -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_A1I&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_A1M)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n A1_INT insert/remove case, need to handle. ISR =%x ",tempValue ); -+#endif -+ /* earpiece insert/remove need handler */ -+ if (headjack_change_interrupt_routine) -+ (*headjack_change_interrupt_routine)(0,NULL,NULL); -+ } -+ } -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_MB2I&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_MB2M)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n MIC insert/remove case, need to handle! ISR =%x ",tempValue ); -+#endif -+ //queue_apm_event(KRNL_KEYPAD,NULL); -+ /* mic insert/remove or answer/end call handler */ -+ if(mic_change_interrupt_routine) -+ (*mic_change_interrupt_routine)(0,NULL,NULL); -+ } -+ } -+ return; -+} -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+static u32 ssp_pcap_last_jiffies = 0; -+ -+static void ssp_pcap_ts_send_pMmessage(void) -+{ -+ u32 temp = jiffies - ssp_pcap_last_jiffies; -+ -+ if( temp >SSP_SEND_PM_ALART_INTERVAL) -+ { -+ ssp_pcap_last_jiffies = (u32) jiffies; -+ apm_queue_event(KRNL_TOUCHSCREEN); -+ } -+ return; -+} -+ -+static void ssp_pcap_interrupt_routine(int irq, void *dev_id, struct pt_regs *regs ) -+{ -+ u32 pcap_repeat_num; -+ U32 tempValue; -+ u32 tempClearInterrupt; -+#ifdef PCAP_LOG_FFUART_OUT -+ u8 temp[100]; -+ pcap_log_add_data("SSP interrupt by GPIO.",strlen("\n SSP interrupt by GPIO.")); -+#endif -+ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n ************************ \n SSP interrupt by GPIO. "); -+#endif -+ /* should care the return value */ -+ pcap_repeat_num = 0; -+intRepeat: -+ SSP_PCAP_read_data_from_PCAP( SSP_PCAP_ADJ_ISR_REGISTER,&tempValue); -+ tempClearInterrupt = tempValue&(SSP_PCAP_ADJ_BIT_ISR_MB2I|SSP_PCAP_ADJ_BIT_ISR_STI|SSP_PCAP_ADJ_BIT_ISR_A1I|SSP_PCAP_ADJ_BIT_ISR_USB1VI|SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I|SSP_PCAP_ADJ_BIT_ISR_TSI|SSP_PCAP_ADJ_BIT_ISR_USB4VI); -+ -+ /* send the data to ISR register to clear the interrupt flag */ -+ SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_ISR_REGISTER,tempClearInterrupt); -+ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk("\n w17202 TSI = 0x%x ",tempClearInterrupt); -+#endif -+ if(SSP_PCAP_ADJ_BIT_ISR_ADCDONE2I&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_ADCDONE2M)) -+ { -+ /* call read XY callback function */ -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("SSP ADC interrupt need handle.",strlen("SSP ADC interrupt need handle.")); -+#endif -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n ************************** \n SSP ADC interrupt need handle." ); -+#endif -+ ssp_pcap_ts_send_pMmessage(); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_ADC1_ADEN); -+ /* 2 seconds protect timer */ -+ /* better used it after linux 2.4.17 */ -+ mod_timer(&ssp_tsi_timer,jiffies + SSP_PCAP_TS_KEEPER_TIMER); -+ ezx_ts_dataReadok_interrupt(0,NULL,NULL); -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n ************************** \n SSP ADC interrupt should be discarded." ); -+#endif -+ } -+ } -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_TSI&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_TSM)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n ************************* \n SSP TSI need handle."); -+#endif -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("SSP TSI need handle.",strlen("SSP TSI need handle.")); -+#endif -+ ssp_pcap_ts_send_pMmessage(); -+ //if ( pxafb_ezx_getLCD_status() ) -+ if (1) -+ { -+ /* call touch panel callbcak function */ -+ SSP_PCAP_bit_set( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ /* 2 seconds protect timer */ -+ /* better used it after linux 2.4.17 */ -+ mod_timer(&ssp_tsi_timer,jiffies + SSP_PCAP_TS_KEEPER_TIMER);; -+ ezx_ts_touch_interrupt(0,NULL,NULL); -+ } -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP TSI should be discarded."); -+#endif -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("SSP TSI need not handle.",strlen("SSP TSI need not handle.")); -+#endif -+ } -+ } -+ -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_USB4VI&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_USB4VM)) -+ { -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_4V)) -+ { -+ /* maybe we can support low speed USB how to do??? */ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP USB4VI need handle."); -+#endif -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("SSP USB4VI need handle.",strlen("SSP USB4VI need handle.")); -+#endif -+ accessory_bus_detect_handler(ACCESSORY_DEVICE_USB_PORT,ACCESSORY_DEVICE_STATUS_ATTACHED,NULL); -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n ************************* \n SSP USB4VI low need NOT handle same as USB1VI low."); -+#endif -+ } -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP USB4VI should be discarded."); -+#endif -+ } -+ } -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_USB1VI&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_USB1VM)) -+ { -+ if(SSP_PCAP_BIT_ONE == SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_USBDET_1V)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP USB_VBUS greater than 1V!"); -+#endif -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP USB_VBUS less than 1V! need handle."); -+#endif -+ accessory_bus_detect_handler(ACCESSORY_DEVICE_USB_PORT,ACCESSORY_DEVICE_STATUS_DETACHED,NULL); -+ } -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP USB1VI should be discarded."); -+#endif -+ } -+ } -+ -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_A1I&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_A1M)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n A1_INT insert/remove case, need to handle. ISR =%x ",tempValue ); -+#endif -+#ifdef PCAP_LOG_FFUART_OUT -+ sprintf(temp,"A1_INT insert/remove case, need to handle. ISR =%x ",tempValue ); -+ pcap_log_add_data(temp,strlen(temp)); -+#endif -+ /* earpiece insert/remove need handler */ -+ if (headjack_change_interrupt_routine) -+ (*headjack_change_interrupt_routine)(0,NULL,NULL); -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n A1_INT should be discarded." ); -+#endif -+ } -+ } -+ -+ if(SSP_PCAP_ADJ_BIT_ISR_MB2I&tempValue) -+ { -+ if(SSP_PCAP_BIT_ZERO == SSP_PCAP_get_bit_from_buffer(SSP_PCAP_ADJ_BIT_MSR_MB2M)) -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n MIC insert/remove case, need to handle! ISR =%x ",tempValue ); -+#endif -+#ifdef PCAP_LOG_FFUART_OUT -+ sprintf(temp,"MIC insert/remove case, need to handle! ISR =%x ",tempValue ); -+ pcap_log_add_data(temp,strlen(temp)); -+#endif -+ //queue_apm_event(KRNL_KEYPAD,NULL); -+ /* mic insert/remove or answer/end call handler */ -+ if (mic_change_interrupt_routine) -+ (*mic_change_interrupt_routine)(0,NULL,NULL); -+ } -+ else -+ { -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk( "\n************************* \n SSP MB2I should be discarded."); -+#endif -+ } -+ } -+ if(GPLR0&0x00000002) -+ { -+ /* this case is a very critical case. */ -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("repeat pcap int!",strlen("repeat pcap int!")); -+#endif -+ if(pcap_repeat_num<10) -+ { -+ pcap_repeat_num++; -+ goto intRepeat; -+ } -+ else -+ { -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("repeat pcap exceed 10 times!",strlen("repeat pcap exceed 10 times!")); -+#endif -+ } -+ } -+ return; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+ -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+ -+void ssp_put_intoData(U32 pcapValue) -+{ -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ char string[100]; -+#endif -+ U32 tempFirstByte; -+ U32 tempSecondByte; -+ tempFirstByte = (pcapValue&SSP_PCAP_REGISTER_VALUE_UP_WORD_MASK)>>SSP_PCAP_REGISTER_VALUE_LENGTH; -+ tempSecondByte = (pcapValue&SSP_PCAP_REGISTER_VALUE_DOWN_WORD_MASK); -+ /* disable all interrupt or disable the SSP (zero to SSE) */ -+ local_irq_disable(); -+ SSDR = tempFirstByte ; -+ SSDR = tempSecondByte ; -+ local_irq_enable(); -+#ifdef SSP_PCAP_OPERATE_DEBUG_INFORNMATION -+ printk("\n ssp put dat \n"); -+ sprintf( string,"\n fisrt part =%8x second part =%8x \n",tempFirstByte,tempSecondByte); -+ printk(string); -+#endif -+ return; -+} -+ -+#endif -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_write_data_to_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER sspPcapRegister,U32 registerValue) -+{ -+ u32 pcapTempValue ; -+ unsigned long flags; -+ /* prevent the process schedule out and mask the PCAP's interrupt handler */ -+ //ICMR &= ~(1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+ save_flags(flags); -+ local_irq_disable(); -+ spin_lock(&pcapoperation_lock); -+ -+ if(!test_and_set_bit(0,&ssp_pcap_status)) -+ { -+ switch(sspPcapRegister) -+ { -+#ifdef SSP_PCAP_DEBUG_BOARD -+ case 3: -+ case 22: -+#endif -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+ ssp_pcap_registerValue[sspPcapRegister] = registerValue&SSP_PCAP_REGISTER_VALUE_MASK; -+ pcapTempValue = SSP_PCAP_REGISTER_WRITE_OP_BIT|(sspPcapRegister<<SSP_PCAP_REGISTER_ADDRESS_SHIFT )|(ssp_pcap_registerValue[sspPcapRegister]); -+ -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+ ssp_put_intoData(pcapTempValue); -+ interruptible_sleep_on(&ssp_pcap_send_wait); -+ /* here need to judge the wakeup reason and handle it */ -+#else -+ ssp_pcap_gpioWrite(pcapTempValue); -+#endif -+ clear_bit(0,&ssp_pcap_status); -+ -+ /* Now it's OK */ -+ spin_unlock(&pcapoperation_lock); -+ restore_flags(flags); -+ //ICMR |= (1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+/* -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("write pcap end!",strlen("write pcap end!")); -+#endif -+*/ -+ return SSP_PCAP_SUCCESS; -+ /* maybe here should NOT be a break */ -+ break; -+ default: -+ clear_bit(0,&ssp_pcap_status); -+ -+ /* Now it's OK */ -+ spin_unlock(&pcapoperation_lock); -+ restore_flags(flags); -+ //ICMR |= (1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+/* -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("write pcap error register!",strlen("write pcap error register!")); -+#endif -+*/ -+ return SSP_PCAP_ERROR_REGISTER; -+ /* maybe here should NOT be a break */ -+ break; -+ } -+ } -+ else -+ { -+ -+ /* Now it's OK */ -+ spin_unlock(&pcapoperation_lock); -+ restore_flags(flags); -+ //ICMR |= (1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+/* -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("write pcap not run!",strlen("write pcap not run!")); -+#endif -+*/ -+ return SSP_PCAP_NOT_RUN; -+ } -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_read_data_from_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER sspPcapRegister,P_U32 pSspPcapRegisterValue) -+{ -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+ U32 pcapTempValue; -+#endif -+ unsigned long flags; -+/* -+#ifdef PCAP_LOG_FFUART_OUT -+ pcap_log_add_data("read pcap start!",strlen("read pcap start!")); -+#endif -+*/ -+ /* prevent the process schedule out and mask the PCAP's interrupt handler */ -+ //ICMR &= ~(1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+ save_flags(flags); -+ local_irq_disable(); -+ spin_lock(&pcapoperation_lock); -+ -+ if(!test_and_set_bit(0,&ssp_pcap_status)) -+ { -+ switch(sspPcapRegister) -+ { -+#ifdef SSP_PCAP_DEBUG_BOARD -+ case 3: -+ case 22: -+#endif -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+#ifdef SSP_PCAP_OPERATE_WITH_SPI -+ pcapTempValue = SSP_PCAP_REGISTER_READ_OP_BIT|(sspPcapRegister<<SSP_PCAP_REGISTER_ADDRESS_SHIFT ); -+ ssp_put_intoData(pcapTempValue); -+ /* sleep with timeout */ -+ interruptible_sleep_on(&ssp_pcap_send_wait); -+ -+ /* here need to judge the wakeup reason and handle it */ -+// if (signal_pending(current)) { -+// ret = -ERESTARTSYS; -+// break; -+// } -+ *pSspPcapRegisterValue = ssp_pcap_readValue; -+#else -+ ssp_pcap_gpioRead(sspPcapRegister,pSspPcapRegisterValue); -+#endif -+ ssp_pcap_registerValue[sspPcapRegister] = *pSspPcapRegisterValue&SSP_PCAP_REGISTER_VALUE_MASK; -+ clear_bit(0,&ssp_pcap_status); -+ -+ /* Now it's OK */ -+ spin_unlock(&pcapoperation_lock); -+ restore_flags(flags); -+ //ICMR |= (1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+ return SSP_PCAP_SUCCESS; -+ /* maybe here should NOT be a break */ -+ break; -+ default: -+ clear_bit(0,&ssp_pcap_status); -+ -+ /* Now it's OK */ -+ spin_unlock(&pcapoperation_lock); -+ restore_flags(flags); -+ //ICMR |= (1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+ return SSP_PCAP_ERROR_REGISTER; -+ /* maybe here should NOT be a break */ -+ break; -+ } -+ } -+ else -+ { -+ /* Now it's OK */ -+ spin_unlock(&pcapoperation_lock); -+ restore_flags(flags); -+ //ICMR |= (1<<(GPIO1_RST+PXA_IRQ_SKIP)); -+ return SSP_PCAP_NOT_RUN; -+ } -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_bit_set(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE sspPcapBit ) -+{ -+ U32 sspPcapRegisterBitValue; -+ SSP_PCAP_STATUS ret; -+ U8 sspPcapRegister = (sspPcapBit&SSP_PCAP_REGISTER_ADDRESS_MASK)>>SSP_PCAP_REGISTER_ADDRESS_SHIFT; -+ -+ switch(sspPcapRegister) -+ { -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ ssp_pcap_registerValue[sspPcapRegister] = 0; -+#ifdef SSP_PCAP_DEBUG_BOARD -+ case 22: -+#endif -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+ -+ sspPcapRegisterBitValue = (sspPcapBit&SSP_PCAP_REGISTER_VALUE_MASK); -+ ssp_pcap_registerValue[sspPcapRegister] |= sspPcapRegisterBitValue; -+ /* should care the return value */ -+ ret =SSP_PCAP_write_data_to_PCAP(sspPcapRegister,ssp_pcap_registerValue[sspPcapRegister]); -+ return SSP_PCAP_SUCCESS; -+ break; -+ default: -+ return SSP_PCAP_ERROR_REGISTER; -+ break; -+ } -+ return SSP_PCAP_SUCCESS; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_STATUS SSP_PCAP_bit_clean(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE sspPcapBit ) -+{ -+ U32 sspPcapRegisterBitValue; -+ SSP_PCAP_STATUS ret; -+ U8 sspPcapRegister = (sspPcapBit&SSP_PCAP_REGISTER_ADDRESS_MASK)>>SSP_PCAP_REGISTER_ADDRESS_SHIFT; -+ -+ switch(sspPcapRegister) -+ { -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ ssp_pcap_registerValue[sspPcapRegister] = 0; -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+ sspPcapRegisterBitValue = (sspPcapBit&SSP_PCAP_REGISTER_VALUE_MASK); -+ ssp_pcap_registerValue[sspPcapRegister] &= ~sspPcapRegisterBitValue; -+ /* should care the return value */ -+ ret =SSP_PCAP_write_data_to_PCAP(sspPcapRegister,ssp_pcap_registerValue[sspPcapRegister]); -+ return SSP_PCAP_SUCCESS; -+ break; -+ default: -+ return SSP_PCAP_ERROR_REGISTER; -+ break; -+ } -+ return SSP_PCAP_SUCCESS; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_BIT_STATUS SSP_PCAP_get_bit_from_buffer(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE sspPcapBit ) -+{ -+ U32 sspPcapRegisterBitValue; -+ U8 sspPcapRegister = (sspPcapBit&SSP_PCAP_REGISTER_ADDRESS_MASK)>>SSP_PCAP_REGISTER_ADDRESS_SHIFT; -+ switch(sspPcapRegister) -+ { -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+ sspPcapRegisterBitValue = (sspPcapBit&SSP_PCAP_REGISTER_VALUE_MASK); -+ sspPcapRegisterBitValue &= ssp_pcap_registerValue[sspPcapRegister]; -+ if(sspPcapRegisterBitValue) -+ { -+ return SSP_PCAP_BIT_ONE; -+ } -+ else -+ { -+ return SSP_PCAP_BIT_ZERO; -+ } -+ break; -+ default: -+ return SSP_PCAP_BIT_ERROR; -+ break; -+ } -+ return SSP_PCAP_BIT_ERROR; -+} -+ -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+SSP_PCAP_BIT_STATUS SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER_BIT_TYPE sspPcapBit ) -+{ -+ U32 sspPcapTempRegisterValue; -+ U32 sspPcapRegisterBitValue; -+ SSP_PCAP_STATUS ret; -+ U8 sspPcapRegister = (sspPcapBit&SSP_PCAP_REGISTER_ADDRESS_MASK)>>SSP_PCAP_REGISTER_ADDRESS_SHIFT; -+ -+ switch(sspPcapRegister) -+ { -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+ sspPcapRegisterBitValue = (sspPcapBit&SSP_PCAP_REGISTER_VALUE_MASK); -+ /* should care the return value */ -+ ret = SSP_PCAP_read_data_from_PCAP(sspPcapRegister,&sspPcapTempRegisterValue); -+ sspPcapRegisterBitValue &= sspPcapTempRegisterValue; -+ if(sspPcapRegisterBitValue) -+ { -+ return SSP_PCAP_BIT_ONE; -+ } -+ else -+ { -+ return SSP_PCAP_BIT_ZERO; -+ } -+ break; -+ default: -+ return SSP_PCAP_BIT_ERROR; -+ break; -+ } -+ return SSP_PCAP_BIT_ERROR; -+} -+/*--------------------------------------------------------------------------- -+ DESCRIPTION: -+ -+ INPUTS: -+ -+ -+ OUTPUTS: -+ -+ -+ IMPORTANT NOTES: -+ -+ -+---------------------------------------------------------------------------*/ -+U32 SSP_PCAP_get_register_value_from_buffer(SSP_PCAP_SECONDARY_PROCESSOR_REGISTER sspPcapRegister ) -+{ -+ switch(sspPcapRegister) -+ { -+ case SSP_PCAP_ADJ_ISR_REGISTER: -+ case SSP_PCAP_ADJ_MSR_REGISTER: -+ case SSP_PCAP_ADJ_PSTAT_REGISTER: -+ case SSP_PCAP_ADJ_VREG2_REGISTER: -+ case SSP_PCAP_ADJ_AUX_VREG_REGISTER: -+ case SSP_PCAP_ADJ_BATT_DAC_REGISTER: -+ case SSP_PCAP_ADJ_ADC1_REGISTER: -+ case SSP_PCAP_ADJ_ADC2_REGISTER: -+ case SSP_PCAP_ADJ_AUD_CODEC_REGISTER: -+ case SSP_PCAP_ADJ_AUD_RX_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_ST_DAC_REGISTER: -+ case SSP_PCAP_ADJ_BUSCTRL_REGISTER: -+ case SSP_PCAP_ADJ_PERIPH_REGISTER: -+ case SSP_PCAP_ADJ_LOWPWR_CTRL_REGISTER: -+ case SSP_PCAP_ADJ_TX_AUD_AMPS_REGISTER: -+ case SSP_PCAP_ADJ_GP_REG_REGISTER: -+ return ssp_pcap_registerValue[sspPcapRegister]; -+ break; -+ default: -+ return SSP_PCAP_ERROR_REGISTER; -+ break; -+ } -+} -+#ifdef __cplusplus -+} -+#endif -Index: linux-2.6.16.5-a/drivers/char/Kconfig -=================================================================== ---- linux-2.6.16.5-a.orig/drivers/char/Kconfig 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/drivers/char/Kconfig 2006-05-04 17:07:04.000000000 +0200 -@@ -1007,6 +1007,16 @@ - The mmtimer device allows direct userspace access to the - Altix system timer. - -+config LINUX_LED -+ tristate "LED support" -+ -+config PXA_E680_LED -+ tristate "E680 LED suppory" -+ depends on LINUX_LED -+ -+config BULVERDE_SRAM_DEV -+ tristate "BULVERDE Internal SRAM char device" -+ - source "drivers/char/tpm/Kconfig" - - config TELCLOCK -Index: linux-2.6.16.5-a/drivers/char/Makefile -=================================================================== ---- linux-2.6.16.5-a.orig/drivers/char/Makefile 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/drivers/char/Makefile 2006-05-04 17:07:04.000000000 +0200 -@@ -95,6 +95,14 @@ - - obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o - obj-$(CONFIG_TCG_TPM) += tpm/ -+ -+obj-$(CONFIG_LINUX_LED) += led.o -+obj-$(CONFIG_PXA_E680_LED) += led_pxa_e680.o -+ -+obj-$(CONFIG_MAINSTONE_KEYPAD) += mstone_keypad.o -+obj-$(CONFIG_BULVERDE_SRAM_DEV) += sram.o -+ -+ - # Files generated that shall be removed upon make clean - clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c - -Index: linux-2.6.16.5-a/drivers/char/gpio_test.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/char/gpio_test.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,216 @@ -+/* -+ * linux/drivers/char/gpio_test.c -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Jay Jia -+ * Created: April 25, 2004 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/delay.h> -+#include <linux/init.h> -+#include <linux/kdev_t.h> -+#include <linux/fs.h> -+#include <linux/wrapper.h> -+#include <asm/hardware.h> -+#include <asm/irq.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <asm/arch/ezx.h> -+#include "../misc/ssp_pcap.h" -+ -+ -+#define SUCCESS 0 -+#define DEVICE_NAME "gpio_test" -+#define GPIO_TEST_IOCTL_CMD_OPS_MASK 0x000F -+#define GPIO_TEST_IOCTL_CMD_VAL_MASK 0x0080 -+#define GPIO_TEST_IOCTL_CMD_NUM_MASK 0xFF00 -+#define GPIO_TEST_IOCTL_CMD_VAL_SHIFT 7 -+#define GPIO_TEST_IOCTL_CMD_NUM_SHIFT 8 -+ -+static int Major=127; -+static unsigned char pcap_usb_ps = 0; -+static unsigned char pcap_vusb_en = 0; -+static unsigned char pcap_ov_test_on = 0; -+ -+static int gpio_test_open(struct inode *inode,struct file *file) -+{ -+ MOD_INC_USE_COUNT; -+ return SUCCESS; -+} -+ -+static int gpio_test_release(struct inode *inode,struct file *file) -+ -+{ -+ MOD_DEC_USE_COUNT; -+ return SUCCESS; -+} -+ -+ -+/******************************************************************************* -+Function Name: gpio_test_ioctl -+ -+Parameter: -+ The ioctl() accept a 2-byte command : cmd -+ Use this param as follows: -+ -+ bit 0 - 3: operation type. -+ 0x01, gpio read -+ 0x02, gpio write -+ 0x03, gpio config -+ 0x04, PCAP test -+ bit 4 -6: -+ reserved. keep ZERO -+ bit 7: -+ For gpio, write/config value. -+ For Over voltage test, -+ 0, ON -+ 1, OFF -+ bit 8 - 15: -+ For gpio, it is gpio pin number -+ For PCAP test, -+ 0x01, Over voltage test. -+ others, reserved. -+ -+Return Value: -+ For Over voltage test, -+ return 0 for success. -+ return 1 for error. -+*******************************************************************************/ -+static int gpio_test_ioctl(struct inode *inode,struct file *file,unsigned short cmd,unsigned long arg) -+{ -+ int num, val, ops, ret; -+ -+ ret = 0; -+ num = (cmd & GPIO_TEST_IOCTL_CMD_NUM_MASK) >> GPIO_TEST_IOCTL_CMD_NUM_SHIFT; -+ val = cmd & GPIO_TEST_IOCTL_CMD_VAL_MASK; -+ ops = cmd & GPIO_TEST_IOCTL_CMD_OPS_MASK; -+ -+ if(ops == 1)/*read gpio*/ -+ { -+// set_GPIO_mode(num); -+// GPDR(num) &= ~GPIO_bit(num); -+ ret = GPLR(num) & GPIO_bit(num); -+// printk("in GPIO kernel read function, num = %d and ret = %d\n",num,ret); -+ return (ret == 0) ? 0:1; -+ } -+ -+ if(ops == 2)/*write gpio*/ -+ { -+// set_GPIO_mode(num); -+// GPDR(num) |= GPIO_bit(num); -+ if( val ) -+ GPSR(num) = GPIO_bit(num); -+ else -+ GPCR(num) = GPIO_bit(num); -+ return 2; -+ } -+ -+ if(ops == 3)/*set gpio*/ -+ { -+ set_GPIO_mode(num); -+ if( val ) -+ GPDR(num) |= GPIO_bit(num); -+ else -+ GPDR(num) &= ~GPIO_bit(num); -+ return 3; -+ } -+ -+ if(ops == 4)/* PCAP test */ -+ { -+ printk("PCAP test, cmd = 0x%x.\n", cmd); -+ val = val >> GPIO_TEST_IOCTL_CMD_VAL_SHIFT; -+ switch(num) -+ { -+ case 1: /* Over Voltage test */ -+ if(val == 0) /* ON */ -+ { -+ printk("Over Voltage test ON.\n"); -+ /* backup USB_PS and VUSB_EN */ -+ pcap_ov_test_on = 1; -+ pcap_usb_ps = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PS); -+ pcap_vusb_en = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ /* USB_PS = 0, PCAP USB powered by VUSB_IN */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PS); -+ /* VUSB_EN = 1, USB tranceiver enabled */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ /* USB 1V INT mask */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_MSR_USB1VM); -+ /* USB 4V INT mask */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_MSR_USB4VM); -+ ret = 0; -+ } -+ else if(val == 1) /* OFF */ -+ { -+ printk("Over Voltage test OFF.\n"); -+ if(pcap_ov_test_on != 1) -+ { -+ ret = 1; /* return error */ -+ break; -+ } -+ /* restore USB_PS and VUSB_EN */ -+ if(pcap_usb_ps) -+ { -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PS); -+ } -+ else -+ { -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PS); -+ } -+ if(pcap_vusb_en) -+ { -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ } -+ else -+ { -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ } -+ pcap_ov_test_on = 0; -+ /* USB 1V INT unmask */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_USB1VI); /* clear 1V INT status */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_MSR_USB1VM); -+ /* USB 4V INT unmask */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_USB4VI); /* clear 4V INT status */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_MSR_USB4VM); -+ ret = 0; -+ } -+ else /* Unrecongized command */ -+ { -+ ret = 1; -+ } -+ break; -+ default: -+ ret = 1; -+ } -+ return ret; -+ } /* end of PCAP test */ -+} -+ -+static struct file_operations gpio_test_fops={ -+ ioctl: gpio_test_ioctl, -+ open: gpio_test_open, -+ release:gpio_test_release, -+}; -+ -+int gpio_test_init_module() -+{ -+ register_chrdev(Major, DEVICE_NAME, &gpio_test_fops); -+ return 0; -+} -+ -+void gpio_test_cleanup_module() -+{ -+ unregister_chrdev(Major,DEVICE_NAME); -+} -+ -+module_init(gpio_test_init_module); -+module_exit(gpio_test_cleanup_module); -+MODULE_AUTHOR("Jay Jia"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.16.5-a/drivers/char/led.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/char/led.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,318 @@ -+/* -+ * Device driver for controlling LEDs. See linux/led.h for info on -+ * how to use this. -+ * -+ * This currently only supports mono and bicolor LEDs, but support for -+ * fancier LEDs (scrolling text or numeric LEDs, for instance) could -+ * easily be added. -+ * -+ * Corey Minyard <minyard@mvista.com> -+ */ -+ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/types.h> -+#include <linux/errno.h> -+#include <linux/miscdevice.h> -+#include <asm/io.h> -+#include <asm/uaccess.h> -+#include <asm/system.h> -+#include <linux/init.h> -+#include <linux/led.h> -+#include <linux/string.h> -+#include <linux/spinlock.h> -+ -+#define VERSION "1.0" -+ -+/* A lock that is held when manipulating LED info. */ -+static spinlock_t led_lock = SPIN_LOCK_UNLOCKED; -+ -+/* A linked list of all the LEDs registered. */ -+static struct led_reg_info *leds; -+ -+/* Register a new LED with the driver. */ -+int register_led_info(struct led_reg_info *info) -+{ -+ struct led_reg_info *led; -+ int rv = 0; -+ -+ spin_lock(&led_lock); -+ info->next = NULL; -+ led = leds; -+ if (led == NULL) -+ { -+ leds = info; -+ } -+ else -+ { -+ while (led->next != NULL) -+ { -+ if (strcmp(led->info->name, info->info->name) == 0) -+ { -+ /* Registering a duplicate. */ -+ rv = -1; -+ goto out; -+ } -+ led = led->next; -+ } -+ led->next = info; -+ } -+ MOD_INC_USE_COUNT; -+ -+out: -+ spin_unlock(&led_lock); -+ -+ return rv; -+} -+ -+/* Unregister an LED from the driver. */ -+int unregister_led_info(struct led_reg_info *info) -+{ -+ int rv = -1; -+ struct led_reg_info *led; -+ -+ if (info == NULL) -+ { -+ return -1; -+ } -+ -+ spin_lock(&led_lock); -+ led = leds; -+ if (led == info) -+ { -+ MOD_DEC_USE_COUNT; -+ leds = leds->next; -+ } -+ else -+ { -+ while (led->next != NULL) -+ { -+ if (led->next == info) -+ { -+ MOD_DEC_USE_COUNT; -+ led->next = info->next; -+ rv = 0; -+ goto out; -+ } -+ led = led->next; -+ } -+ } -+out: -+ spin_unlock(&led_lock); -+ return rv; -+} -+ -+/* Return the number of LEDs registered. */ -+static int count_leds(void) -+{ -+ struct led_reg_info *led; -+ int count = 0; -+ -+ spin_lock(&led_lock); -+ led = leds; -+ while (led != NULL) -+ { -+ count = count + 1; -+ led = led->next; -+ } -+ spin_unlock(&led_lock); -+ -+ return count; -+} -+ -+/* Find an LED by its number. Must be called with the led spin lock -+ held. */ -+static struct led_reg_info *get_led_by_num(int num) -+{ -+ struct led_reg_info *led; -+ int count = num; -+ -+ led = leds; -+ while (led != NULL) -+ { -+ if (count == 0) -+ { -+ led->info->led_num = num; -+ return led; -+ } -+ count = count - 1; -+ led = led->next; -+ } -+ -+ return NULL; -+} -+ -+/* Find an LED by its name. Must be called with the led spin lock -+ held. */ -+static struct led_reg_info *get_led_by_name(char *name) -+{ -+ struct led_reg_info *led; -+ int count = 0; -+ -+ led = leds; -+ while (led != NULL) -+ { -+ if (strcmp(name, led->info->name) == 0) -+ { -+ led->info->led_num = count; -+ return led; -+ } -+ count++; -+ led = led->next; -+ } -+ -+ return NULL; -+} -+ -+/* The IOCTL handler for the LED driver. */ -+static int led_ioctl(struct inode *inode, -+ struct file *file, -+ unsigned int cmd, -+ unsigned long arg) -+{ -+ int i; -+ struct led_reg_info *led; -+ struct led_info info; -+ struct led_op op; -+ -+ switch(cmd) -+ { -+ case LEDIOC_GETCOUNT: -+ return count_leds(); -+ -+ case LEDIOC_GETINFO_BY_NUM: -+ case LEDIOC_GETINFO_BY_NAME: -+ i = copy_from_user(&info, (void*)arg, sizeof(info)); -+ if (i) -+ { -+ return -EFAULT; -+ } -+ -+ spin_lock(&led_lock); -+ if (cmd == LEDIOC_GETINFO_BY_NUM) -+ led = get_led_by_num(info.led_num); -+ else -+ led = get_led_by_name(info.name); -+ if (led == NULL) -+ { -+ spin_unlock(&led_lock); -+ return -EINVAL; -+ } -+ -+ info.type = led->info->type; -+ info.led_num = led->info->led_num; -+ strcpy(info.name, led->info->name); -+ info.info = led->info->info; -+ i = copy_to_user((void *)arg, &info, sizeof(info)); -+ -+ spin_unlock(&led_lock); -+ -+ if (i) -+ { -+ return -EFAULT; -+ } -+ return 0; -+ -+ case LEDIOC_OP: -+ i = copy_from_user(&op, (void*)arg, sizeof(op)); -+ if (i) -+ { -+ return -EFAULT; -+ } -+ -+ spin_lock(&led_lock); -+ led = get_led_by_name(op.name); -+ if (led == NULL) -+ { -+ spin_unlock(&led_lock); -+ return -EINVAL; -+ } -+ -+ i = led->handle_led_op(led, &op); -+ if (!i) -+ { -+ i = copy_to_user((void *)arg, &op, sizeof(op)); -+ if (i) -+ { -+ i = -EFAULT; -+ } -+ } -+ spin_unlock(&led_lock); -+ -+ return i; -+ -+ default: -+ return -ENOIOCTLCMD; -+ } -+} -+ -+/* Not much to do for opening. */ -+static int led_open(struct inode *inode, struct file *file) -+{ -+ switch(MINOR(inode->i_rdev)) -+ { -+ case LED_MINOR: -+ return 0; -+ -+ default: -+ return -ENODEV; -+ } -+} -+ -+/* Closing is really easy. */ -+static int led_close(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+ -+static struct file_operations led_fops = { -+ owner: THIS_MODULE, -+ llseek: NULL, -+ read: NULL, -+ write: NULL, -+ ioctl: led_ioctl, -+ open: led_open, -+ release: led_close, -+}; -+ -+static struct miscdevice led_miscdev= -+{ -+ LED_MINOR, -+ "led", -+ &led_fops -+}; -+ -+ -+/* Remove the LED driver. */ -+static void __exit led_exit(void) -+{ -+ misc_deregister(&led_miscdev); -+} -+ -+/* Set up the LED device driver. */ -+static int __init led_init(void) -+{ -+ int ret; -+ -+ printk("generic LED driver: v%s Corey Minyard (minyard@mvista.com)\n", -+ VERSION); -+ -+ leds = NULL; -+ ret = misc_register(&led_miscdev); -+ if (ret) { -+ printk(KERN_ERR "led: can't misc_register on minor=%d\n", -+ LED_MINOR); -+ return -1; -+ } -+ return 0; -+} -+ -+module_init(led_init); -+module_exit(led_exit); -+ -+EXPORT_SYMBOL(register_led_info); -+EXPORT_SYMBOL(unregister_led_info); -+ -+MODULE_LICENSE("GPL"); -Index: linux-2.6.16.5-a/drivers/char/led_pxa_e680.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/char/led_pxa_e680.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,596 @@ -+/*-------------------------------------------------------------------------------------------- -+// Module Name: led_pxa_e680.c -+// -+// General Description: This is the driver for E680 LED. -+//--------------------------------------------------------------------------------------------- -+// Motorola Confidential Proprietary -+// (c) Copyright Motorola 2003-2004, All Rights Reserved -+// -+// -+// Revision History: -+// Modification Tracking -+// Author (core ID) Date Number Description of Changes -+// ------------------------- ------------ ---------- ---------------------------- -+// Liu weijie (A19553) 11/01/2003 LIBdd43835 Init create -+// Wang Jamshid(a5036c) 04/29/2004 LIBee01180 fix bug,register pm call back -+*/ -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/version.h> -+#include <linux/string.h> -+#include <linux/kernel.h> -+#include <asm/io.h> -+#include <asm/errno.h> -+#include <linux/init.h> -+#include <linux/led_pxa_e680.h> -+#include <linux/pm.h> -+#include "../misc/ssp_pcap.h" -+ -+#ifdef CONFIG_E680_P4A -+#define IND_CNTL_R_BUL 79 -+#define IND_CNTL_G_BUL 18 -+#else -+#define IND_CNTL_R_BUL 46 -+#define IND_CNTL_G_BUL 47 -+#endif -+ -+#define SSP_PCAP_LED_MASK 0x000fffe0 -+#define SSP_PCAP_LED_SHIFT 5 -+ -+#define VERSION "1.0" -+ -+//#define DEBUG_LED_DRIVER -+ -+#ifdef DEBUG_LED_DRIVER -+#define PRINTK(s...) printk(s) -+#else -+#define PRINTK(s...) -+#endif -+typedef struct -+{ -+ unsigned char ind_GPIO_red; /*Indicator Red control GPIO 79: 0 active, 1 disactive*/ -+ unsigned char ind_GPIO_green; /*Indicator Green control GPIO 18: 0 active, 1 disactive*/ -+ unsigned char pcap_LEDR_en; /*pcap LEDR_EN bit value: 1 =Red LED(&Green) -+ sink circuit enabled*/ -+ unsigned char pcap_LEDG_en; /*pcap LEDG_EN bit value:1 =Green(->Blue)LED -+ sink circuit enabled*/ -+ unsigned char pcap_LEDR_CTRL; /* 4bits Sets the timing for the red(&Green) LED -+ sink circuit*/ -+ unsigned char pcap_LEDG_CTRL; /* 4bits Sets the timing for the GREEN (->Blue) LED -+ sink circuit*/ -+ unsigned char pcap_LEDR_I; /* 2 bits 00 3mA,01 4mA, 10 5mA, 11 9mA */ -+ /* sets the pulsed current level for LEDR*/ -+ unsigned char pcap_LEDG_I; -+ unsigned char pcap_SKIP_on; /*1=The ON timing sequence defined by LEDx_CTRL -+ is executed on every other cycle*/ -+}PCAP2_LED_REGISTER_VALUE; -+ -+const PCAP2_LED_REGISTER_VALUE led_register_value [LED_BOTTOM_STATE +1 ]= -+{ -+ {0x1,0x1, 0x0,0x0, 0x0,0x0, 0x0,0x0,0x0}, /*LED_OFF*/ -+ -+ /*Always On*/ -+ {0x0,0x1, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /*LED_RED_ALWAYS_ON,skip off*/ -+ {0x1,0x0, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /*LED_GREEN_ALWAYS_ON*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0xc, 0x0,0x0,0x0}, /*LED_BLUE_ALWAYS_ON*/ -+ {0x0,0x1, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /*LED_LIGHT_RED_ALWAYS_ON*/ -+ {0x0,0x0, 0x1,0x0, 0xc,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_ALWAYS_ON*/ -+ {0x1,0x0, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /*LED_LIGHT_BLUE_ALWAYS_ON*/ -+ {0x0,0x0, 0x1,0x1, 0xc,0xc, 0x1,0x0,0x0}, /*LED_WHITE_ALWAYS_ON*/ -+ -+ /* RED 5 mA current Skip OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x1,0x0, 0x1,0x0,0x0}, /*LED_RED_01_ON_19_OFF,skip off*/ -+ {0x0,0x1, 0x1,0x0, 0x2,0x0, 0x1,0x0,0x0}, /*LED_RED_02_ON_18_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x3,0x0, 0x1,0x0,0x0}, /*LED_RED_05_ON_15_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x4,0x0, 0x1,0x0,0x0}, /*LED_RED_025_ON_075_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x5,0x0, 0x1,0x0,0x0}, /*LED_RED_025_ON_175_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x6,0x0, 0x1,0x0,0x0}, /*LED_RED_005_ON_195_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x7,0x0, 0x1,0x0,0x0}, /*LED_RED_05_ON_05_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x8,0x0, 0x1,0x0,0x0}, /*LED_RED_05_OFF_05_ON*/ -+ {0x0,0x1, 0x1,0x0, 0x9,0x0, 0x1,0x0,0x0}, /*LED_RED_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0xa,0x0, 0x1,0x0,0x0}, /*LED_RED_0125_ON_2075_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0xb,0x0, 0x1,0x0,0x0}, /*LED_RED_0625_OFF_0075_ON_15_OFF*/ -+ -+ /* RED Skip ON*/ -+ {0x0,0x1, 0x1,0x0, 0x1,0x0, 0x1,0x0,0x1}, /*LED_RED_01_ON_19_OFF,skip On*/ -+ {0x0,0x1, 0x1,0x0, 0x2,0x0, 0x1,0x0,0x1}, /*LED_RED_02_ON_18_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x3,0x0, 0x1,0x0,0x1}, /*LED_RED_05_ON_15_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x4,0x0, 0x1,0x0,0x1}, /*LED_RED_025_ON_075_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x5,0x0, 0x1,0x0,0x1}, /*LED_RED_025_ON_175_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x6,0x0, 0x1,0x0,0x1}, /*LED_RED_005_ON_195_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x7,0x0, 0x1,0x0,0x1}, /*LED_RED_05_ON_05_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0x8,0x0, 0x1,0x0,0x1}, /*LED_RED_05_OFF_05_ON*/ -+ {0x0,0x1, 0x1,0x0, 0x9,0x0, 0x1,0x0,0x1}, /*LED_RED_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0xa,0x0, 0x1,0x0,0x1}, /*LED_RED_0125_ON_2075_OFF*/ -+ {0x0,0x1, 0x1,0x0, 0xb,0x0, 0x1,0x0,0x1}, /*LED_RED_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*GREEN Skip OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x1,0x0, 0x1,0x0,0x0}, /*LED_GREEN_01_ON_19_OFF,skip off*/ -+ {0x1,0x0, 0x1,0x0, 0x2,0x0, 0x1,0x0,0x0}, /*LED_GREEN_02_ON_18_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x3,0x0, 0x1,0x0,0x0}, /*LED_GREEN_05_ON_15_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x4,0x0, 0x1,0x0,0x0}, /*LED_GREEN_025_ON_075_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x5,0x0, 0x1,0x0,0x0}, /*LED_GREEN_025_ON_175_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x6,0x0, 0x1,0x0,0x0}, /*LED_GREEN_005_ON_195_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x7,0x0, 0x1,0x0,0x0}, /*LED_GREEN_05_ON_05_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x8,0x0, 0x1,0x0,0x0}, /*LED_GREEN_05_OFF_05_ON*/ -+ {0x1,0x0, 0x1,0x0, 0x9,0x0, 0x1,0x0,0x0}, /*LED_GREEN_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0xa,0x0, 0x1,0x0,0x0}, /*LED_GREEN_0125_ON_2075_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0xb,0x0, 0x1,0x0,0x0}, /*LED_GREEN_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*GREEN Skip ON*/ -+ {0x1,0x0, 0x1,0x0, 0x1,0x0, 0x1,0x0,0x1}, /*LED_GREEN_01_ON_19_OFF,skip On*/ -+ {0x1,0x0, 0x1,0x0, 0x2,0x0, 0x1,0x0,0x1}, /*LED_GREEN_02_ON_18_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x3,0x0, 0x1,0x0,0x1}, /*LED_GREEN_05_ON_15_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x4,0x0, 0x1,0x0,0x1}, /*LED_GREEN_025_ON_075_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x5,0x0, 0x1,0x0,0x1}, /*LED_GREEN_025_ON_175_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x6,0x0, 0x1,0x0,0x1}, /*LED_GREEN_005_ON_195_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x7,0x0, 0x1,0x0,0x1}, /*LED_GREEN_05_ON_05_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0x8,0x0, 0x1,0x0,0x1}, /*LED_GREEN_05_OFF_05_ON*/ -+ {0x1,0x0, 0x1,0x0, 0x9,0x0, 0x1,0x0,0x1}, /*LED_GREEN_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0xa,0x0, 0x1,0x0,0x1}, /*LED_GREEN_0125_ON_2075_OFF*/ -+ {0x1,0x0, 0x1,0x0, 0xb,0x0, 0x1,0x0,0x1}, /*LED_GREEN_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*BLUE 5 mA Current Skip OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x1, 0x0,0x0,0x0}, /*LED_BLUE_01_ON_19_OFF,skip off*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x2, 0x0,0x0,0x0}, /*LED_BLUE_02_ON_18_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x3, 0x0,0x0,0x0}, /*LED_BLUE_05_ON_15_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x4, 0x0,0x0,0x0}, /*LED_BLUE_025_ON_075_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x5, 0x0,0x0,0x0}, /*LED_BLUE_025_ON_175_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x6, 0x0,0x0,0x0}, /*LED_BLUE_005_ON_195_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x7, 0x0,0x0,0x0}, /*LED_BLUE_05_ON_05_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x8, 0x0,0x0,0x0}, /*LED_BLUE_05_OFF_05_ON*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x9, 0x0,0x0,0x0}, /*LED_BLUE_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0xa, 0x0,0x0,0x0}, /*LED_BLUE_0125_ON_2075_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0xb, 0x0,0x0,0x0}, /*LED_BLUE_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*BLUE 5 mA Current Skip On*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x1, 0x0,0x0,0x1}, /*LED_BLUE_01_ON_19_OFF,skip On*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x2, 0x0,0x0,0x1}, /*LED_BLUE_02_ON_18_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x3, 0x0,0x0,0x1}, /*LED_BLUE_05_ON_15_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x4, 0x0,0x0,0x1}, /*LED_BLUE_025_ON_075_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x5, 0x0,0x0,0x1}, /*LED_BLUE_025_ON_175_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x6, 0x0,0x0,0x1}, /*LED_BLUE_005_ON_195_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x7, 0x0,0x0,0x1}, /*LED_BLUE_05_ON_05_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x8, 0x0,0x0,0x1}, /*LED_BLUE_05_OFF_05_ON*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0x9, 0x0,0x0,0x1}, /*LED_BLUE_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0xa, 0x0,0x0,0x1}, /*LED_BLUE_0125_ON_2075_OFF*/ -+ {0x1,0x1, 0x0,0x1, 0x0,0xb, 0x0,0x0,0x1}, /*LED_BLUE_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*ORANGE 5 mA Current Skip OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x1,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_01_ON_19_OFF,skip off*/ -+ {0x0,0x0, 0x1,0x0, 0x2,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_02_ON_18_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x3,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_05_ON_15_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x4,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_025_ON_075_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x5,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_025_ON_175_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x6,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_005_ON_195_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x7,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_05_ON_05_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x8,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_05_OFF_05_ON*/ -+ {0x0,0x0, 0x1,0x0, 0x9,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0xa,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_0125_ON_2075_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0xb,0x0, 0x1,0x0,0x0}, /*LED_ORANGE_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*ORANGE 5 mA current Skip On*/ -+ {0x0,0x0, 0x1,0x0, 0x1,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_01_ON_19_OFF,skip On*/ -+ {0x0,0x0, 0x1,0x0, 0x2,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_02_ON_18_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x3,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_05_ON_15_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x4,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_025_ON_075_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x5,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_025_ON_175_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x6,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_005_ON_195_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x7,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_05_ON_05_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0x8,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_05_OFF_05_ON*/ -+ {0x0,0x0, 0x1,0x0, 0x9,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_0125_ON_05_OFF_0075_ON_15_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0xa,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_0125_ON_2075_OFF*/ -+ {0x0,0x0, 0x1,0x0, 0xb,0x0, 0x1,0x0,0x1}, /*LED_ORANGE_0625_OFF_0075_ON_15_OFF*/ -+ -+ /*LED_RED_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF*/ -+ {0x0,0x1, 0x1,0x1, 0xa,0xb, 0x1,0x0,0x0}, -+ /*LED_GREEN_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF*/ -+ {0x1,0x0, 0x1,0x1, 0xa,0xb, 0x1,0x0,0x0}, -+ /*LED_ORANGE_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF*/ -+ {0x0,0x0, 0x1,0x1, 0xa,0xb, 0x1,0x0,0x0}, -+ -+ /*LED_RED_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF_SKIP*/ -+ {0x0,0x1, 0x1,0x1, 0xa,0xb, 0x1,0x0,0x1}, -+ /*LED_GREEN_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF_SKIP*/ -+ {0x1,0x0, 0x1,0x1, 0xa,0xb, 0x1,0x0,0x1}, -+ /*LED_ORANGE_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF_SKIP*/ -+ {0x0,0x0, 0x1,0x1, 0xa,0xb, 0x1,0x0,0x1}, -+ -+ {0, 0, 0, 0, 0, 0, 0, 0, 0} -+}; -+ -+#ifdef DEBUG_LED_DRIVER -+char LED_Name[LED_BOTTOM_STATE +1][100]= -+{ -+ "LED_OFF", -+ -+ "LED_RED_ALWAYS_ON", -+ "LED_GREEN_ALWAYS_ON", -+ "LED_BLUE_ALWAYS_ON", -+ "LED_LIGHT_RED_ALWAYS_ON", -+ "LED_ORANGE_ALWAYS_ON", -+ "LED_LIGHT_BLUE_ALWAYS_ON", -+ "LED_WHITE_ALWAYS_ON", -+ -+ "LED_RED_01_ON_19_OFF", -+ "LED_RED_02_ON_18_OFF", -+ "LED_RED_05_ON_15_OFF", -+ "LED_RED_025_ON_075_OFF", -+ "LED_RED_025_ON_175_OFF", -+ "LED_RED_005_ON_195_OFF", -+ "LED_RED_05_ON_05_OFF", -+ "LED_RED_05_OFF_05_ON", -+ "LED_RED_0125_ON_05_OFF_0075_ON_15_OFF", -+ "LED_RED_0125_ON_2075_OFF", -+ "LED_RED_0625_OFF_0075_ON_15_OFF", -+ -+ "LED_RED_01_ON_19_OFF_SKIP", -+ "LED_RED_02_ON_18_OFF_SKIP", -+ "LED_RED_05_ON_15_OFF_SKIP", -+ "LED_RED_025_ON_075_OFF_SKIP", -+ "LED_RED_025_ON_175_OFF_SKIP", -+ "LED_RED_005_ON_195_OFF_SKIP", -+ "LED_RED_05_ON_05_OFF_SKIP", -+ "LED_RED_05_OFF_05_ON_SKIP", -+ "LED_RED_0125_ON_05_OFF_0075_ON_15_OFF_SKIP", -+ "LED_RED_0125_ON_2075_OFF_SKIP", -+ "LED_RED_0625_OFF_0075_ON_15_OFF_SKIP", -+ -+ "LED_GREEN_01_ON_19_OFF", -+ "LED_GREEN_02_ON_18_OFF", -+ "LED_GREEN_05_ON_15_OFF", -+ "LED_GREEN_025_ON_075_OFF", -+ "LED_GREEN_025_ON_175_OFF", -+ "LED_GREEN_005_ON_195_OFF", -+ "LED_GREEN_05_ON_05_OFF", -+ "LED_GREEN_05_OFF_05_ON", -+ "LED_GREEN_0125_ON_05_OFF_0075_ON_15_OFF", -+ "LED_GREEN_0125_ON_2075_OFF", -+ "LED_GREEN_0625_OFF_0075_ON_15_OFF", -+ -+ "LED_GREEN_01_ON_19_OFF_SKIP", -+ "LED_GREEN_02_ON_18_OFF_SKIP", -+ "LED_GREEN_05_ON_15_OFF_SKIP", -+ "LED_GREEN_025_ON_075_OFF_SKIP", -+ "LED_GREEN_025_ON_175_OFF_SKIP", -+ "LED_GREEN_005_ON_195_OFF_SKIP", -+ "LED_GREEN_05_ON_05_OFF_SKIP", -+ "LED_GREEN_05_OFF_05_ON_SKIP", -+ "LED_GREEN_0125_ON_05_OFF_0075_ON_15_OFF_SKIP", -+ "LED_GREEN_0125_ON_2075_OFF_SKIP", -+ "LED_GREEN_0625_OFF_0075_ON_15_OFF_SKIP", -+ -+ "LED_BLUE_01_ON_19_OFF", -+ "LED_BLUE_02_ON_18_OFF", -+ "LED_BLUE_05_ON_15_OFF", -+ "LED_BLUE_025_ON_075_OFF", -+ "LED_BLUE_025_ON_175_OFF", -+ "LED_BLUE_005_ON_195_OFF", -+ "LED_BLUE_05_ON_05_OFF", -+ "LED_BLUE_05_OFF_05_ON", -+ "LED_BLUE_0125_ON_05_OFF_0075_ON_15_OFF", -+ "LED_BLUE_0125_ON_2075_OFF", -+ "LED_BLUE_0625_OFF_0075_ON_15_OFF", -+ -+ "LED_BLUE_01_ON_19_OFF_SKIP", -+ "LED_BLUE_02_ON_18_OFF_SKIP", -+ "LED_BLUE_05_ON_15_OFF_SKIP", -+ "LED_BLUE_025_ON_075_OFF_SKIP", -+ "LED_BLUE_025_ON_175_OFF_SKIP", -+ "LED_BLUE_005_ON_195_OFF_SKIP", -+ "LED_BLUE_05_ON_05_OFF_SKIP", -+ "LED_BLUE_05_OFF_05_ON_SKIP", -+ "LED_BLUE_0125_ON_05_OFF_0075_ON_15_OFF_SKIP", -+ "LED_BLUE_0125_ON_2075_OFF_SKIP", -+ "LED_BLUE_0625_OFF_0075_ON_15_OFF_SKIP", -+ -+ "LED_ORANGE_01_ON_19_OFF", -+ "LED_ORANGE_02_ON_18_OFF", -+ "LED_ORANGE_05_ON_15_OFF", -+ "LED_ORANGE_025_ON_075_OFF", -+ "LED_ORANGE_025_ON_175_OFF", -+ "LED_ORANGE_005_ON_195_OFF", -+ "LED_ORANGE_05_ON_05_OFF", -+ "LED_ORANGE_05_OFF_05_ON", -+ "LED_ORANGE_0125_ON_05_OFF_0075_ON_15_OFF", -+ "LED_ORANGE_0125_ON_2075_OFF", -+ "LED_ORANGE_0625_OFF_0075_ON_15_OFF", -+ -+ "LED_ORANGE_01_ON_19_OFF_SKIP", -+ "LED_ORANGE_02_ON_18_OFF_SKIP", -+ "LED_ORANGE_05_ON_15_OFF_SKIP", -+ "LED_ORANGE_025_ON_075_OFF_SKIP", -+ "LED_ORANGE_025_ON_175_OFF_SKIP", -+ "LED_ORANGE_005_ON_195_OFF_SKIP", -+ "LED_ORANGE_05_ON_05_OFF_SKIP", -+ "LED_ORANGE_05_OFF_05_ON_SKIP", -+ "LED_ORANGE_0125_ON_05_OFF_0075_ON_15_OFF_SKIP", -+ "LED_ORANGE_0125_ON_2075_OFF_SKIP", -+ "LED_ORANGE_0625_OFF_0075_ON_15_OFF_SKIP", -+ -+ "LED_RED_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF", -+ "LED_GREEN_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF", -+ "LED_ORANGE_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF", -+ -+ -+ "LED_RED_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF_SKIP", -+ "LED_GREEN_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF_SKIP", -+ "LED_ORANGE_0125_ON_2075_OFF_BLUE_0625_OFF_0075_ON_15_OFF_SKIP", -+ "" -+}; /* LED Name*/ -+#endif -+/* These are the control structures for the LEDs. */ -+static struct led_info info1; -+static struct led_reg_info led1; -+static int old_state ; -+static unsigned int old_tempValue; -+static struct pm_dev *led_pxa_pm_dev; -+/*--------------------------------------------------------------------------- -+DESCRIPTION: Set LED state. -+INPUTS: int state LED light mode. -+OUTPUTS: int 0, succesee else return error no. -+IMPORTANT NOTES: -+To prevent RED to GREEN phase timing issues, the RED and Green LED bit codes should be written -+simultaneously. Additionally, changing the timing of one or both drivers should be accomplished by first writing a -+zero to each bit location, followed by a write to both locations with the desired bits. -+ -+---------------------------------------------------------------------------*/ -+int PXA_E680_LED_set(int state) -+{ -+ unsigned char ledr_en,ledg_en,ledr_ctrl,ledg_ctrl,ledr_i,ledg_i,skip; -+ unsigned int tempValue, value =0; -+ -+ if ( state >= LED_BOTTOM_STATE) -+ { -+ PRINTK("Driver:LED The State is invalid.\n"); -+ return 1; -+ } -+ else if ( old_state == state) -+ { -+ PRINTK("Driver:LED Same to previous State %s.\n",LED_Name[state]); -+ return 0; /*Donn't need change the LED state.*/ -+ } -+ /*First Disable LED.*/ -+ if(SSP_PCAP_read_data_from_PCAP(SSP_PCAP_ADJ_PERIPH_REGISTER,&tempValue)!= -+ SSP_PCAP_SUCCESS) -+ { -+ PRINTK("Driver:LED PCAP Read Failed.\n"); -+ return 1; -+ } -+ tempValue &= (~SSP_PCAP_LED_MASK); -+ if(SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_PERIPH_REGISTER,tempValue)!=SSP_PCAP_SUCCESS) -+ { -+ PRINTK("Driver:LED PCAP Write Failed (Clear Data).\n"); -+ return 1; -+ } -+ -+ /*Set GPIO as general I/O and as output*/ -+ set_GPIO_mode(IND_CNTL_R_BUL | GPIO_OUT); -+ set_GPIO_mode(IND_CNTL_G_BUL | GPIO_OUT); -+ -+ if (led_register_value[state].ind_GPIO_red && led_register_value[state].ind_GPIO_green) -+ { -+ /*Disable Red & Green signal*/ -+ set_GPIO(IND_CNTL_R_BUL); /*IND_CNTL_R_BUL Low active*/ -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ clr_GPIO(IND_CNTL_G_BUL); /*IND_CNTL_G_BUL High active*/ -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ PRINTK("GPIO Green Disable, Red Disable!\n"); -+ }else if ( (!led_register_value[state].ind_GPIO_red) && -+ led_register_value[state].ind_GPIO_green) -+ { -+ /*Green Disable, Red Enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ clr_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ PRINTK("GPIO Green Disable, Red Enable!\n"); -+ }else if ( led_register_value[state].ind_GPIO_red && -+ !led_register_value[state].ind_GPIO_green) -+ { -+ /*Red Disable, Green Enable*/ -+ set_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ PRINTK("GPIO Red Disable, Green Enable"); -+ }else -+ { -+ /*Red & Green enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ PRINTK("GPIO Red & Green enable!\n"); -+ } -+ PRINTK("Driver:--IND_CNTL_G_BUL:%x IND_CNTL_R_BUL:%x\n",GPIO_is_high(IND_CNTL_G_BUL), -+ GPIO_is_high(IND_CNTL_R_BUL)); -+ /* Write PCAP Peripheral Control Register*/ -+ ledr_en = led_register_value[state].pcap_LEDR_en & 0x1; -+ ledg_en = led_register_value[state].pcap_LEDG_en & 0x1; -+ ledr_ctrl = led_register_value[state].pcap_LEDR_CTRL & 0xf; -+ ledg_ctrl = led_register_value[state].pcap_LEDG_CTRL & 0xf; -+ ledr_i = led_register_value[state].pcap_LEDR_I & 0x3; -+ ledg_i = led_register_value[state].pcap_LEDG_I & 0x3; -+ skip = led_register_value[state].pcap_SKIP_on & 0x1; -+ -+ value = ( ledr_en | (ledg_en <<1) | (ledr_ctrl <<2) | (ledg_ctrl <<6) | -+ (ledr_i << 10) | (ledg_i <<12) | (skip <<14) ) & 0x7fff; -+ tempValue |= (value <<SSP_PCAP_LED_SHIFT); -+ if(SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_PERIPH_REGISTER,tempValue)==SSP_PCAP_SUCCESS) -+ { -+ PRINTK("Driver:LED write Value to PCAP:0x%x :0x%x\n",tempValue,value); -+ PRINTK("Driver:LED State To: %s\n",LED_Name[state]); -+ old_tempValue = tempValue; -+ old_state = state; -+ return 0; -+ }else -+ { -+ PRINTK("Driver:LED: Changed to State %s Failed.\n",LED_Name[state]); -+ return 1; -+ } -+} -+ -+ -+/*--------------------------------------------------------------------------- -+DESCRIPTION: reptore PGSR. -+INPUTS: old_state. -+OUTPUTS: int 0, succesee else return error no. -+IMPORTANT NOTES: -+ -+---------------------------------------------------------------------------*/ -+int PXA_E680_LED_retore_PGSR(struct pm_dev *dev, pm_request_t rqst, void *data) -+{ -+ unsigned int tempValue; -+ -+ -+ switch (rqst) -+ { -+ case PM_RESUME: -+ { -+ /*First Disable LED.*/ -+ if(SSP_PCAP_read_data_from_PCAP(SSP_PCAP_ADJ_PERIPH_REGISTER,&tempValue)!= -+ SSP_PCAP_SUCCESS) -+ { -+ PRINTK("Driver:LED PCAP Read Failed.\n"); -+ return 1; -+ } -+ tempValue &= (~SSP_PCAP_LED_MASK); -+ if(SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_PERIPH_REGISTER,tempValue)!=SSP_PCAP_SUCCESS) -+ { -+ PRINTK("Driver:LED PCAP Write Failed (Clear Data).\n"); -+ return 1; -+ } -+ -+ if (led_register_value[old_state].ind_GPIO_red && led_register_value[old_state].ind_GPIO_green) -+ { -+ /*Disable Red & Green signal*/ -+ set_GPIO(IND_CNTL_R_BUL); /*IND_CNTL_R_BUL Low active*/ -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ clr_GPIO(IND_CNTL_G_BUL); /*IND_CNTL_G_BUL High active*/ -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ PRINTK("RESTORE____GPIO Green Disable, Red Disable!\n"); -+ }else if ( (!led_register_value[old_state].ind_GPIO_red) && -+ led_register_value[old_state].ind_GPIO_green) -+ { -+ /*Green Disable, Red Enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ clr_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ -+ PRINTK("RESTORE____GPIO Green Disable, Red Enable!\n"); -+ }else if ( led_register_value[old_state].ind_GPIO_red && -+ !led_register_value[old_state].ind_GPIO_green) -+ { -+ /*Red Disable, Green Enable*/ -+ set_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ PRINTK("RESTORE____GPIO Red Disable, Green Enable"); -+ }else -+ { -+ /*Red & Green enable*/ -+ clr_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) & (~GPIO_bit(IND_CNTL_R_BUL)); -+ -+ set_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) | GPIO_bit(IND_CNTL_G_BUL); -+ PRINTK("RESTORE____GPIO Red & Green enable!\n"); -+ } -+ PRINTK("Driver:--IND_CNTL_G_BUL:%x IND_CNTL_R_BUL:%x\n",GPIO_is_high(IND_CNTL_G_BUL), -+ GPIO_is_high(IND_CNTL_R_BUL)); -+ -+ if(SSP_PCAP_write_data_to_PCAP(SSP_PCAP_ADJ_PERIPH_REGISTER,old_tempValue)==SSP_PCAP_SUCCESS) -+ { -+ PRINTK("Driver:LED write Value to PCAP:0x%x\n",old_tempValue); -+ PRINTK("Driver:LED State To: %s\n",LED_Name[old_state]); -+ return 0; -+ }else -+ { -+ PRINTK("Driver:LED: Changed to State %s Failed.\n",LED_Name[old_state]); -+ return 1; -+ } -+ -+ break; -+ }//end of case RESUME -+ }//end of switch -+ return 0; -+}//end of function -+ -+ -+/* Handle an actual LED set*/ -+int handle_led_op(struct led_reg_info *info, -+ struct led_op *op) -+{ -+ switch (op->op) -+ { -+ case SET_LED: -+ if ( PXA_E680_LED_set(op->op_info.bicolor.color) == 0) -+ return 0; -+ else -+ return -EINVAL; -+ default: -+ PRINTK("LED:Error CMD.\n"); -+ return -EINVAL; -+ } -+} -+ -+/** -+ * PXA_E680_LED_exit: -+ * -+ * Remove the LEDs from the LED driver -+ */ -+ -+static void __exit PXA_E680_LED_exit(void) -+{ -+ pm_unregister(led_pxa_pm_dev); -+ unregister_led_info(&led1); -+} -+ -+/** -+ * PXA_E680_LED_init -+ * -+ * Register the LEDs with the LED driver. -+ */ -+ -+static int __init PXA_E680_LED_init(void) -+{ -+ info1.type = LED_TYPE_BICOLOR; -+ strcpy(info1.name, LED_E680_NAME); -+ led1.info = &info1; -+ led1.data = (void *) 0; -+ led1.handle_led_op = handle_led_op; -+ register_led_info(&led1); -+ -+ old_state = LED_OFF; -+ old_tempValue = 0; -+ led_pxa_pm_dev = pm_register(PM_UNKNOWN_DEV, PM_SYS_UNKNOWN, PXA_E680_LED_retore_PGSR); -+ -+ /*Set GPIO as general IO and as Output*/ -+ set_GPIO_mode(IND_CNTL_R_BUL | GPIO_OUT); -+ set_GPIO_mode(IND_CNTL_G_BUL | GPIO_OUT); -+ -+ set_GPIO(IND_CNTL_R_BUL); -+ PGSR(IND_CNTL_R_BUL) = PGSR(IND_CNTL_R_BUL) | GPIO_bit(IND_CNTL_R_BUL); -+ -+ clr_GPIO(IND_CNTL_G_BUL); -+ PGSR(IND_CNTL_G_BUL) = PGSR(IND_CNTL_G_BUL) & (~GPIO_bit(IND_CNTL_G_BUL)); -+ PRINTK("PCAP2 LED driver: v%s E680\n", VERSION); -+ return 0; -+} -+ -+module_init(PXA_E680_LED_init); -+module_exit(PXA_E680_LED_exit); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.16.5-a/drivers/char/mstone_keypad.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/char/mstone_keypad.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,581 @@ -+/* -+ * linux/driver/char/mstone_keypad.c -+ * Keypad driver for Intel Mainstone development board -+ * -+ * Copyright (C) 2003, Intel Corporation (yu.tang@intel.com) -+ * Copyright 2003 MontaVista Software Inc. -+ * Author: MontaVista Software, Inc. -+ * source@mvista.com -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/errno.h> -+#include <linux/delay.h> -+#include <linux/poll.h> -+#include <linux/spinlock.h> -+#include <linux/sem.h> -+#include <linux/miscdevice.h> -+#include <asm/system.h> -+#include <asm/irq.h> -+#include <asm/hardware.h> -+#include <asm/hardirq.h> -+#include <asm/uaccess.h> -+#include <asm/ioctl.h> -+ -+#include <asm/arch/keypad.h> -+ -+/* Direct-KEY scan-code for Mainstone-I Board */ -+#define ROTARY_DEFAULT 0x7F -+#define NO_KEY 0xFF -+#define SCAN_CODE_SCROLL_UP 0xA -+#define SCAN_CODE_SCROLL_DOWN 0xB -+#define SCAN_CODE_ACTION 0xC -+ -+DECLARE_MUTEX(kpdrv_mutex); -+static struct kpe_queue kpe_queue; -+static int kpdrv_refcount = 0; -+ -+//#define DEBUG 1 -+#if DEBUG -+static unsigned int mstone_keypad_dbg = 1; -+#else -+#define mstone_keypad_dbg 0 -+#endif -+ -+#ifdef CONFIG_DPM -+#include <linux/device.h> -+ -+static int pxakpd_suspend(struct device *dev, u32 state, u32 level); -+static int pxakpd_resume(struct device *dev, u32 level); -+static int pxakpd_scale(struct bus_op_point *op, u32 level); -+ -+static struct device_driver pxakpd_driver_ldm = { -+ name: "pxa-kpd", -+ devclass: NULL, -+ probe: NULL, -+ suspend: pxakpd_suspend, -+ resume: pxakpd_resume, -+ scale: pxakpd_scale, -+ remove: NULL, -+ constraints: NULL, -+}; -+ -+static struct device pxakpd_device_ldm = { -+ name: "PXA Keypad", -+ bus_id: "pxakpd", -+ driver: NULL, -+ power_state: DPM_POWER_ON, -+}; -+ -+static void -+pxakpd_ldm_register(void) -+{ -+ extern void pxaopb_driver_register(struct device_driver *driver); -+ extern void pxaopb_device_register(struct device *device); -+ -+ pxaopb_driver_register(&pxakpd_driver_ldm); -+ pxaopb_device_register(&pxakpd_device_ldm); -+} -+ -+static void -+pxakpd_ldm_unregister(void) -+{ -+ extern void pxaopb_driver_unregister(struct device_driver *driver); -+ extern void pxaopb_device_unregister(struct device *device); -+ -+ pxaopb_device_unregister(&pxakpd_device_ldm); -+ pxaopb_driver_unregister(&pxakpd_driver_ldm); -+} -+ -+static int -+pxakpd_resume(struct device *dev, u32 level) -+{ -+ if (mstone_keypad_dbg) -+ printk("+++: in pxakpd_resume()\n"); -+ -+ switch (level) { -+ case RESUME_POWER_ON: -+ /* enable direct and matrix interrupts */ -+ KPC |= (KPC_DIE | KPC_MIE); -+ -+ /* enable clock to keypad */ -+ CKEN |= CKEN19_KEYPAD; -+ { -+ struct kp_event kpe; -+ unsigned char c; -+ -+ kpe.flags |= (KP_DIRECT | KP_MATRIX ); -+ c = get_scancode(&kpe); -+ if (c != NO_KEY) { -+ /* Insert it into key event list. */ -+ kpq_put(&kpe); -+ } -+ else { -+ /* We are not woke by key press. */ -+ } -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+static int -+pxakpd_suspend(struct device *dev, u32 state, u32 level) -+{ -+ if (mstone_keypad_dbg) -+ printk("+++: in pxakpd_suspend()\n"); -+ -+ switch (level) { -+ case SUSPEND_POWER_DOWN: -+ /* disable clock to keypad */ -+ CKEN &= ~CKEN19_KEYPAD; -+ -+ /* disable direct and matrix interrupts */ -+ KPC &= ~(KPC_DIE | KPC_MIE); -+ break; -+ } -+ -+ return 0; -+} -+ -+static int -+pxakpd_scale(struct bus_op_point *op, u32 level) -+{ -+ printk("+++: in pxakpd_scale()\n"); -+ -+ return 0; -+} -+#endif /* CONFIG_DPM */ -+ -+/* Init kpe queue */ -+static void kpq_init(void) -+{ -+ kpe_queue.head = kpe_queue.tail = kpe_queue.len = 0; -+ kpe_queue.spinlock = SPIN_LOCK_UNLOCKED; -+ init_waitqueue_head(&kpe_queue.waitq); -+} -+ -+static int kpq_empty(void) -+{ -+ int flags, empty; -+ -+ spin_lock_irqsave(&kpe_queue.spinlock,flags); -+ empty = kpe_queue.len ? 0 : 1; -+ spin_unlock_irqrestore(&kpe_queue.spinlock, flags); -+ -+ return empty; -+} -+ -+static int kpq_get(struct kp_event *kpe) -+{ -+ int flags, err = 0; -+ -+ spin_lock_irqsave(&kpe_queue.spinlock, flags); -+ if (kpe_queue.head == kpe_queue.tail) { -+ printk(KERN_ERR "keypad: empty event queue, looks bad\n"); -+ err = -EAGAIN; -+ goto out; -+ } -+ memcpy(kpe, kpe_queue.kpes + kpe_queue.tail, sizeof(struct kp_event)); -+ kpe_queue.len--; -+ kpe_queue.tail = (kpe_queue.tail + 1) % MAX_KPES; -+ out: -+ spin_unlock_irqrestore(&kpe_queue.spinlock, flags); -+ return err; -+} -+ -+static void kpq_put(struct kp_event *kpe) -+{ -+ int flags; -+ -+ spin_lock_irqsave(&kpe_queue.spinlock, flags); -+ memcpy(kpe_queue.kpes + kpe_queue.head, kpe, sizeof(struct kp_event)); -+ kpe_queue.len++; -+ if (kpe_queue.len == MAX_KPES) { -+ printk(KERN_ERR "keypad: events are comes too fast, will discard next\n"); -+ kpe_queue.len--; -+ goto out; -+ } -+ kpe_queue.head = (kpe_queue.head + 1) % MAX_KPES; -+ out: -+ spin_unlock_irqrestore(&kpe_queue.spinlock, flags); -+ /* Wake up the waiting processes */ -+ wake_up_interruptible(&kpe_queue.waitq); -+} -+ -+static int kp_direct_scan(struct kp_event *kpe) -+{ -+ kpe->flags |= KP_DIRECT; -+ kpe->direct = KPDK; -+ kpe->rotary = KPREC; -+ return 0; -+} -+ -+static int kp_matrix_scan(struct kp_event *kpe) -+{ -+ KPC |= KPC_AS; -+ while (KPAS &KPAS_SO); -+ -+ kpe->flags |= KP_MATRIX; -+ kpe->matrix[0] = KPAS; -+ kpe->matrix[1] = KPASMKP0; -+ kpe->matrix[2] = KPASMKP1; -+ kpe->matrix[3] = KPASMKP2; -+ kpe->matrix[4] = KPASMKP3; -+ -+ KPC &= ~KPC_AS; -+ -+ return 0; -+} -+ -+/* Interrupt kandler for keypad */ -+static void kp_interrupt(int irq, void *ptr, struct pt_regs *regs) -+{ -+ struct kp_event kpe = {0}; -+ int flags; -+ unsigned long kpc_val; -+ -+ printk("+++: kp_interrupt()\n"); -+ -+ spin_lock_irqsave(&kpe_queue.spinlock,flags); -+ -+ /* ACK interrupt */ -+ kpc_val = KPC; -+ kpe.jiffies = jiffies; -+ -+ /* Direct interrupt */ -+ if (kpc_val & KPC_DI) -+ kp_direct_scan(&kpe); -+ -+ /* Matrix interrupt */ -+ if (kpc_val & KPC_MI) -+ kp_matrix_scan(&kpe); -+ -+ spin_unlock_irqrestore(&kpe_queue.spinlock, flags); -+ -+ if (((kpe.flags & KP_DIRECT) || (kpe.flags & KP_MATRIX)) && kpdrv_refcount) -+ kpq_put(&kpe); -+} -+ -+/* Wait for keypad event, must be in task-context */ -+int kp_wait(struct kp_event *kpe, signed int timeout) -+{ -+ int n, err = 0; -+ -+ while(1) { -+ if (!kpq_empty()) { -+ n = kpq_get(kpe); -+ if (n < 0) -+ continue; -+ break; -+ } -+ -+ /* No event available ? */ -+ if (!timeout) { -+ err = -EAGAIN; -+ break; -+ } -+ -+ if (timeout > 0) { -+ /* Wait for timeout */ -+ timeout = interruptible_sleep_on_timeout(&kpe_queue.waitq, timeout); -+ continue; -+ } -+ else{ -+ /* Wait for kpevent/signal */ -+ while(1) { -+ interruptible_sleep_on(&kpe_queue.waitq); -+ if (kpq_empty() && !signal_pending(current)) -+ continue; -+ break; -+ } -+ -+ if (signal_pending(current)) { -+ err = -EINTR; -+ break; -+ } -+ } -+ } -+ return err; -+} -+ -+/* Poll for keypad event */ -+unsigned int kp_poll(struct file *file, poll_table *wait) -+{ -+ poll_wait(file, &kpe_queue.waitq, wait); -+ return kpq_empty() ? 0 : POLLIN | POLLRDNORM; -+} -+ -+static unsigned char get_scancode(struct kp_event *kpe) -+{ -+ static unsigned int curr, prev = ROTARY_DEFAULT; -+ unsigned int c; -+ -+ c = NO_KEY; -+ -+ if (kpe->flags & KP_DIRECT) { -+ -+ curr = kpe->rotary & 0xFF; -+ -+ if (kpe->rotary & KPREC_OF0) { -+ KPREC &= ~KPREC_OF0; -+ KPREC |= ROTARY_DEFAULT; -+ prev = ROTARY_DEFAULT; -+ c = SCAN_CODE_SCROLL_UP; -+ } -+ else if (kpe->rotary & KPREC_UF0) { -+ KPREC &= ~KPREC_UF0; -+ KPREC |= ROTARY_DEFAULT; -+ prev = ROTARY_DEFAULT; -+ c = SCAN_CODE_SCROLL_DOWN; -+ } -+ else if (curr > prev) { -+ c = SCAN_CODE_SCROLL_UP; -+ prev = curr; -+ } -+ else if (curr < prev) { -+ c = SCAN_CODE_SCROLL_DOWN; -+ prev = curr; -+ } -+ else if (kpe->direct & KPDK_DK2) { -+ c = SCAN_CODE_ACTION; -+ prev = curr; -+ } -+ } -+ -+ if (kpe->flags & KP_MATRIX) { -+ unsigned int count = (kpe->matrix[0] >> 26) & 0x1f; -+ -+ c = kpe->matrix[0] & 0xff; -+ -+ /* Key up */ -+ if (!count) c |= 0x80; -+ } -+ -+ return c; -+} -+ -+static ssize_t kpdrv_read(struct file * filp, char * buf, -+ size_t count, loff_t *ppos) -+{ -+ struct kp_event kpe; -+ int err,left,timeout; -+ unsigned char c; -+ -+ timeout = 0; -+ left = count; -+ do { -+ err = kp_wait(&kpe, timeout); -+ if (err) { -+ if ( left != count ) return (count-left); -+ -+ if (filp->f_flags & O_NONBLOCK) return err; -+ -+ if (timeout) return err; -+ -+ timeout = -1; -+ continue; -+ } -+ /* Parse if direct/matrix flags are set*/ -+ if ( (kpe.flags & KP_DIRECT) || (kpe.flags & KP_MATRIX) ) { -+ c = get_scancode(&kpe); -+ if (c != NO_KEY) { -+ put_user(c, buf++); -+ left --; -+ } -+ } -+ } while (left); -+ return (count-left); -+} -+ -+static int kpdrv_ioctl(struct inode *ip, struct file *fp, -+ unsigned int cmd, unsigned long arg) -+{ -+ int interval = KPKDI & 0xffff; -+ int ign = (KPC & KPC_IMKP); -+ -+ switch(cmd) { -+ case KPIOGET_INTERVAL: -+ if (copy_to_user((void*)arg, &interval, sizeof(int))) -+ return -EFAULT; -+ break; -+ case KPIOGET_IGNMULTI: -+ if (copy_to_user((void*)arg, &ign, sizeof(int))) -+ return -EFAULT; -+ break; -+ case KPIOSET_INTERVAL: -+ if (copy_from_user(&interval, (void*)arg, sizeof(int))) -+ return -EFAULT; -+ -+ /* FIXME : sighting #34833, Matrix Key interval should be >10ms */ -+ if ( (interval & 0xff) < 10) return -EINVAL; -+ -+ KPKDI &= ~0xffff; -+ KPKDI |= (interval & 0xffff); -+ break; -+ case KPIOSET_IGNMULTI: -+ if (copy_from_user(&ign, (void*)arg, sizeof(int))) -+ return -EFAULT; -+ -+ if (ign) -+ KPC |= KPC_IMKP; -+ else -+ KPC &= ~KPC_IMKP; -+ -+ break; -+ -+ default: -+ /* Unknown command */ -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static unsigned int kpdrv_poll(struct file *filp, poll_table * wait) { -+ return kp_poll(filp, wait); -+} -+ -+static int kpdrv_open(struct inode *inode, struct file *filp) -+{ -+ down(&kpdrv_mutex); -+ if (!kpdrv_refcount) -+ kpq_init(); -+ kpdrv_refcount++; -+ up(&kpdrv_mutex); -+ return 0; -+} -+ -+static int kpdrv_close(struct inode *inode, struct file *filp) -+{ -+ down(&kpdrv_mutex); -+ kpdrv_refcount--; -+ up(&kpdrv_mutex); -+ -+ return 0; -+} -+ -+static struct file_operations kpdrv_fops = { -+ owner: THIS_MODULE, -+ open: kpdrv_open, -+ release: kpdrv_close, -+ read: kpdrv_read, -+ ioctl: kpdrv_ioctl, -+ poll: kpdrv_poll, -+}; -+ -+ -+static struct miscdevice keypad_miscdevice = { -+ minor: MISC_DYNAMIC_MINOR, -+ name: "keypad", -+ fops: &kpdrv_fops -+}; -+ -+static int __init kpdrv_init(void) -+{ -+ int err; -+ -+ /* Setup gpio */ -+ set_GPIO_mode(93 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(94 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(95 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(96 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(97 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(98 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(99 | GPIO_ALT_FN_1_IN); -+ -+ set_GPIO_mode(100 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(101 | GPIO_ALT_FN_1_IN); -+ set_GPIO_mode(102 | GPIO_ALT_FN_1_IN); -+ -+ set_GPIO_mode(103 | GPIO_ALT_FN_2_OUT); -+ set_GPIO_mode(104 | GPIO_ALT_FN_2_OUT); -+ set_GPIO_mode(105 | GPIO_ALT_FN_2_OUT); -+ set_GPIO_mode(106 | GPIO_ALT_FN_2_OUT); -+ set_GPIO_mode(107 | GPIO_ALT_FN_2_OUT); -+ set_GPIO_mode(108 | GPIO_ALT_FN_2_OUT); -+ -+ /* Set keypad control register */ -+ KPC = (KPC_ASACT | (3<<26) | (4<<23)| -+ KPC_ME | (2<<6) | KPC_DEE0 | KPC_DE | -+ KPC_MS_ALL | KPC_MIE | KPC_DIE | KPC_IMKP); -+ -+ /* Set debouce time seperately for Matrix/Direct. */ -+ KPKDI= 0x010A; -+ -+ /* Set scroll wheel value to mid-point value */ -+ KPREC= 0x7F; -+ -+ /* Enable unit clock */ -+ CKEN |= CKEN19_KEYPAD; -+ -+ /* Request keypad IRQ */ -+ err = request_irq(IRQ_KEYPAD, kp_interrupt, 0, "keypad", NULL); -+ if (err) { -+ printk (KERN_CRIT "can't register IRQ%d for keypad, error %d\n", -+ IRQ_KEYPAD, err); -+ /* Disable clock unit */ -+ CKEN &= ~CKEN19_KEYPAD; -+ return -ENODEV; -+ } -+ -+ /* Register driver as miscdev */ -+ err = misc_register(&keypad_miscdevice); -+ if (err) -+ printk(KERN_ERR "can't register keypad misc device, error %d\n", err); -+ else -+ printk(KERN_INFO "Intel Mainstone Keypad driver registered with minor %d\n", -+ keypad_miscdevice.minor); -+ -+#ifdef CONFIG_DPM -+ pxakpd_ldm_register(); -+#endif /* CONFIG_DPM */ -+ -+ return err; -+} -+ -+static void __exit kpdrv_exit(void) -+{ -+#ifdef CONFIG_DPM -+ pxakpd_ldm_unregister(); -+#endif /* CONFIG_DPM */ -+ -+ /* Disable clock unit */ -+ CKEN &= ~CKEN19_KEYPAD; -+ -+ /* Free keypad IRQ */ -+ free_irq(IRQ_KEYPAD, NULL); -+ -+ /* Unregister keypad device */ -+ misc_deregister(&keypad_miscdevice); -+} -+ -+module_init(kpdrv_init); -+module_exit(kpdrv_exit); -+ -+MODULE_AUTHOR("Yu Tang <yu.tang@intel.com>, source@mvista.com"); -+MODULE_DESCRIPTION("Intel Mainstone KEYPAD driver"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.16.5-a/drivers/char/n_tty.c -=================================================================== ---- linux-2.6.16.5-a.orig/drivers/char/n_tty.c 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/drivers/char/n_tty.c 2006-05-04 17:07:04.000000000 +0200 -@@ -60,6 +60,12 @@ - #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */ - #define TTY_THRESHOLD_UNTHROTTLE 128 - -+#if defined(CONFIG_ARCH_EZX) && 0 -+extern int btuart_flip_flow_ctl; -+extern void rs_flip_unthrottle(struct tty_struct *tty); -+#endif -+ -+ - static inline unsigned char *alloc_buf(void) - { - gfp_t prio = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; -@@ -957,6 +963,11 @@ - - n_tty_set_room(tty); - -+#if defined (CONFIG_ARCH_EZX) && 0 -+ if (tty && tth->driver.btuart) -+ rs_flip_unthrottle(tty); -+#endif -+ - if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { - kill_fasync(&tty->fasync, SIGIO, POLL_IN); - if (waitqueue_active(&tty->read_wait)) -Index: linux-2.6.16.5-a/drivers/char/sram.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/char/sram.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,194 @@ -+/* -+ * linux/drivers/char/sram.c -+ * -+ * Bulverde Internal Memory character device driver -+ * -+ * Created: Sep 05, 2003 -+ * Copyright: MontaVista Software Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/config.h> -+#include <linux/mm.h> -+#include <linux/major.h> -+#include <linux/miscdevice.h> -+#include <linux/vmalloc.h> -+#include <linux/mman.h> -+#include <linux/init.h> -+#include <linux/rwsem.h> -+ -+#include <asm/uaccess.h> -+#include <asm/io.h> -+#include <asm/pgalloc.h> -+ -+#include <linux/devfs_fs_kernel.h> -+ -+static unsigned long sram_base = 0; -+static unsigned long sram_size = 0; -+ -+extern int sram_access_obtain(unsigned long *pmem, unsigned long *psize); -+extern int sram_access_release(unsigned long *pmem, unsigned long *psize); -+ -+/* -+ * This funcion reads the SRAM memory. -+ * The f_pos points to the SRAM memory location. -+ */ -+static ssize_t sram_read(struct file * file, char * buf, -+ size_t count, loff_t *ppos) { -+ unsigned long p = *ppos; -+ ssize_t read; -+ -+ if (p >= sram_size) -+ return 0; -+ -+ if (count > sram_size - p) -+ count = sram_size - p; -+ -+ read = 0; -+ -+ if (copy_to_user(buf, (char *)(sram_base + p), count)) -+ return -EFAULT; -+ -+ read += count; -+ *ppos += read; -+ -+ return read; -+} -+ -+static ssize_t sram_write(struct file * file, const char * buf, -+ size_t count, loff_t *ppos) { -+ unsigned long p = *ppos; -+ ssize_t written; -+ -+ if (p >= sram_size) -+ return 0; -+ -+ if (count > sram_size - p) -+ count = sram_size - p; -+ -+ written = 0; -+ -+ if (copy_from_user((char *)(sram_base + p), buf, count)) -+ return -EFAULT; -+ -+ written += count; -+ *ppos += written; -+ -+ return written; -+} -+ -+static int sram_mmap(struct file * file, struct vm_area_struct * vma) { -+ -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ -+ if (((file->f_flags & O_WRONLY) != 0) || -+ ((file->f_flags & O_RDWR) != 0)) { -+ vma->vm_page_prot = (pgprot_t)PAGE_SHARED; -+ } else { -+ vma->vm_page_prot = (pgprot_t)PAGE_READONLY; -+ } -+ -+ /* Do not cache SRAM memory if O_SYNC flag is set */ -+ if ((file->f_flags & O_SYNC) != 0) { -+ pgprot_val(vma->vm_page_prot) &= ~L_PTE_CACHEABLE; -+ } -+ -+ /* Don't try to swap out physical pages.. */ -+ vma->vm_flags |= VM_RESERVED | VM_LOCKED; -+ -+ if (remap_page_range(vma->vm_start, SRAM_MEM_PHYS + offset, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) { -+ return -EAGAIN; -+ } -+ -+ return 0; -+} -+ -+ -+static loff_t sram_lseek(struct file * file, loff_t offset, int orig) { -+ -+ switch (orig) { -+ case 0: -+ file->f_pos = offset; -+ break; -+ case 1: -+ file->f_pos += offset; -+ break; -+ case 2: -+ file->f_pos = SRAM_SIZE + offset; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (file->f_pos < 0) { -+ file->f_pos = 0; -+ } else if (file->f_pos > SRAM_SIZE) { -+ file->f_pos = SRAM_SIZE; -+ } -+ -+ return file->f_pos; -+} -+ -+static int sram_open(struct inode * inode, struct file * filp) { -+ return sram_access_obtain(&sram_base, &sram_size); -+} -+ -+static int sram_release(struct inode * inode, struct file * filp) { -+ return sram_access_release(&sram_base, &sram_size); -+} -+ -+ -+static struct file_operations sram_fops = { -+ llseek: sram_lseek, -+ read: sram_read, -+ write: sram_write, -+ mmap: sram_mmap, -+ open: sram_open, -+ release: sram_release, -+}; -+ -+static struct miscdevice sram_misc = { -+ minor : MISC_DYNAMIC_MINOR, -+ name : "misc/sram", -+ fops : &sram_fops, -+}; -+ -+static int __init sram_chr_init(void) { -+ if (misc_register(&sram_misc) != 0) -+ { -+ printk(KERN_ERR "Cannot register device /dev/%s\n", -+ sram_misc.name); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+static void __exit sram_chr_exit(void) { -+ misc_deregister(&sram_misc); -+} -+ -+module_init(sram_chr_init) -+module_exit(sram_chr_exit) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("MontaVista Software Inc."); -Index: linux-2.6.16.5-a/drivers/char/tty_io.c -=================================================================== ---- linux-2.6.16.5-a.orig/drivers/char/tty_io.c 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/drivers/char/tty_io.c 2006-05-04 17:07:04.000000000 +0200 -@@ -2772,6 +2772,14 @@ - goto out; - } - spin_lock_irqsave(&tty->buf.lock, flags); -+#if defined(CONFIG_EZX_A780) || defined(CONFIG_ARCH_EZX_E680) -+ if (tty && tty->driver.btuart && -+ ((N_TTY_BUF_SIZE - tty->read_cnt - 2) < (512 + 128))) { -+ schedule_delayed_work(&tty->flip.work, 1); -+ return; -+ } -+#endif -+ - while((tbuf = tty->buf.head) != NULL) { - while ((count = tbuf->commit - tbuf->read) != 0) { - char_buf = tbuf->char_buf_ptr + tbuf->read; -Index: linux-2.6.16.5-a/drivers/misc/Kconfig -=================================================================== ---- linux-2.6.16.5-a.orig/drivers/misc/Kconfig 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/drivers/misc/Kconfig 2006-05-04 17:07:04.000000000 +0200 -@@ -30,3 +30,4 @@ - - endmenu - -+source "drivers/misc/ezx/Kconfig" -Index: linux-2.6.16.5-a/drivers/misc/Makefile -=================================================================== ---- linux-2.6.16.5-a.orig/drivers/misc/Makefile 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/drivers/misc/Makefile 2006-05-04 17:07:04.000000000 +0200 -@@ -5,3 +5,4 @@ - - obj-$(CONFIG_IBM_ASM) += ibmasm/ - obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ -+obj-$(CONFIG_PXA_EZX) += ezx/ -Index: linux-2.6.16.5-a/drivers/misc/ezx/Kconfig -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/Kconfig 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,20 @@ -+# -+# Misc strange devices -+# -+ -+menu "Motorola EZX devices" -+ -+config KEYPAD_A780 -+ tristate "Device driver for Motorola A780 keypad" -+ -+config KEYPAD_E680 -+ tristate "Device driver for Motorola E680 keypad" -+ -+config KEYLIGHT_A780 -+ tristate "Device driver for Motorola A780 keylight" -+ -+config FMRADIO_E680 -+ tristate "Device driver for Motorola E680 FM Radio" -+ -+endmenu -+ -Index: linux-2.6.16.5-a/drivers/misc/ezx/Makefile -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/Makefile 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,13 @@ -+ -+obj-$(CONFIG_PXA_EZX) += ssp_pcap_main.o ezx-ts.o ezx-button.o ezx-emu.o -+ -+# obj-$(CONFIG_EZX) += keypad.o keypad-panasonic.o keypad-e398.o -+ -+obj-$(CONFIG_KEYPAD_A780) += keypad.o -+obj-$(CONFIG_KEYPAD_E680) += keypad.o -+obj-$(CONFIG_KEYLIGHT_A780) += keylight.o -+obj-$(CONFIG_FMRADIO_E680) += fmradio.o -+ -+obj-$(CONFIG_PANIC_LOG) += log.o -+obj-$(CONFIG_ARCH_EZX) += ezx_log.o -+ -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-button.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-button.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,476 @@ -+/* -+ * linux/drivers/char/ezx-button.c --- button driver on ezx -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Zhou Qiong, Jay Jia -+ * Created: Dec 16, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Jin Lihong(w20076) Mar.15,2004,LIBdd86574 headset judgement condition reverse -+ * Jin Lihong(w20076) Apr.13,2004,LIBdd96876 reorganise file header -+ * -+ */ -+ -+#include <linux/init.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/timer.h> -+#include <linux/fs.h> -+#include <linux/miscdevice.h> -+#include <linux/string.h> -+#include <linux/errno.h> -+#include <linux/poll.h> -+#include <linux/pm.h> -+#include <linux/delay.h> -+#include <linux/apm_bios.h> -+ -+#include <asm/hardware.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+#include <asm/semaphore.h> -+#include <asm/mach-types.h> -+#include <asm/arch/pxa-regs.h> -+#include <asm/arch/ezx.h> -+ -+#include "ssp_pcap.h" -+#include "ezx-button.h" -+ -+#define DEBUG -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+#endif -+ -+#define FULL(queue) ((queue.head+1==queue.tail)||(queue.head+1-NR_BUTTONS==queue.tail)) -+ -+struct button_queue{ -+ unsigned short button_buffer[NR_BUTTONS]; -+ unsigned int head; -+ unsigned int tail; -+}; -+ -+static struct timer_list lockscreen_timer; -+static struct timer_list answer_timer; -+ -+static DECLARE_WAIT_QUEUE_HEAD(button_wait_queue); /* Used for blocking read */ -+static struct button_queue buttonevent; -+ -+static int answer_flag=0; -+int lockscreen_flag=0; -+ -+static int first_open=0; -+static int before_emu=0; -+static int before_charge_500mA=0; -+static int before_charge_0mA=0; -+ -+void usb_cable_event_handler(unsigned short cable_event) -+{ -+ if(!FULL(buttonevent)) -+ { -+ buttonevent.button_buffer[buttonevent.head] = cable_event; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+ wake_up_interruptible(&button_wait_queue); -+ printk("usb cable event = %d\n", cable_event); -+ } -+} -+ -+static int button_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) -+{ -+ int data, ret; -+ -+ switch(cmd){ -+/* -+*/ -+ case BUTTON_GET_HEADSETSTATUS: -+ data = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_A1SNS); -+ if(data) -+ ret = HEADSET_IN; -+ else -+ ret = HEADSET_OUT; -+ return put_user(ret, (int *)arg); -+/* -+*/ -+ case BUTTON_GET_FLIPSTATUS: -+ data = GPLR(GPIO_FLIP_PIN) & GPIO_bit(GPIO_FLIP_PIN); -+ if(!data) -+ ret = FLIP_OFF; -+ else -+ ret = FLIP_ON; -+ lockscreen_flag = ret; -+ return put_user(ret, (int *)arg); -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static unsigned int button_poll(struct file *file, poll_table *wait) -+{ -+ poll_wait(file, &button_wait_queue, wait); -+ if(buttonevent.head != buttonevent.tail) -+ return POLLIN | POLLRDNORM; -+ return 0; -+} -+/* -+ * This function is called when a user space program attempts to read -+ * /dev/button. It puts the device to sleep on the wait queue until -+ * irq handler writes some data to the buffer and flushes -+ * the queue, at which point it writes the data out to the device and -+ * returns the number of characters it has written. This function is -+ * reentrant, so that many processes can be attempting to read from the -+ * device at any one time. -+ */ -+ -+static int button_read (struct file *file, char *buffer, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ int retval = 0; -+ -+ if (buttonevent.head == buttonevent.tail) -+ { -+ add_wait_queue(&button_wait_queue, &wait); -+ current->state = TASK_INTERRUPTIBLE; -+ -+ while (buttonevent.head == buttonevent.tail) -+ { -+ if (file->f_flags & O_NONBLOCK) -+ { -+ retval = -EAGAIN; -+ break; -+ } -+ if (signal_pending(current)) -+ { -+ retval = -ERESTARTSYS; -+ break; -+ } -+ schedule(); -+ } -+ current->state = TASK_RUNNING; -+ remove_wait_queue(&button_wait_queue, &wait); -+ } -+ -+ if (retval) -+ return retval; -+ -+ while ((buttonevent.head != buttonevent.tail) && (retval + sizeof(unsigned short)) <= count) -+ { -+ if (copy_to_user(buffer+retval, buttonevent.button_buffer+buttonevent.tail, sizeof(unsigned short))) -+ return -EFAULT; -+ buttonevent.tail = (buttonevent.tail+1)%(NR_BUTTONS); -+ retval += sizeof(unsigned short); -+ } -+ -+ return retval; -+} -+ -+static void scan_lockscreen_button(unsigned long parameters) -+{ -+ unsigned long data; -+ int bdelay = BUTTON_INTERVAL; -+ -+#ifdef DEBUG -+ printk("enter scan_lockscreen_button\n"); -+#endif -+ data = GPLR(GPIO_FLIP_PIN); -+ if(!(data & GPIO_bit(GPIO_FLIP_PIN))) // lockscreen - 0 -+ { -+ lockscreen_flag = 0; -+ if(!FULL(buttonevent)) -+ { -+ buttonevent.button_buffer[buttonevent.head] = FLIP | KEYDOWN; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+#ifdef CONFIG_KEYPAD_E680 -+ ssp_pcap_screenlock_lock(0); -+#endif -+ wake_up_interruptible(&button_wait_queue); -+#ifdef CONFIG_APM -+ apm_queue_event(KRNL_FLIP_OFF); -+#endif -+ -+#ifdef DEBUG -+ printk("LockScreen keydown\n"); -+#endif -+ } -+ } -+ else // lockscreen - 1 -+ { -+ lockscreen_flag = 1; -+ if(!FULL(buttonevent)) -+ { -+ buttonevent.button_buffer[buttonevent.head] = FLIP | KEYUP; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+#ifdef CONFIG_KEYPAD_E680 -+ ssp_pcap_screenlock_unlock(0); -+#endif -+ wake_up_interruptible(&button_wait_queue); -+#ifdef CONFIG_APM -+ apm_queue_event(KRNL_FLIP_ON); -+#endif -+ -+#ifdef DEBUG -+ printk("LockScreen keyup\n"); -+#endif -+ } -+ } -+} -+ -+static void scan_answer_button(unsigned long parameters) -+{ -+ int ssp_pcap_bit_status; -+ int bdelay = BUTTON_INTERVAL; -+ -+#ifdef DEBUG -+ printk("enter scan_answer_button\n"); -+#endif -+ /* read pcap register to check if headjack is in */ -+// ssp_pcap_bit_status = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_A1SNS); -+// if( ssp_pcap_bit_status != 0 ) /* headjack is in */ -+ { -+ ssp_pcap_bit_status = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_MB2SNS); -+ if(ssp_pcap_bit_status == 0) // keydown -+ { -+ answer_flag ++; -+ if((!FULL(buttonevent))&&((answer_flag==1)||((answer_flag%NR_REPEAT)==0))) -+ { -+ buttonevent.button_buffer[buttonevent.head] = ANSWER | KEYDOWN; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+ wake_up_interruptible(&button_wait_queue); -+#ifdef DEBUG -+ printk("answer keydown\n"); -+#endif -+ } -+ answer_timer.expires = (jiffies + bdelay); -+ add_timer (&answer_timer); -+ } -+ else if(answer_flag) // keyup -+ { -+ del_timer(&answer_timer); -+ answer_flag = 0; -+ if(!FULL(buttonevent)) -+ { -+ buttonevent.button_buffer[buttonevent.head] = ANSWER | KEYUP; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+ wake_up_interruptible(&button_wait_queue); -+#ifdef DEBUG -+ printk("answer keyup\n"); -+#endif -+ } -+ } -+ } -+} -+ -+static void lockscreen_handler(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ int bdelay = 10; /* The delay, in jiffies */ -+ -+ del_timer (&lockscreen_timer); -+ lockscreen_timer.expires = (jiffies + bdelay); -+ add_timer (&lockscreen_timer); -+} -+ -+void answer_button_handler(int irq, void *dev_id, struct pt_regs *regs) -+{ -+#if 0 -+ int bdelay = BUTTON_DELAY; /* The delay, in jiffies */ -+ -+ del_timer (&answer_timer); -+ answer_timer.expires = (jiffies + bdelay); -+ add_timer (&answer_timer); -+ printk("answer_button_handler\n"); -+#endif -+ scan_answer_button(0); -+} -+ -+void headset_in_handler(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ if(!FULL(buttonevent)) -+ { -+ buttonevent.button_buffer[buttonevent.head] = HEADSET_INT | KEYDOWN; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+ wake_up_interruptible(&button_wait_queue); -+ printk("headset button insert\n"); -+ answer_flag = 0; -+ } -+} -+ -+ -+void headset_out_handler(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ if(!FULL(buttonevent)) -+ { -+ buttonevent.button_buffer[buttonevent.head] = HEADSET_INT | KEYUP; -+ buttonevent.head = (buttonevent.head+1)%(NR_BUTTONS); -+ wake_up_interruptible(&button_wait_queue); -+ printk("headset button remove\n"); -+ answer_flag = 0; -+ } -+} -+ -+#ifdef CONFIG_PM -+static int button_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ break; -+ -+ case PM_RESUME: -+ break; -+ } -+ return 0; -+} -+#endif -+ -+static int count=0; -+static int button_release(struct inode * inode, struct file * file) -+{ -+ int i; -+ -+ count --; -+ if(count) -+ { -+ return -EBUSY; -+ } -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_MB2I); /* clear interrupt */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_MSR_MB2M); /* mask interrupt */ -+ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_A1I); /* clear interrupt */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_MSR_A1M); /* mask interrupt */ -+ -+ // init gpio12 input, -+// GPDR(GPIO_LOCK_SCREEN_PIN) &= 0xFFFFEFFF; -+ GPDR(GPIO_FLIP_PIN) &= ~(GPIO_bit(GPIO_FLIP_PIN)); -+ del_timer (&lockscreen_timer); -+ del_timer (&answer_timer); -+ free_irq(IRQ_GPIO(GPIO_FLIP_PIN), NULL); -+ -+ for(i=0; i<NR_BUTTONS; i++) -+ buttonevent.button_buffer[i] = 0; -+ buttonevent.head = 0; -+ buttonevent.tail = 0; -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+#ifdef DEBUG -+ printk("button device released\n"); -+#endif -+ -+ return 0; -+} -+ -+static int button_open(struct inode * inode, struct file * file) -+{ -+ int i, data; -+ -+ if(count) -+ { -+ return -EBUSY; -+ } -+ -+ count ++; -+ for(i=0; i<NR_BUTTONS; i++) -+ buttonevent.button_buffer[i] = 0; -+ buttonevent.head = 0; -+ buttonevent.tail = 0; -+ -+ init_timer (&lockscreen_timer); -+ lockscreen_timer.function = scan_lockscreen_button; -+ init_timer (&answer_timer); -+ answer_timer.function = scan_answer_button; -+ GAFR(GPIO_FLIP_PIN) &= ~(3<<(2*(GPIO_bit(GPIO_FLIP_PIN) & 0xf))); -+ GPDR(GPIO_FLIP_PIN) |= GPIO_bit(GPIO_FLIP_PIN); -+ udelay(10); -+ set_GPIO_IRQ_edge(GPIO_FLIP_PIN, GPIO_FALLING_EDGE | GPIO_RISING_EDGE); -+ if (request_irq (IRQ_GPIO(GPIO_FLIP_PIN), lockscreen_handler, SA_INTERRUPT, "flip", NULL)) -+ { -+ printk (KERN_WARNING "flip irq is free.\n"); -+ return -EIO; -+ } -+ -+ ssp_pcap_open(SSP_PCAP_AUDIO_OPEN); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_A1I); /* clear interrupt */ -+ udelay(10); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_MSR_A1M); /* unmask interrupt */ -+ data = SSP_PCAP_get_bit_from_PCAP(SSP_PCAP_ADJ_BIT_PSTAT_A1SNS); -+ if(data) -+ { -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_TX_AUD_AMPS_MB_ON2); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_ISR_MB2I); -+ udelay(10); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_MSR_MB2M); -+ } -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, button_pm_callback); -+#endif -+ -+#ifdef DEBUG -+ printk("button device opened\n"); -+#endif -+ -+#ifdef CONFIG_KEYPAD_E680 -+ data = GPLR(GPIO_FLIP_PIN) & GPIO_bit(GPIO_FLIP_PIN); -+ if(!data) -+ ssp_pcap_screenlock_lock(0); -+#endif -+ -+ first_open = 1; -+ return 0; -+} -+ -+/* add button_ioctl to check flip status */ -+static struct file_operations button_fops = { -+ owner: THIS_MODULE, -+ open: button_open, -+ release: button_release, -+ read: button_read, -+ poll: button_poll, -+ ioctl: button_ioctl, -+}; -+ -+/* -+ * This structure is the misc device structure, which specifies the minor -+ * device number (158 in this case), the name of the device (for /proc/misc), -+ * and the address of the above file operations structure. -+ */ -+ -+static struct miscdevice button_misc_device = { -+ BUTTON_MINOR, -+ "button", -+ &button_fops, -+}; -+ -+/* -+ * This function is called to initialise the driver, either from misc.c at -+ * bootup if the driver is compiled into the kernel, or from init_module -+ * below at module insert time. It attempts to register the device node -+ * and the IRQ and fails with a warning message if either fails, though -+ * neither ever should because the device number and IRQ are unique to -+ * this driver. -+ */ -+ -+static int __init button_init(void) -+{ -+ if (misc_register (&button_misc_device)) { -+ printk (KERN_WARNING "button: Couldn't register device 10, " -+ "%d.\n", BUTTON_MINOR); -+ return -EBUSY; -+ } -+} -+ -+static void __exit button_exit (void) -+{ -+ misc_deregister(&button_misc_device); -+} -+ -+module_init(button_init); -+module_exit(button_exit); -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-button.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-button.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,84 @@ -+/* -+ * linux/drivers/char/ezx-button.h -+ * author: zhouqiong -+ * company: Motorola BJDC -+ * date: 11/6/2002 -+ */ -+/* modified by zq, Jan 15,2003 -+ * (1) add flip status ioctl definition -+ */ -+#include <linux/ioctl.h> -+ -+/* Various defines: */ -+#define BUTTON_DELAY 1 /* How many jiffies to wait */ -+#define BUTTON_INTERVAL 10 /* How many jiffies to interval */ -+#define VERSION "0.1" /* Driver version number */ -+#define BUTTON_MINOR 158 /* Major 10, Minor 158, /dev/button */ -+ -+/* single button */ -+#define FLIP 0x80 -+#define ANSWER 0x81 -+#define HEADSET_INT 0x82 -+#define EMU_CHARGER_500mA 0x83 -+#define EMU_USB 0x84 -+#define EMU_CHARGER_0 0x85 -+ -+#define NR_BUTTONS 256 -+ -+#define BUTTON_IOCTL_BASE 0xde -+#define BUTTON_GET_FLIPSTATUS _IOR(BUTTON_IOCTL_BASE, 1,int) -+#define BUTTON_GET_HEADSETSTATUS _IOR(BUTTON_IOCTL_BASE, 2,int) -+#define BUTTON_GET_EMU_CABLE _IOR(BUTTON_IOCTL_BASE, 3,int) -+#define BUTTON_GET_EMU_CHARGER _IOR(BUTTON_IOCTL_BASE, 4,int) -+#define BUTTON_USB_CABLE_IN _IOR(BUTTON_IOCTL_BASE, 5,int) -+#define BUTTON_USB_CABLE_OUT _IOR(BUTTON_IOCTL_BASE, 6,int) -+#define BUTTON_CHARGER_CAP _IOR(BUTTON_IOCTL_BASE, 7,int) -+#define BUTTON_USB_DEV_TYPE _IOR(BUTTON_IOCTL_BASE, 8,int) -+#define NR_REPEAT 5 -+#define FLIP_ON 1 -+#define FLIP_OFF 0 -+#define HEADSET_IN 0 -+#define HEADSET_OUT 1 -+#define EMU_CABLE_BEFORE 1 -+#define EMU_CHARGE_500mA_BEFORE 1 -+#define EMU_CHARGE_0mA_BEFORE 2 -+ -+#define KEYDOWN 0x8000 -+#define KEYUP 0x0000 -+//#define LOCKSCREEN 0x84 -+#define LOCKSCREEN FLIP -+//# define BUTTON_GET_LOCKSCREENSTATUS _IOR(BUTTON_IOCTL_BASE, 3,int) -+# define BUTTON_GET_LOCKSCREENSTATUS BUTTON_GET_FLIPSTATUS -+//#define LOCKSCREEN_ON 1 -+#define LOCKSCREEN_ON FLIP_OFF -+//#define LOCKSCREEN_OFF 0 -+#define LOCKSCREEN_OFF FLIP_ON -+ -+#ifndef u16 -+#define u16 unsigned short -+#endif -+/* usb cable event */ -+#define USB_CABLE_IN 0xa0 -+#define USB_CABLE_OUT 0xa1 -+#define USB_CABLE_500mA 0xa2 -+#define USB_CABLE_0mA 0xa3 -+#define NETMONITOR_CABLE 0xa4 -+#define MODEM_CABLE 0xa5 -+#define APLOG_CABLE 0xa6 -+#define CFG11_CABLE 0xa7 -+#define DSPLOG_CABLE 0xa8 -+#define USBNET_CABLE 0xa9 -+#define PST_CABLE 0xaa -+#define MASSSTORAGE_CABLE 0xab -+#define UNKNOWN_CABLE 0xff -+/*add function*/ -+extern void answer_button_handler(int irq, void *dev_id, struct pt_regs *regs); -+extern void headset_in_handler(int irq, void *dev_id, struct pt_regs *regs); -+extern void headset_out_handler(int irq, void *dev_id, struct pt_regs *regs); -+/* -+extern void emu_charger_500mA_handler(void); -+extern void emu_usb_in_handler(void); -+extern void emu_usb_out_handler(void); -+extern void emu_charger_0(void); -+*/ -+extern void usb_cable_event_handler(unsigned short cable_event); -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-emu.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-emu.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,1185 @@ -+#ifdef EMU_PIHF_FEATURE -+/* -+ * linux/drivers/misc/ezx-emu.c --- EMU driver on ezx -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Cheng Xuefeng -+ * Created: April 30, 2004 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include <linux/init.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/timer.h> -+#include <linux/fs.h> -+#include <linux/miscdevice.h> -+#include <linux/string.h> -+#include <linux/errno.h> -+#include <linux/poll.h> -+#include <linux/pm.h> -+#include <linux/delay.h> -+#include <linux/apm_bios.h> -+ -+#include <asm/hardware.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+#include <asm/semaphore.h> -+#include <asm/mach-types.h> -+#include "ssp_pcap.h" -+#include "ezx-emu.h" -+ -+#include <asm/arch/pxa-regs.h> -+#include <asm/arch/ezx.h> -+ -+#define DEBUG -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+#endif -+ -+#ifdef EMU_INTERFACE_DEBUG -+#define EMU_DBG(fmt,args...) printk("EMU:"fmt,##args); -+#else -+#define EMU_DBG(fmt,args...) -+#endif -+ -+EXPORT_SYMBOL(emu_switch_to); -+ -+extern void emu_switch_to(T_EMU_SWITCH_TO to); -+ -+#define EMU_YES (1) -+#define EMU_NO (0) -+ -+/* 1ms */ -+#define EMU_PIHF_DPLUS_INIT_INTERVAL (1) -+ -+static int emu_is_int = EMU_NO; -+static int emu_is_wait = EMU_NO; -+ -+typedef enum{ -+ EMU_USB = 0, -+ EMU_SPD, -+ EMU_PIHF, /*EMU_PIHF is a subset of EMU_SPD*/ -+ EMU_EIHF -+} T_EMU_CURRENT_DEVICE; -+ -+typedef enum{ -+ EMU_MODE_UART =0, -+ EMU_MODE_USB, -+ EMU_MODE_AUDIO_MONO, -+ EMU_MODE_AUDIO_STEREO -+} T_EMU_MODE; -+ -+static T_EMU_CURRENT_DEVICE emu_current_device = EMU_USB; -+static T_EMU_MODE emu_current_mode = EMU_MODE_USB; -+ -+static DECLARE_WAIT_QUEUE_HEAD(emu_wait_queue); /* Used for blocking read */ -+ -+static int emucount=0; -+ -+ -+static void emu_handle_int(int irq,void *dev,struct pt_regs *regs); -+ -+/* This will be export to other modules. For other feature, developer should -+ * add related T_EMU_SWITCH_TO type as requriement. -+ */ -+void emu_switch_to(T_EMU_SWITCH_TO to) -+{ -+ switch(to) -+ { -+ case EMU_SWITCH_TO_NO_DEV: -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_NO_DEV\n"); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ -+ /* Disable the PCAP transceiver both for USB and RS232 */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ -+ /* Set the Bulverde GPIO */ -+ pxa_gpio_mode(GPIO34_USB_P2_2_MD); -+ set_GPIO(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_USB_P2_1_MD); -+ pxa_gpio_mode(GPIO36_USB_P2_4_MD); -+ pxa_gpio_mode(GPIO39_USB_P2_6_MD); //pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_USB_P2_5_MD); -+ pxa_gpio_mode(GPIO53_USB_P2_3_MD); -+ break; -+ case EMU_SWITCH_TO_UART: -+ -+ /* set the PCAP as UART mode */ -+ /*SSP_PCAP_configure_USB_UART_transeiver(SSP_PCAP_SERIAL_PORT);*/ -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN)) -+ { -+ EMU_DBG("Before SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB clean\n"); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ } -+ else -+ { -+ return; -+ } -+ -+ /* This must be set. */ -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232_DIR); -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_UART:set txd high\n"); -+ set_GPIO(GPIO39_FFTXD); -+ -+ /* set other USB related GPIO direcction to IN first */ -+ pxa_gpio_mode(GPIO34_USB_P2_2_MD); -+ set_GPIO(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ -+ /* Init UART related GPIO */ -+ pxa_gpio_mode(GPIO39_FFTXD_MD); -+ pxa_gpio_mode(GPIO53_FFRXD_MD); -+ CKEN |= CKEN6_FFUART; -+ -+ /* set the MUX1/2 to data mode */ -+ clr_GPIO(GPIO_EMU_MUX1); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+ emu_current_mode = EMU_MODE_UART; -+ break; -+ case EMU_SWITCH_TO_USB: -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_USB\n"); -+ /* set the 6 USB related GPIOs as USB function*/ -+ pxa_gpio_mode(GPIO34_USB_P2_2_MD); -+ pxa_gpio_mode(GPIO35_USB_P2_1_MD); -+ pxa_gpio_mode(GPIO36_USB_P2_4_MD); -+ pxa_gpio_mode(GPIO39_USB_P2_6_MD); -+ pxa_gpio_mode(GPIO40_USB_P2_5_MD); -+ pxa_gpio_mode(GPIO53_USB_P2_3_MD); -+ UP2OCR = 0x02000000; -+ -+ /* set the PCAP as UART mode */ -+ /*SSP_PCAP_configure_USB_UART_transeiver(SSP_PCAP_HIGH_USB_PORT);*/ -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB)) -+ { -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_FSENB)) -+ { -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ } -+ } -+ -+ /* set the MUX1/2 to data mode */ -+ clr_GPIO(GPIO_EMU_MUX1); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+ emu_current_mode = EMU_MODE_USB; -+ break; -+ case EMU_SWITCH_TO_AUDIO_MONO: -+ /* This will not change the PCAP audio related -+ * register. Just change the MUX1/2. Switching -+ * the audio path is controlled by other driver. -+ */ -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_AUDIO_MONO\n"); -+ -+ clr_GPIO(GPIO39_VPOUT); -+ mdelay(1); -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); -+ set_GPIO(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ -+ /* set the MUX1/2 to mono mode */ -+ set_GPIO(GPIO_EMU_MUX1); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+ emu_current_mode = EMU_MODE_AUDIO_MONO; -+ break; -+ case EMU_SWITCH_TO_AUDIO_STEREO: -+ /* This will not change the PCAP audio related -+ * register. Just change the MUX1/2. Switching -+ * the audio path is controlled by other driver. -+ */ -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_AUDIO_STEREO\n"); -+ clr_GPIO(GPIO39_VPOUT); -+ pxa_gpio_mode(GPIO34_USB_P2_@ | GPIO_IN); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ -+ /* set the MUX1/2 to stereo mode */ -+ set_GPIO(GPIO_EMU_MUX1); -+ set_GPIO(GPIO_EMU_MUX2); -+ emu_current_mode = EMU_MODE_AUDIO_STEREO; -+ break; -+ default: -+ break; -+ } -+ return; -+} -+ -+ -+static int emu_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) -+{ -+ int ret; -+ long val; -+ -+ switch(cmd){ -+ -+ /* Switch the MUX1/2 and set the GPIOs */ -+ case EMU_SW_TO_UART: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_UART:before change\n"); -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ break; -+ -+ case EMU_SW_TO_USB: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_USB:before change\n"); -+ emu_switch_to(EMU_SWITCH_TO_USB); -+ break; -+ -+ case EMU_SW_TO_AUDIO_MONO: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_AUDIO_MONO:before change\n"); -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_MONO); -+ break; -+ -+ case EMU_SW_TO_AUDIO_STEREO: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_AUDIO_STEREO: not support...\n"); -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_STEREO); -+ break; -+ -+ case EMU_SMART_SPD_INIT: -+ -+ EMU_DBG("emu_ioctl:EMU_SPD_INIT\n"); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PD); -+ mdelay(EMU_PIHF_DPLUS_INIT_INTERVAL); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PD); -+ -+ /* init to UART mode */ -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ -+ EMU_DBG("emu_ioctl:set GPIO 86\n"); -+ /* For SNP_INT_CTL, the inactive state is low. -+ * That means the ID line is high. -+ */ -+ pxa_gpio_mode(GPIO_SNP_INT_CTL|GPIO_OUT); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ -+ EMU_DBG("emu_ioctl:before request_irq()\n"); -+ -+ udelay(10); -+ -+ set_GPIO_IRQ_edge(GPIO_SNP_INT_IN,GPIO_FALLING_EDGE|GPIO_RISING_EDGE); -+ -+ if (request_irq(IRQ_GPIO(GPIO_SNP_INT_IN),emu_handle_int, -+ SA_INTERRUPT|SA_SAMPLE_RANDOM, -+ "EMU SNP interrupt",(void*)1) -+ ) -+ { -+ printk(KERN_WARNING"can't get EMU snp_int irq\n"); -+ return -EIO; -+ } -+ -+ emu_current_device = EMU_SPD; -+ break; -+ -+ /* EMU PIHF */ -+ case EMU_PIHF_INIT: -+ EMU_DBG("%s,%s:EMU_PIHF_INIT",__FILE__,__FUNCTION__); -+ -+ /* init to UART mode */ -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ -+ emu_current_device = EMU_PIHF; -+ break; -+ case EMU_PIHF_SNP_INT_CTL: -+ EMU_DBG("emu_ioctl:got the SNP_INT_CTL...\n"); -+ /* For SNP_INT_CTL, the inactive state is low. -+ * That means the ID line is high. -+ */ -+ ret = get_user(val,(long *)arg); -+ if (ret) -+ return ret; -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ set_GPIO(GPIO_SNP_INT_CTL); -+ mdelay(val); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ break; -+ -+ case EMU_PIHF_ID_LOW: -+ EMU_DBG("emu_ioctl:EMU_PIHF_ID_LOW\n"); -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ set_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ break; -+ -+ case EMU_PIHF_ID_HIGH: -+ EMU_DBG("emu_ioctl:EMU_PIHF_ID_HIGH\n"); -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ break; -+ -+ /* EMU EIHF */ -+ case EMU_EIHF_INIT: -+ emu_current_device = EMU_EIHF; -+ break; -+ -+ case EMU_EIHF_MUTE: -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ break; -+ -+ case EMU_EIHF_UNMUTE: -+ set_GPIO(GPIO_SNP_INT_CTL); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static unsigned int emu_poll(struct file *file, poll_table *wait) -+{ -+ if (emu_is_int == EMU_NO) -+ { -+ EMU_DBG("%s,%s:emu_is_int is NO\n",__FILE__,__FUNCTION__); -+ emu_is_wait = EMU_YES; -+ poll_wait(file, &emu_wait_queue, wait); -+ } -+ else -+ { -+ EMU_DBG("%s,%s:emu_is_int is YES\n",__FILE__,__FUNCTION__); -+ emu_is_int = EMU_NO; -+ } -+ return POLLIN | POLLRDNORM; -+} -+/* -+ * This function is called when a user space program attempts to read -+ * /dev/emu. It puts the device to sleep on the wait queue until -+ * irq handler writes some data to the buffer and flushes -+ * the queue, at which point it writes the data out to the device and -+ * returns the number of characters it has written. This function is -+ * reentrant, so that many processes can be attempting to read from the -+ * device at any one time. -+ */ -+ -+static int emu_read (struct file *file, char *buffer, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ int retval = 0; -+ -+ EMU_DBG("%s,%s:enter ...\n",__FILE__,__FUNCTION__); -+ if (EMU_NO == emu_is_int) -+ { -+ EMU_DBG("%s,%s:emu_is_int is NO\n",__FILE__,__FUNCTION__); -+ add_wait_queue(&emu_wait_queue, &wait); -+ current->state = TASK_INTERRUPTIBLE; -+ -+ while (EMU_NO == emu_is_int) -+ { -+ if (file->f_flags & O_NONBLOCK) -+ { -+ retval = -EAGAIN; -+ break; -+ } -+ if (signal_pending(current)) -+ { -+ retval = -ERESTARTSYS; -+ break; -+ } -+ emu_is_wait = EMU_YES; -+ EMU_DBG("%s,%s:before schedule()\n",__FILE__,__FUNCTION__); -+ schedule(); -+ } -+ current->state = TASK_RUNNING; -+ EMU_DBG("%s,%s:after wake up\n",__FILE__,__FUNCTION__); -+ remove_wait_queue(&emu_wait_queue, &wait); -+ } -+ -+ return retval; -+} -+ -+#ifdef CONFIG_PM -+static int emu_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ EMU_DBG("emu_pm_callback\n"); -+ switch(req) -+ { -+ case PM_SUSPEND: -+ EMU_DBG("emu_pm_callback:PM_SUSPEND\n"); -+ /* Disable the PCAP transceiver both for USB and RS232 */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ -+ /* Set the Bulverde GPIO */ -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); -+ set_GPIO(GPIO34_TXENB); -+ PGSR(GPIO34_TXENB)|=GPIO_bit(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ break; -+ -+ case PM_RESUME: -+ -+ if ( emucount != 0) -+ { -+ switch ( emu_current_device) -+ { -+ case EMU_PIHF: -+ -+ EMU_DBG("emu_pm_callback:EMU_PIHF\n"); -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ -+ switch(emu_current_mode) -+ { -+ case EMU_MODE_UART: -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ break; -+ case EMU_MODE_USB: -+ emu_switch_to(EMU_SWITCH_TO_USB); -+ break; -+ case EMU_MODE_AUDIO_MONO: -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_MONO); -+ break; -+ case EMU_MODE_AUDIO_STEREO: -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_STEREO); -+ break; -+ default: -+ break; -+ } -+ break; -+ case EMU_EIHF: -+ /* Should not come here since the EIHF must have the charger. */ -+ break; -+ case EMU_USB: -+ emu_switch_to(EMU_SWITCH_TO_USB); -+ break; -+ default: -+ break; -+ } -+ } -+ break; -+ } -+ return 0; -+} -+#endif -+ -+static int emu_release(struct inode * inode, struct file * file) -+{ -+ int i; -+ -+ if ( emucount > 0) -+ emucount --; -+ -+ if(emucount) -+ { -+ return -EBUSY; -+ } -+ -+ if ( EMU_PIHF == emu_current_device) -+ free_irq(IRQ_GPIO(GPIO_SNP_INT_IN),NULL); -+ -+ EMU_DBG("emu_release:freed irq...%d\n",IRQ_GPIO(87)); -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+#ifdef DEBUG -+ EMU_DBG("emu_release:emu device released\n"); -+#endif -+ -+ return 0; -+} -+ -+static void emu_handle_int(int irq,void *dev,struct pt_regs *regs) -+{ -+ EMU_DBG("%s,%s:got the interrupt...\n",__FILE__,__FUNCTION__); -+ if ( EMU_YES == emu_is_wait ) -+ { -+ EMU_DBG("%s,%s:emu_is_wait is YES...\n",__FILE__,__FUNCTION__); -+ wake_up_interruptible(&emu_wait_queue); -+ emu_is_wait = EMU_NO; -+ } -+ else -+ { -+ EMU_DBG("%s,%s:emu_is_wait is NO...\n",__FILE__,__FUNCTION__); -+ emu_is_int = EMU_YES; -+ } -+ EMU_DBG("emu_handle_int:after wake up...\n"); -+} -+ -+static int emu_open(struct inode * inode, struct file * file) -+{ -+ int i, data; -+ int ret; -+ -+ /* emucount could only be 1 or 0 */ -+ if(emucount) -+ { -+ return -EBUSY; -+ } -+ emucount ++; -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, emu_pm_callback); -+#endif -+ EMU_DBG("emu_open:emu device opened\n"); -+ return 0; -+} -+ -+/* add emu_ioctl to check flip status */ -+static struct file_operations emu_fops = { -+ owner: THIS_MODULE, -+ open: emu_open, -+ release: emu_release, -+ read: emu_read, -+ poll: emu_poll, -+ ioctl: emu_ioctl, -+}; -+ -+/* -+ * This structure is the misc device structure, which specifies the minor -+ * device number (165 in this case), the name of the device (for /proc/misc), -+ * and the address of the above file operations structure. -+ */ -+ -+static struct miscdevice emu_misc_device = { -+ EMU_MINOR, -+ "emu", -+ &emu_fops, -+}; -+ -+/* -+ * This function is called to initialise the driver, either from misc.c at -+ * bootup if the driver is compiled into the kernel, or from init_module -+ * below at module insert time. It attempts to register the device node -+ * and the IRQ and fails with a warning message if either fails, though -+ * neither ever should because the device number and IRQ are unique to -+ * this driver. -+ */ -+ -+static int __init emu_init(void) -+{ -+ pxa_gpio_mode(GPIO_SNP_INT_IN | GPIO_IN); -+ pxa_gpio_mode(GPIO_EMU_MUX1 | GPIO_OUT); -+ pxa_gpio_mode(GPIO_EMU_MUX2 | GPIO_OUT); -+ -+ if (misc_register (&emu_misc_device)) { -+ EMU_DBG (KERN_WARNING "emu: Couldn't register device 10, " -+ "%d.\n", EMU_MINOR); -+ return -EBUSY; -+ } -+} -+ -+static void __exit emu_exit (void) -+{ -+ misc_deregister(&emu_misc_device); -+} -+ -+ -+module_init(emu_init); -+module_exit(emu_exit); -+#else /* EMU_PIHF_FEATURE */ -+ -+/* -+ * linux/drivers/misc/ezx-emu.c --- EMU driver on ezx -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Cheng Xuefeng -+ * Created: April 30, 2004 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ */ -+ -+#include <linux/init.h> -+#include <linux/config.h> -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/interrupt.h> -+#include <linux/time.h> -+#include <linux/timer.h> -+#include <linux/fs.h> -+#include <linux/miscdevice.h> -+#include <linux/string.h> -+#include <linux/errno.h> -+#include <linux/poll.h> -+#include <linux/pm.h> -+#include <linux/delay.h> -+#include <linux/apm_bios.h> -+ -+#include <asm/hardware.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+#include <asm/semaphore.h> -+#include <asm/mach-types.h> -+#include "ssp_pcap.h" -+#include "ezx-emu.h" -+ -+#include <asm/arch/pxa-regs.h> -+#include <asm/arch/ezx.h> -+ -+#define DEBUG -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+#endif -+ -+#ifdef EMU_INTERFACE_DEBUG -+#define EMU_DBG(fmt,args...) printk("EMU:"fmt,##args); -+#else -+#define EMU_DBG(fmt,args...) -+#endif -+ -+EXPORT_SYMBOL(emu_switch_to); -+ -+extern void emu_switch_to(T_EMU_SWITCH_TO to); -+ -+#define EMU_YES (0) -+#define EMU_NO (1) -+ -+/* 1ms */ -+#define EMU_PIHF_DPLUS_INIT_INTERVAL (1) -+ -+static int emu_is_int = EMU_NO; -+static int emu_is_wait = EMU_NO; -+ -+typedef enum{ -+ EMU_USB = 0, -+ EMU_PIHF, -+ EMU_EIHF -+} T_EMU_CURRENT_DEVICE; -+ -+typedef enum{ -+ EMU_MODE_UART =0, -+ EMU_MODE_USB, -+ EMU_MODE_AUDIO_MONO, -+ EMU_MODE_AUDIO_STEREO -+} T_EMU_MODE; -+ -+static T_EMU_CURRENT_DEVICE emu_current_device = EMU_USB; -+static T_EMU_MODE emu_current_mode = EMU_MODE_USB; -+ -+static DECLARE_WAIT_QUEUE_HEAD(emu_wait_queue); /* Used for blocking read */ -+ -+static int emucount=0; -+ -+ -+static void emu_handle_int(int irq,void *dev,struct pt_regs *regs); -+ -+/* This will be export to other modules. For other feature, developer should -+ * add related T_EMU_SWITCH_TO type as requriement. -+ */ -+void emu_switch_to(T_EMU_SWITCH_TO to) -+{ -+ switch(to) -+ { -+ case EMU_SWITCH_TO_NO_DEV: -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_NO_DEV\n"); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ -+ /* Disable the PCAP transceiver both for USB and RS232 */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ -+ /* Set the Bulverde GPIO */ -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); -+ set_GPIO(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ break; -+ case EMU_SWITCH_TO_UART: -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_UART\n"); -+ /* set other USB related GPIO direcction to IN first */ -+ set_GPIO(GPIO39_VPOUT); -+ -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_IN); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ -+ /* Init UART related GPIO */ -+ pxa_gpio_mode(GPIO39_FFTXD_MD); -+ pxa_gpio_mode(GPIO53_FFRXD_MD); -+ CKEN |= CKEN6_FFUART; -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_UART:set txd high\n"); -+ -+ /* set the PCAP as UART mode */ -+ /*SSP_PCAP_configure_USB_UART_transeiver(SSP_PCAP_SERIAL_PORT);*/ -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN)) -+ { -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ } -+ else -+ { -+ return; -+ } -+ -+ /* set the MUX1/2 to data mode */ -+ clr_GPIO(GPIO_EMU_MUX1); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+ emu_current_mode = EMU_MODE_UART; -+ break; -+ case EMU_SWITCH_TO_USB: -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_USB\n"); -+ /* set the 6 USB related GPIOs as USB function*/ -+ pxa_gpio_mode(GPIO34_USB_P2_2_MD); -+ pxa_gpio_mode(GPIO35_XRXD_MD); -+ pxa_gpio_mode(GPIO36_VMOUT_MD); -+ pxa_gpio_mode(GPIO39_VPOUT_MD); -+ pxa_gpio_mode(GPIO40_VPIN_MD); -+ pxa_gpio_mode(GPIO53_VMIN_MD); -+ UP2OCR = 0x02000000; -+ -+ /* set the PCAP as UART mode */ -+ /*SSP_PCAP_configure_USB_UART_transeiver(SSP_PCAP_HIGH_USB_PORT);*/ -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB)) -+ { -+ if(SSP_PCAP_SUCCESS == SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_FSENB)) -+ { -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ } -+ } -+ -+ /* set the MUX1/2 to data mode */ -+ clr_GPIO(GPIO_EMU_MUX1); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+ emu_current_mode = EMU_MODE_USB; -+ break; -+ case EMU_SWITCH_TO_AUDIO_MONO: -+ /* This will not change the PCAP audio related -+ * register. Just change the MUX1/2. Switching -+ * the audio path is controlled by other driver. -+ */ -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_AUDIO_MONO\n"); -+ -+ clr_GPIO(GPIO39_VPOUT); -+ mdelay(1); -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); -+ set_GPIO(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ -+ /* set the MUX1/2 to mono mode */ -+ set_GPIO(GPIO_EMU_MUX1); -+ clr_GPIO(GPIO_EMU_MUX2); -+ -+ emu_current_mode = EMU_MODE_AUDIO_MONO; -+ break; -+ case EMU_SWITCH_TO_AUDIO_STEREO: -+ /* This will not change the PCAP audio related -+ * register. Just change the MUX1/2. Switching -+ * the audio path is controlled by other driver. -+ */ -+ EMU_DBG("emu_switch_to:EMU_SWITCH_TO_AUDIO_STEREO\n"); -+ clr_GPIO(GPIO39_VPOUT); -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); -+ set_GPIO(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ -+ /* set the MUX1/2 to stereo mode */ -+ set_GPIO(GPIO_EMU_MUX1); -+ set_GPIO(GPIO_EMU_MUX2); -+ emu_current_mode = EMU_MODE_AUDIO_STEREO; -+ break; -+ default: -+ break; -+ } -+ return; -+} -+ -+ -+static int emu_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) -+{ -+ int ret; -+ long val; -+ -+ switch(cmd){ -+ -+ /* Switch the MUX1/2 and set the GPIOs */ -+ case EMU_SW_TO_UART: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_UART:before change\n"); -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ break; -+ -+ case EMU_SW_TO_USB: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_USB:before change\n"); -+ emu_switch_to(EMU_SWITCH_TO_USB); -+ break; -+ -+ case EMU_SW_TO_AUDIO_MONO: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_AUDIO_MONO:before change\n"); -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_MONO); -+ break; -+ -+ case EMU_SW_TO_AUDIO_STEREO: -+ EMU_DBG("emu_ioctl:EMU_SW_TO_AUDIO_STEREO: not support...\n"); -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_STEREO); -+ break; -+ -+ /* EMU PIHF */ -+ case EMU_PIHF_INIT: -+ EMU_DBG("%s,%s:EMU_PIHF_INIT",__FILE__,__FUNCTION__); -+ -+ /* init to UART mode */ -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ -+ EMU_DBG("emu_ioctl:set GPIO 86\n"); -+ /* For SNP_INT_CTL, the inactive state is low. -+ * That means the ID line is high. -+ */ -+ pxa_gpio_mode(GPIO_SNP_INT_CTL|GPIO_OUT); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ -+ EMU_DBG("emu_ioctl:before request_irq()\n"); -+ -+ udelay(10); -+ -+ set_GPIO_IRQ_edge(GPIO_SNP_INT_IN,GPIO_FALLING_EDGE|GPIO_RISING_EDGE); -+ -+#if 0 -+ if(GPLR(GPIO_SNP_INT_IN) & GPIO_bit(GPIO_SNP_INT_IN)) -+ { -+ EMU_DBG("emu_ioctl:87 is high\n"); -+ } -+ else -+ { -+ EMU_DBG("emu_ioctl:87 is low\n"); -+ } -+#endif -+ -+ if (request_irq(IRQ_GPIO(GPIO_SNP_INT_IN),emu_handle_int, -+ SA_INTERRUPT|SA_SAMPLE_RANDOM, -+ "EMU SNP interrupt",(void*)1) -+ ) -+ { -+ printk(KERN_WARNING"can't get EMU snp_int irq\n"); -+ return -EIO; -+ } -+ -+ emu_current_device = EMU_PIHF; -+ break; -+ case EMU_PIHF_SNP_INT_CTL: -+ EMU_DBG("emu_ioctl:got the SNP_INT_CTL...\n"); -+ /* For SNP_INT_CTL, the inactive state is low. -+ * That means the ID line is high. -+ */ -+ ret = get_user(val,(long *)arg); -+ if (ret) -+ return ret; -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ set_GPIO(GPIO_SNP_INT_CTL); -+ mdelay(val); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ break; -+ -+ case EMU_PIHF_ID_LOW: -+ EMU_DBG("emu_ioctl:EMU_PIHF_ID_LOW\n"); -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ set_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ break; -+ -+ case EMU_PIHF_ID_HIGH: -+ EMU_DBG("emu_ioctl:EMU_PIHF_ID_HIGH\n"); -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ break; -+ -+ case EMU_PIHF_INIT_DPLUS_CTL: -+ EMU_DBG("emu_ioctl:EMU_PIHF_INIT_DPLUS_CTL\n"); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PU); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PD); -+ mdelay(EMU_PIHF_DPLUS_INIT_INTERVAL); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_USB_PD); -+ break; -+ -+ /* EMU EIHF */ -+ case EMU_EIHF_INIT: -+ emu_current_device = EMU_EIHF; -+ break; -+ -+ case EMU_EIHF_MUTE: -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ break; -+ -+ case EMU_EIHF_UNMUTE: -+ set_GPIO(GPIO_SNP_INT_CTL); -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static unsigned int emu_poll(struct file *file, poll_table *wait) -+{ -+ if (emu_is_int == EMU_NO) -+ { -+ emu_is_wait = EMU_YES; -+ poll_wait(file, &emu_wait_queue, wait); -+ } -+ else -+ { -+ emu_is_int = EMU_NO; -+ } -+ return POLLIN | POLLRDNORM; -+} -+/* -+ * This function is called when a user space program attempts to read -+ * /dev/emu. It puts the device to sleep on the wait queue until -+ * irq handler writes some data to the buffer and flushes -+ * the queue, at which point it writes the data out to the device and -+ * returns the number of characters it has written. This function is -+ * reentrant, so that many processes can be attempting to read from the -+ * device at any one time. -+ */ -+ -+static int emu_read (struct file *file, char *buffer, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ int retval = 0; -+ -+ if (EMU_NO == emu_is_int) -+ { -+ add_wait_queue(&emu_wait_queue, &wait); -+ current->state = TASK_INTERRUPTIBLE; -+ -+ while (EMU_NO == emu_is_int) -+ { -+ if (file->f_flags & O_NONBLOCK) -+ { -+ retval = -EAGAIN; -+ break; -+ } -+ if (signal_pending(current)) -+ { -+ retval = -ERESTARTSYS; -+ break; -+ } -+ emu_is_wait = EMU_YES; -+ schedule(); -+ } -+ current->state = TASK_RUNNING; -+ remove_wait_queue(&emu_wait_queue, &wait); -+ } -+ -+ return retval; -+} -+ -+#ifdef CONFIG_PM -+static int emu_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ EMU_DBG("emu_pm_callback\n"); -+ switch(req) -+ { -+ case PM_SUSPEND: -+ EMU_DBG("emu_pm_callback:PM_SUSPEND\n"); -+ /* Disable the PCAP transceiver both for USB and RS232 */ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_BUSCTRL_VUSB_EN); -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_BUSCTRL_RS232ENB); -+ -+ /* Set the Bulverde GPIO */ -+ pxa_gpio_mode(GPIO34_TXENB | GPIO_OUT); -+ set_GPIO(GPIO34_TXENB); -+ PGSR(GPIO34_TXENB)|=GPIO_bit(GPIO34_TXENB); -+ pxa_gpio_mode(GPIO35_XRXD | GPIO_IN); -+ pxa_gpio_mode(GPIO36_VMOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO39_VPOUT | GPIO_IN); -+ pxa_gpio_mode(GPIO40_VPIN | GPIO_IN); -+ pxa_gpio_mode(GPIO53_VMIN | GPIO_IN); -+ break; -+ -+ case PM_RESUME: -+ -+ if ( emucount != 0) -+ { -+ switch ( emu_current_device) -+ { -+ case EMU_PIHF: -+ -+ EMU_DBG("emu_pm_callback:EMU_PIHF\n"); -+ disable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ clr_GPIO(GPIO_SNP_INT_CTL); -+ enable_irq(IRQ_GPIO(GPIO_SNP_INT_IN)); -+ -+ switch(emu_current_mode) -+ { -+ case EMU_MODE_UART: -+ emu_switch_to(EMU_SWITCH_TO_UART); -+ break; -+ case EMU_MODE_USB: -+ emu_switch_to(EMU_SWITCH_TO_USB); -+ break; -+ case EMU_MODE_AUDIO_MONO: -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_MONO); -+ break; -+ case EMU_MODE_AUDIO_STEREO: -+ emu_switch_to(EMU_SWITCH_TO_AUDIO_STEREO); -+ break; -+ default: -+ break; -+ } -+ break; -+ case EMU_EIHF: -+ /* Should not come here since the EIHF must have the charger. */ -+ break; -+ case EMU_USB: -+ emu_switch_to(EMU_SWITCH_TO_USB); -+ break; -+ default: -+ break; -+ } -+ } -+ break; -+ } -+ return 0; -+} -+#endif -+ -+static int emu_release(struct inode * inode, struct file * file) -+{ -+ int i; -+ -+ if ( emucount > 0) -+ emucount --; -+ -+ if(emucount) -+ { -+ return -EBUSY; -+ } -+ -+ if ( EMU_PIHF == emu_current_device) -+ free_irq(IRQ_GPIO(GPIO_SNP_INT_IN),NULL); -+ -+ EMU_DBG("emu_release:freed irq...%d\n",IRQ_GPIO(87)); -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+#ifdef DEBUG -+ EMU_DBG("emu_release:emu device released\n"); -+#endif -+ -+ return 0; -+} -+ -+static void emu_handle_int(int irq,void *dev,struct pt_regs *regs) -+{ -+ EMU_DBG("emu_handle_int:got the interrupt...\n"); -+ if ( EMU_YES == emu_is_wait ) -+ { -+ wake_up_interruptible(&emu_wait_queue); -+ emu_is_wait = EMU_NO; -+ } -+ else -+ { -+ emu_is_int = EMU_YES; -+ } -+ EMU_DBG("emu_handle_int:after wake up...\n"); -+} -+ -+static int emu_open(struct inode * inode, struct file * file) -+{ -+ int i, data; -+ int ret; -+ -+ /* emucount could only be 1 or 0 */ -+ if(emucount) -+ { -+ return -EBUSY; -+ } -+ emucount ++; -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, emu_pm_callback); -+#endif -+ EMU_DBG("emu_open:emu device opened\n"); -+ return 0; -+} -+ -+/* add emu_ioctl to check flip status */ -+static struct file_operations emu_fops = { -+ owner: THIS_MODULE, -+ open: emu_open, -+ release: emu_release, -+ read: emu_read, -+ poll: emu_poll, -+ ioctl: emu_ioctl, -+}; -+ -+/* -+ * This structure is the misc device structure, which specifies the minor -+ * device number (165 in this case), the name of the device (for /proc/misc), -+ * and the address of the above file operations structure. -+ */ -+ -+static struct miscdevice emu_misc_device = { -+ EMU_MINOR, -+ "emu", -+ &emu_fops, -+}; -+ -+/* -+ * This function is called to initialise the driver, either from misc.c at -+ * bootup if the driver is compiled into the kernel, or from init_module -+ * below at module insert time. It attempts to register the device node -+ * and the IRQ and fails with a warning message if either fails, though -+ * neither ever should because the device number and IRQ are unique to -+ * this driver. -+ */ -+ -+static int __init emu_init(void) -+{ -+ pxa_gpio_mode(GPIO_SNP_INT_IN | GPIO_IN); -+ -+ if (misc_register (&emu_misc_device)) { -+ EMU_DBG (KERN_WARNING "emu: Couldn't register device 10, " -+ "%d.\n", EMU_MINOR); -+ return -EBUSY; -+ } -+} -+ -+static void __exit emu_exit (void) -+{ -+ misc_deregister(&emu_misc_device); -+} -+ -+ -+module_init(emu_init); -+module_exit(emu_exit); -+#endif /* EMU_PIHF_FEATURE */ -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-emu.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-emu.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,93 @@ -+#ifdef EMU_PIHF_FEATURE -+/* -+ * linux/drivers/emu/ezx-emu.h -+ * author: Cheng Xuefeng -+ * company: Motorola Inc. -+ * date: 30/4/2004 -+ */ -+#include <linux/ioctl.h> -+ -+/* Various defines: */ -+#define VERSION "0.1" /* Driver version number */ -+#define EMU_MINOR 250 /* Major 10, Minor 250, /dev/emu */ -+ -+/* single button */ -+ -+#define EMU_IOCTL_BASE 0xdf -+ -+/* Switch the Mux1/2 and set the GPIOs */ -+#define EMU_SW_TO_UART _IO(EMU_IOCTL_BASE, 1) -+#define EMU_SW_TO_USB _IO(EMU_IOCTL_BASE, 2) -+#define EMU_SW_TO_AUDIO_MONO _IO(EMU_IOCTL_BASE, 3) -+#define EMU_SW_TO_AUDIO_STEREO _IO(EMU_IOCTL_BASE, 4) -+#define EMU_SMART_SPD_INIT _IO(EMU_IOCTL_BASE, 5) -+ -+/* EMU PIHF */ -+#define EMU_PIHF_INIT _IOW(EMU_IOCTL_BASE, 21,int) -+/*#define EMU_PIHF_GET_STATUS _IOR(EMU_IOCTL_BASE, 12,int)*/ -+#define EMU_PIHF_SNP_INT_CTL _IOR(EMU_IOCTL_BASE, 23,int) -+#define EMU_PIHF_ID_LOW _IO(EMU_IOCTL_BASE, 24) -+#define EMU_PIHF_ID_HIGH _IO(EMU_IOCTL_BASE, 25) -+ -+/* EMU EIHF */ -+#define EMU_EIHF_INIT _IOW(EMU_IOCTL_BASE, 31,int) -+#define EMU_EIHF_MUTE _IO(EMU_IOCTL_BASE, 32) -+#define EMU_EIHF_UNMUTE _IO(EMU_IOCTL_BASE, 33) -+ -+typedef enum{ -+ EMU_SWITCH_TO_UART = 0, -+ EMU_SWITCH_TO_USB, -+ EMU_SWITCH_TO_AUDIO_MONO, -+ EMU_SWITCH_TO_AUDIO_STEREO, -+ EMU_SWITCH_TO_NO_DEV -+} T_EMU_SWITCH_TO; -+ -+void emu_switch_to(T_EMU_SWITCH_TO to); -+ -+#else /* EMU_PIHF_FEATURE */ -+ -+/* -+ * linux/drivers/emu/ezx-emu.h -+ * author: Cheng Xuefeng -+ * company: Motorola Inc. -+ * date: 30/4/2004 -+ */ -+#include <linux/ioctl.h> -+ -+/* Various defines: */ -+#define VERSION "0.1" /* Driver version number */ -+#define EMU_MINOR 250 /* Major 10, Minor 250, /dev/emu */ -+ -+/* single button */ -+ -+#define EMU_IOCTL_BASE 0xdf -+ -+/* Switch the Mux1/2 and set the GPIOs */ -+#define EMU_SW_TO_UART _IO(EMU_IOCTL_BASE, 1) -+#define EMU_SW_TO_USB _IO(EMU_IOCTL_BASE, 2) -+#define EMU_SW_TO_AUDIO_MONO _IO(EMU_IOCTL_BASE, 3) -+#define EMU_SW_TO_AUDIO_STEREO _IO(EMU_IOCTL_BASE, 4) -+ -+/* EMU PIHF */ -+#define EMU_PIHF_INIT _IOW(EMU_IOCTL_BASE, 21,int) -+/*#define EMU_PIHF_GET_STATUS _IOR(EMU_IOCTL_BASE, 12,int)*/ -+#define EMU_PIHF_SNP_INT_CTL _IOR(EMU_IOCTL_BASE, 23,int) -+#define EMU_PIHF_ID_LOW _IO(EMU_IOCTL_BASE, 24) -+#define EMU_PIHF_ID_HIGH _IO(EMU_IOCTL_BASE, 25) -+#define EMU_PIHF_INIT_DPLUS_CTL _IO(EMU_IOCTL_BASE, 26) -+ -+/* EMU EIHF */ -+#define EMU_EIHF_INIT _IOW(EMU_IOCTL_BASE, 31,int) -+#define EMU_EIHF_MUTE _IO(EMU_IOCTL_BASE, 32) -+#define EMU_EIHF_UNMUTE _IO(EMU_IOCTL_BASE, 33) -+ -+typedef enum{ -+ EMU_SWITCH_TO_UART = 0, -+ EMU_SWITCH_TO_USB, -+ EMU_SWITCH_TO_AUDIO_MONO, -+ EMU_SWITCH_TO_AUDIO_STEREO, -+ EMU_SWITCH_TO_NO_DEV -+} T_EMU_SWITCH_TO; -+ -+void emu_switch_to(T_EMU_SWITCH_TO to); -+#endif /* EMU_PIHF_FEATURE */ -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-log.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-log.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,183 @@ -+/* -+ * Kernel panic log interface for Linux on A760(XScale PXA262). -+ * -+ * Copyright (c) 2000 Motorola -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * 0.01 2003-07-01 zxf <w19962@motorola.com> -+ * - initial release -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/mtd/mtd.h> -+ -+#include <asm/io.h> -+#include <asm/uaccess.h> -+ -+#include "log.h" -+ -+#define A760_LOG_NAME "A760" -+#define A760_LOG_START 0x01fc0000 -+#define A760_LOG_SIZE 0x00020000 -+ -+#define E680_LOG_NAME "E680" -+#define E680_LOG_START 0x01fc0000 -+#define E680_LOG_SIZE 0x00020000 -+ -+#define A780_LOG_NAME "A780" -+#define A780_LOG_START 0x01fc0000 -+#define A780_LOG_SIZE 0x00020000 -+ -+#ifdef CONFIG_ARCH_EZX_E680 -+#define LOG_NAME E680_LOG_NAME -+#define LOG_START E680_LOG_START -+#define LOG_SIZE E680_LOG_SIZE -+#elif CONFIG_ARCH_EZX_A780 -+#define LOG_NAME A780_LOG_NAME -+#define LOG_START A780_LOG_START -+#define LOG_SIZE A780_LOG_SIZE -+#else -+#define LOG_NAME A760_LOG_NAME -+#define LOG_START A760_LOG_START -+#define LOG_SIZE A760_LOG_SIZE -+#endif -+ -+static ssize_t log_read(const char *buf, size_t count, loff_t *ppos); -+static ssize_t log_write(const char *buf, size_t count); -+ -+static struct log_area flash_log = { -+ name: LOG_NAME, //"A760", -+ start: LOG_START, // LOGO_ADDR is 0x01fc0000 -+ size: LOG_SIZE, -+ write: log_write, -+ read: log_read, -+}; -+ -+/* -+ * Here the read implementation should not impact mtd device. -+ * Most part of the read function is coming from mtdchar.c -+ */ -+#define MAX_KMALLOC_SIZE 0x20000 -+static ssize_t log_read(const char *buf, size_t count, loff_t *ppos) -+{ -+ struct mtd_info *mtd; -+ size_t retlen=0; -+ size_t total_retlen=0; -+ int ret=0; -+ int len; -+ char *kbuf; -+ -+ mtd = get_mtd_device(NULL, 3); -+ if (!mtd) -+ return -ENODEV; -+ -+ while (count) { -+ if (count > MAX_KMALLOC_SIZE) -+ len = MAX_KMALLOC_SIZE; -+ else -+ len = count; -+ -+ kbuf=kmalloc(len,GFP_KERNEL); -+ if (!kbuf) -+ return -ENOMEM; -+ -+ ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf); -+ if (!ret) { -+ *ppos += retlen; -+ if (copy_to_user(buf, kbuf, retlen)) { -+ kfree(kbuf); -+ return -EFAULT; -+ } -+ else -+ total_retlen += retlen; -+ -+ count -= retlen; -+ buf += retlen; -+ } -+ else { -+ kfree(kbuf); -+ return ret; -+ } -+ -+ kfree(kbuf); -+ } -+ -+ return total_retlen; -+} -+ -+static ssize_t log_write(const char *buf, size_t count) -+{ -+ int i; -+ ssize_t ret; -+ void *area; -+ unsigned short *buffer; -+ volatile unsigned short *ptr; -+ -+ //printk(KERN_EMERG "****** panic time: %d ******\n", OSCR); -+ -+ area = __ioremap(flash_log.start, flash_log.size, 0); -+ if (!area) -+ return -ENOMEM; -+ -+ ptr = (unsigned short *)area; -+ ret = count; -+ -+#define EZX_A760 -+#ifdef EZX_A760 -+ /* wait state ready */ -+ *ptr = 0x70; -+ while (!((*ptr) & 0x80)); -+ -+ /* unlock the block */ -+ *ptr = 0x60; *ptr = 0xd0; -+ while (!((*ptr) & 0x80)); -+ -+ /* erase the block */ -+ *ptr = 0x20; *ptr = 0xd0; -+ while (!((*ptr) & 0x80)); -+ -+#elif EZX_BVD -+ // bvd platform -+ // same as A760 -+#endif -+ -+ /* program the block */ -+ if(count > flash_log.size) -+ count = flash_log.size; -+ count = count / sizeof(unsigned short); /* it doesn't matter to lose a little data */ -+ buffer = (unsigned short *)buf; -+ for (i = 0; i < count; i++, ptr++) { -+ *ptr = 0x40; -+ *ptr = *buffer++; -+ while (!((*ptr) & 0x80)); -+ } -+ -+ //printk(KERN_EMERG "****** panic time: %d ******\n", OSCR); -+ __iounmap(area); -+ return ret; -+} -+ -+ -+static int __init ezxlog_init(void) -+{ -+ return log_register(&flash_log); -+} -+ -+static void __exit ezxlog_exit(void) -+{ -+ log_unregister(&flash_log); -+} -+ -+module_init(ezxlog_init); -+module_exit(ezxlog_exit); -+ -+MODULE_AUTHOR("zxf <w19962@motorola.com>"); -+MODULE_DESCRIPTION("A760 Kernel panic log interface"); -+MODULE_LICENSE("GPL"); -+EXPORT_NO_SYMBOLS; -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-ts.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-ts.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,910 @@ -+/* -+ * linux/drivers/char/ezx-ts.c -+ * -+ * Copyright (C) 2002 Lili Jiang, All Rights Reserved. -+ * -+ * -+ * June, 2002 Lili Jiang, create -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/fs.h> -+#include <linux/miscdevice.h> -+#include <linux/poll.h> -+#include <linux/smp.h> -+#include <linux/smp_lock.h> -+#include <linux/sched.h> -+#include <linux/completion.h> -+#include <linux/string.h> -+#include <linux/pm.h> -+#include <linux/config.h> -+#include <linux/fb.h> -+ -+#include <asm/semaphore.h> -+#include <asm/hardware.h> -+#include <asm/arch/irqs.h> -+#include <linux/timex.h> -+#include <linux/interrupt.h> -+ -+#include <asm/arch/pxa-regs.h> -+ -+#include "ezx-ts.h" -+#include "ssp_pcap.h" -+ -+#define DEBUG 0 /*change it when formal release*/ -+#if DEBUG -+# define TS_DPRINTK(s...) printk(s) -+#else -+# define TS_DPRINTK(s...) -+#endif -+ -+/* -+ * This structure is nonsense - millisecs is not very useful -+ * since the field size is too small. Also, we SHOULD NOT -+ * be exposing jiffies to user space directly. -+ */ -+struct ts_event { -+ u16 pressure; -+ u16 x; -+ u16 y; -+ u16 pad; -+// struct timeval stamp; -+}; -+ -+static struct timer_list ezx_ts_penup_timer; -+ -+static struct irqaction ezx_ts_custom_timer_irq = { -+ name: "ezx_ts_custom_timer", -+}; -+ -+static u8 bSetPenupTimer = 0; -+static u8 bFirstPen = 0; -+//static unsigned long penCurJiffies = 0; -+static unsigned int penSampleCount = 0; -+static u32 tspenSampleCount = 0; -+static u32 tsDiscardDataCount = 0; -+ -+typedef enum -+{ -+ PRESSURE, -+ COORDINATE -+}EZX_TS_READ_STATE; -+ -+EZX_TS_READ_STATE ezx_ts_read_state = PRESSURE; -+ -+#define TS_NR_EVENTS 128 -+/*250 //pay attention to that haed and tail is defined as u8*/ -+ -+#define TS_EDGE_MIN_LIMIT (0) /* 10 */ -+#define TS_EDGE_MAX_LIMIT (1023) -+ -+/* jiffies : 10ms, pen shake 50ms????? */ -+//#define EZX_TS_READ_MIN_SPACE 10 /*100//5*/ -+//#define EZX_TS_PENUP_TIMEOUT_MS 8 -+ -+#define EZX_TS_PENSAMPLE_TIMEOUT_MS 2 -+ //8,6 -+//#define EZX_TS_HWR_TIMEOUT_MS 2 -+ -+#define QT_ONEPEN_SAMPLES_NUM 1 -+ //3,5 -+//#define HWR_ONEPEN_SAMPLES_NUM 1 -+ -+#define CUSTOM_ONEPEN_SAMPLES_NUM 1 -+#define EZX_TS_CUSTOM_TIMEOUT_MS 12 -+ //15ms -+#define X_DIFF 85 -+#define Y_DIFF 75 -+#define MIN_X_HOLD 5 -+#define MIN_Y_HOLD 4 -+#define SAMPLE_COUNT_NOT_JUMPER 20 -+ -+typedef enum -+{ -+ EZX_PEN_NORMAL, -+ EZX_PEN_CUSTOM -+}EZX_TS_PEN_STYLE; -+ -+static EZX_TS_PEN_STYLE gPenStyle = EZX_PEN_NORMAL; -+static u8 gPenSamplesNum = QT_ONEPEN_SAMPLES_NUM; -+//static u32 gHwrTimer = EZX_TS_HWR_TIMEOUT_MS; -+static u32 gCustomTimer = EZX_TS_CUSTOM_TIMEOUT_MS; -+static u8 getPenUp = 0; -+ -+struct ezx_ts_info { -+ /*struct ucb1x00 *ucb;*/ -+ struct fasync_struct *fasync; -+ wait_queue_head_t read_wait; -+ -+ /* -+ struct semaphore irq_wait; -+ struct semaphore sem; -+ struct completion init_exit; -+ struct task_struct *rtask; -+ */ -+ u16 x_cur; /*store the current pen value read from ADC*/ -+ u16 y_cur; /*store the current pen value read from ADC */ -+ u16 cur_pressure; -+ u16 x_pre; -+ u16 y_pre; -+ u8 evt_head; -+ u8 evt_tail; -+ struct ts_event events[TS_NR_EVENTS]; /* buffer for store pen data*/ -+/* -+ int restart:1; -+ int adcsync:1; -+ -+#ifdef CONFIG_PM -+ struct pm_dev *pmdev; -+#endif -+*/ -+}; -+ -+static struct ezx_ts_info ezxts; -+ -+#define EZX_TS_SHAKE_SAMPLES 3 -+static u8 ezx_ts_shake_samples_count = 0; -+static struct ts_event ezx_ts_shake_samples[EZX_TS_SHAKE_SAMPLES]; -+ -+static int ezx_ts_init(void); -+static void ezx_ts_exit(void); -+static int ezx_ts_open(struct inode *inode, struct file * filp); -+static int ezx_ts_release(struct inode *inode, struct file *filp); -+static ssize_t ezx_ts_read(struct file* filp, char* buffer, size_t count, loff_t *ppos); -+static unsigned int ezx_ts_poll(struct file* filp, struct poll_table_struct * wait); -+static int ezx_ts_fasync(int fd, struct file* filp, int mode); -+ -+/* internal function */ -+static void ezx_ts_init_penEvent(void); -+static void ezx_ts_pen_touch_handler(void); -+static void ezx_ts_penup_timeout(unsigned long data); -+static void ezx_ts_set_timer(struct timer_list *timer, void (*timer_timeout)(unsigned long), signed long timeout); -+static void ezx_ts_check_pen_samples(void); -+static void ezx_ts_evt_add(u16 pressure, u16 x, u16 y); -+static struct ts_event ezx_ts_get_onedata(void); -+ -+/* for setup ezx ts self timer,begin */ -+static void ezx_ts_custom_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ TS_DPRINTK("ezx_ts_custom_timer_interrupt entered.jiffies: %d\n@@@\n", jiffies); -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ -+ /* clear this timer */ -+ OIER &= ~OIER_E3; -+ OSSR = OSSR_M3; /* Clear match on timer 2 */ -+} -+ -+static void ezx_ts_custom_setup_timer() -+{ -+ ezx_ts_custom_timer_irq.handler = ezx_ts_custom_timer_interrupt; -+ setup_irq(IRQ_OST3, &ezx_ts_custom_timer_irq); -+} -+ -+ -+static void ezx_ts_custom_timer_start(void) -+{ -+ OIER |= OIER_E3; -+ //OSMR2 = OSCR + sleep_limit * LATCH; //OSCR: 0x40A00010 -+ OSMR3 = OSCR + (gCustomTimer * HZ * LATCH) /1000; -+} -+ -+static void ezx_ts_custom_timer_stop(void) -+{ -+ OIER &= ~OIER_E3; -+ OSSR = OSSR_M3; /* Clear match on timer 2 */ -+} -+ -+/* for setup ezx ts self timer, end */ -+ -+ -+static void ezx_ts_init_penEvent(void) -+{ -+ int i; -+ -+ ezxts.x_cur = 0; -+ ezxts.y_cur = 0; -+ ezxts.x_pre = 0; -+ ezxts.y_pre = 0; -+ ezxts.cur_pressure = PEN_UP; -+ -+ for (i = 0; i < TS_NR_EVENTS; i++) -+ { -+ ezxts.events[i].pressure=(u16)0; -+ ezxts.events[i].x=(u16)0; -+ ezxts.events[i].y=(u16)0; -+ ezxts.events[i].pad=(u16)0; -+ } -+ ezxts.evt_head = 0; -+ ezxts.evt_tail = 0; -+ -+ gPenStyle = EZX_PEN_NORMAL; -+ gPenSamplesNum = QT_ONEPEN_SAMPLES_NUM; -+ //gHwrTimer = EZX_TS_HWR_TIMEOUT_MS; -+ gCustomTimer = EZX_TS_CUSTOM_TIMEOUT_MS; -+} -+ -+ -+static void ezx_ts_pen_touch_handler(void) -+{ -+ SSP_PCAP_TSI_mode_set(PCAP_TS_PRESSURE_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ ezx_ts_read_state = PRESSURE; -+ ezxts.x_pre = 0; -+ ezxts.y_pre = 0; -+ -+ TS_DPRINTK("ezx_ts pen touch handler done.\n"); -+} -+ -+static void ezx_ts_penup_timeout(unsigned long data) -+{ -+ TS_DPRINTK("@@@\nIn pen drag! jiffies: %d\n@@@\n", jiffies); -+ bSetPenupTimer = 0; -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+} -+ -+static void ezx_ts_check_pen_samples(void) -+{ -+ if ( (ezx_ts_read_state == COORDINATE) && (penSampleCount != 0 ) ) -+ { -+ int k; -+ if (penSampleCount < gPenSamplesNum) -+ { -+ for ( k = 0; k < (gPenSamplesNum - penSampleCount); k++) -+ { -+ ezx_ts_evt_add(PEN_DOWN, ezxts.x_cur, ezxts.y_cur); -+ TS_DPRINTK("ezx_ts_add_additional_samples: %d\n", k); -+ } -+ } -+ TS_DPRINTK("ezx_ts_evt_add: PEN_UP\n"); -+ //ezx_ts_evt_add(PEN_UP, 0, 0); -+ } -+ -+ if (bSetPenupTimer) -+ { -+ del_timer(&ezx_ts_penup_timer); -+ bSetPenupTimer = 0; -+ TS_DPRINTK("^^^^Delete penup timer1.\n"); -+ } -+ penSampleCount = 0; -+} -+ -+static void ezx_ts_set_timer(struct timer_list *timer, void (*timer_timeout)(unsigned long), -+ signed long timeout) -+{ -+ init_timer(timer); -+ timer->expires = timeout + jiffies; -+ timer->data = (unsigned long) current; -+ timer->function = timer_timeout; -+ -+ add_timer(timer); -+ //TS_DPRINTK("ezx_ts set timer done.\n"); -+} -+ -+static void ezx_ts_evt_add(u16 pressure, u16 x, u16 y) -+{ -+ int next_head; -+ int last_head; -+ /* if pen_up, then copy pressure=0, last_evt.x y to current evt*/ -+ -+ next_head = ezxts.evt_head + 1; -+ if (next_head == TS_NR_EVENTS) -+ { -+ next_head = 0; -+ } -+ -+ last_head = ezxts.evt_head - 1; -+ if (last_head == -1) -+ { -+ last_head = TS_NR_EVENTS - 1; -+ } -+ -+/* if (next_head != ezxts.evt_tail)*/ -+ //{ -+ if ( pressure == PEN_DOWN) -+ { -+/* if ( (penSampleCount >1) && ((penCurJiffies + EZX_TS_READ_MIN_SPACE) < jiffies)) -+ { -+ // see two ~ four data or just ignore the data except the first one???? -+ return; -+ } -+ else*/ -+ //{ -+ ezxts.events[ezxts.evt_head].pressure = pressure; -+ ezxts.events[ezxts.evt_head].x = x; -+ ezxts.events[ezxts.evt_head].y = y; -+ TS_DPRINTK("ezx_store: x: %d, y :%d, pressure: 0x%x\n", x, y, pressure); -+ //} -+ } -+ else -+ { -+ ezxts.events[ezxts.evt_head].pressure = pressure; -+ ezxts.events[ezxts.evt_head].x = ezxts.events[last_head].x; -+ ezxts.events[ezxts.evt_head].y = ezxts.events[last_head].y; -+ TS_DPRINTK("ezx_store: PEN_UP\n"); -+ } -+ //} -+// do_gettimeofday(&(ezxts.events[ezxts.evt_head].stamp)); -+ ezxts.evt_head = next_head; -+ -+ if (ezxts.evt_head == ezxts.evt_tail) -+ { -+ if ( ++ezxts.evt_tail == TS_NR_EVENTS ) -+ ezxts.evt_tail = 0; -+ } -+ -+ if (ezxts.fasync) -+ kill_fasync(&ezxts.fasync, SIGIO, POLL_IN); -+ wake_up_interruptible(&ezxts.read_wait); -+} -+ -+static struct ts_event ezx_ts_get_onedata(void) -+{ -+ int cur = ezxts.evt_tail; -+ -+ if (++ezxts.evt_tail == TS_NR_EVENTS) -+ ezxts.evt_tail = 0; -+ -+ return ezxts.events[cur]; -+} -+ -+/***************************************************************************** -+ * FUNCTION NAME : ezx_ts_open() -+ * -+ * INPUTS: -+ * -+ * OUTPUTS: pen info from ts event structure -+ * -+ * VALUE RETURNED: none -+ * -+ * DESCRIPTION: -+ * i) Increase this device module used count. -+ * ii) Initialize a buffer for store data read from touch screen interface. -+ * iii) Initialize touch screen interface hardware. -+ * iv) Setup touch screen wait queue. -+***************************************************************************** -+ */ -+static int ezx_ts_open(struct inode *inode, struct file * filp) -+{ -+ struct ezx_ts_info *ts = &ezxts; -+ -+/* ssp_pcap_init(); // change to _start_kernel -+ ssp_pcap_open(); */ -+ ssp_pcap_open(SSP_PCAP_TS_OPEN); -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ -+ ezx_ts_init_penEvent(); -+ filp->private_data = ts; -+ -+ -+ TS_DPRINTK("ezx touch screen driver opened\n"); -+ return 0; -+} -+ -+/* Decrease this device module used count. */ -+static int ezx_ts_release(struct inode *inode, struct file *filp) -+{ -+ ezx_ts_init_penEvent(); -+ ezx_ts_fasync(-1, filp, 0); -+ -+ TS_DPRINTK("ezx touch screen driver closed\n"); -+ return 0; -+} -+ -+/***************************************************************************** -+ * FUNCTION NAME : ezx_ts_read -+ * -+ * INPUTS: -+ * -+ * OUTPUTS: pen info from ts event structure -+ * -+ * VALUE RETURNED: none -+ * -+ * DESCRIPTION: -+ * This is used for UI app to call. -+ * If device is opened by nonblock mode then copy available data from the ts event buffer -+ * to user buffer and return the actual read data count, if device is opened by block mode -+ * and no data available then sleep until the required data count be read completed. -+ * -+ * CAUTIONS: -+ * -+ * -+ ***************************************************************************** -+ */ -+static ssize_t ezx_ts_read(struct file* filp, char* buffer, size_t count, loff_t *ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ -+ struct ezx_ts_info *ts = filp->private_data; -+ char *ptr = buffer; -+ int err = 0; -+ struct ts_event evt; -+ -+ add_wait_queue(&ts->read_wait, &wait); -+ while (count >= sizeof(struct ts_event)) -+ { -+ err = -ERESTARTSYS; -+ if (signal_pending(current)) -+ break; -+ if ((ts)->evt_head != (ts)->evt_tail) -+ { -+ evt = ezx_ts_get_onedata(); /*evt_tail pos changed in this func*/ -+ err = copy_to_user(ptr, &evt, sizeof(struct ts_event)); -+ -+ if (err) -+ break; -+ //printk("ezx_ts_read: x:%d, y:%d, pressure:0x%x\n", evt.x, evt.y, evt.pressure); -+ ptr += sizeof(struct ts_event); -+ count -= sizeof(struct ts_event); -+ continue; -+ } -+ -+ set_current_state(TASK_INTERRUPTIBLE); -+ err = -EAGAIN; -+ if (filp->f_flags & O_NONBLOCK) -+ break; -+ schedule(); -+ } -+ current->state = TASK_RUNNING; -+ remove_wait_queue(&(ts->read_wait), &wait); -+ -+ return ptr == buffer ? err : ptr - buffer; -+ -+} -+ -+/* -+This function is used in nonblock mode to determine whether it can read data from touch screen -+device without blocking. -+Call poll_wait to wait until read operation status changed then return POLLIN (flag of device can be -+read without blocking) | POLLRDNORM (flag of data is available) bit mask if there is readable data -+now. -+*/ -+ -+static unsigned int ezx_ts_poll(struct file* filp, struct poll_table_struct * wait) -+{ -+ struct ezx_ts_info *ts = filp->private_data; -+ int ret = 0; -+ -+ if ( ts != NULL) -+ { -+ TS_DPRINTK("ezx_ts_poll.\n"); -+ poll_wait(filp, &ts->read_wait, wait); -+ if (ts->evt_head != ts->evt_tail) -+ { -+ TS_DPRINTK("ezx_ts_poll: ts->evt_head != ts->evt_tail\n"); -+ ret = POLLIN | POLLRDNORM; -+ } -+ } -+ -+ return ret; -+} -+ -+/* Setup fasync queue for touch screen device. */ -+ -+static int ezx_ts_fasync(int fd, struct file* filp, int mode) -+{ -+ struct ezx_ts_info *ts = filp->private_data; -+ -+ if ( ts != NULL) -+ { -+ TS_DPRINTK("ezx_ts_fasync.\n"); -+ return fasync_helper(fd, filp, mode, &ts->fasync); -+ } -+ else return 0; -+} -+ -+static int -+ezx_ts_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg) -+{ -+ int res = 0; -+ -+ TS_DPRINTK("ezx_ts_ioctl: arg is %d\n", arg); -+ switch (cmd) { -+/* -+ case SETTONORMAL: -+ TS_DPRINTK("ezx_ts_ioctl_test: This is SETTONORMAL.\n"); -+ gPenStyle = EZX_PEN_NORMAL; -+ gPenSamplesNum = QT_ONEPEN_SAMPLES_NUM; -+ //gHwrTimer = EZX_TS_HWR_TIMEOUT_MS; -+ gCustomTimer = EZX_TS_CUSTOM_TIMEOUT_MS; -+ break; -+ -+ case SETTOHWR: -+ TS_DPRINTK("ezx_ts_ioctl_test: This is SETTOHWR.\n"); -+ gPenStyle = EZX_PEN_HWR; -+ gPenSamplesNum = HWR_ONEPEN_SAMPLES_NUM; -+ if ( (arg > 0 ) && (arg < 100) ) -+ { -+ gHwrTimer = arg; -+ TS_DPRINTK("ezx_ts_ioctl_test: gHwrTimer is %d.\n", gHwrTimer); -+ } -+ break; -+ -+ case SETTOCUSTOM: -+ TS_DPRINTK("ezx_ts_ioctl_test: This is SETTOCUSTOM.\n"); -+ gPenStyle = EZX_PEN_CUSTOM; -+ gPenSamplesNum = CUSTOM_ONEPEN_SAMPLES_NUM; -+ if ( (arg > 0 ) && (arg < 100) ) -+ { -+ gCustomTimer = arg; -+ TS_DPRINTK("ezx_ts_ioctl_test: gCustomTimer is %d.\n", gCustomTimer); -+ } -+ break; -+ case GETPENSTYLE: -+ TS_DPRINTK("ezx_ts_ioctl_test: This is GETPENSTYLE.\n"); -+ put_user(gPenStyle, (u32*)arg); -+ break; -+ default: -+ res = -EINVAL; -+*/ -+ } -+ -+ return res; -+} -+ -+/***************************************************************************** -+ * FUNCTION NAME : ezx_ts_touch_interrupt -+ * -+ * INPUTS: -+ * -+ * -+ * OUTPUTS: -+ * -+ * -+ * VALUE RETURNED: -+ * -+ * -+ * DESCRIPTION: -+ * This is touch screen touch interrupt service routine called by PCAP module when touch screen -+ * interrupt happened. First eliminate shake signal to get stable touch screen press information. -+ * Then write instruction to PCAP register to read ADC conversion value of pressed spot x,y coordinate -+ * and return. -+ * -+ * CAUTIONS: -+ * -+ * -+ * -+ ***************************************************************************** -+ */ -+void ezx_ts_touch_interrupt(int irq, void* dev_id, struct pt_regs *regs) -+{ -+ TS_DPRINTK("ezx_ts_touch_irq happened.\n"); -+ ezx_ts_shake_samples_count = 0; -+ //TS_DPRINTK("ezx_ts_touch_irq excuted.\n"); -+ ezx_ts_check_pen_samples(); -+ ezx_ts_pen_touch_handler(); -+ -+} -+ -+/***************************************************************************** -+ * FUNCTION NAME : ezx_ts_dataReadok_interrupt -+ * -+ * INPUTS: call PCAP API to read x,y -+ * -+ * OUTPUTS: Store the pen info to ts event structure -+ * -+ * VALUE RETURNED: none -+ * -+ * DESCRIPTION: -+ * This is called by PCAP module to deal with the touch screen press raw information read from ADC -+ * when ADC data conversion finished. It performs write the data to ts event buffer for user to -+ * read out. -+ * -+ * CAUTIONS: Consider pen shake -+ * -+ * -+ ***************************************************************************** -+ */ -+void ezx_ts_dataReadok_interrupt(int irq, void* dev_id, struct pt_regs *regs) -+{ -+ static u16 pressure; -+ u16 x; -+ u16 y; -+ U16 tempx,tempy; -+ -+ if (SSP_PCAP_TSI_get_XY_value(&x, &y) != SSP_PCAP_SUCCESS) -+ { -+ return; -+ } -+ /* convert x,y???? */ -+ // TS_DPRINTK( "ezx_ts_get_XY_value: x:%d, y:%d\n",x, y); -+ /* TS_DPRINTK( "\nezx_ts before convert: x:%d, y:%d\n",x, y);*/ -+ -+ if ( ezx_ts_read_state == PRESSURE) -+ { -+ if (( y >= TS_EDGE_MAX_LIMIT ) || (y <= TS_EDGE_MIN_LIMIT)) -+ { -+ TS_DPRINTK("ezx_ts_datareadok_irq: PEN_UP.\n"); -+ pressure = PEN_UP; -+ ezxts.cur_pressure = PEN_UP; -+ -+ /*ezx_ts_check_pen_samples();*/ -+ if ( getPenUp == 0 ) -+ { -+ ezx_ts_evt_add( pressure, 0, 0); -+ } -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ return; -+ } -+ else -+ { -+ TS_DPRINTK("ezx_ts_datareadok_irq: PEN_DOWN.\n"); -+ getPenUp = 0; -+ pressure = PEN_DOWN; -+ ezxts.cur_pressure = PEN_DOWN; -+ tspenSampleCount = 0; -+ ezxts.x_pre = 0; -+ ezxts.y_pre = 0; -+ bFirstPen = 1 ; -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ ezx_ts_read_state = COORDINATE; -+ -+ //TS_DPRINTK("ezx_ts_datareadok_irq: Begin read XY.\n"); -+ return; -+ } -+ } -+ else if ( ezx_ts_read_state == COORDINATE) -+ {/* -+ u8 count; -+ -+ count = 0; -+ while ( (( x <= TS_EDGE_MIN_LIMIT)||( x >= TS_EDGE_MAX_LIMIT) || -+ ( y <= TS_EDGE_MIN_LIMIT)||( y >= TS_EDGE_MAX_LIMIT)) -+ && (count++ < 15) ) -+ { -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ } -+ */ -+ if ( ( x <= TS_EDGE_MIN_LIMIT)||( x >= TS_EDGE_MAX_LIMIT) || -+ ( y <= TS_EDGE_MIN_LIMIT)||( y >= TS_EDGE_MAX_LIMIT) ) -+ { /* regard it as PEN_UP */ -+ pressure = PEN_UP; -+ ezxts.cur_pressure = PEN_UP; -+ x = 0; -+ y = 0; -+ tspenSampleCount = 0; -+ SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM); -+ /*del_timer(&ezx_ts_read_timer);*/ -+ ezx_ts_check_pen_samples(); -+ ezx_ts_evt_add( pressure, 0, 0); -+ /* SSP_PCAP_bit_clean( SSP_PCAP_ADJ_BIT_MSR_TSM);*/ -+ ezx_ts_read_state = PRESSURE; -+ getPenUp = 1; -+ TS_DPRINTK( "ezx_ts Invalid x,y position: PEN_UP?\n"); -+ return; -+ } -+ getPenUp = 0; -+ penSampleCount++; -+ //TS_DPRINTK("ezx_ts_datareadok_irq: Begin store XY %d.\n", penSampleCount); -+ -+ if ( gPenStyle == EZX_PEN_CUSTOM ) -+ { -+ if ( ((ezxts.x_pre == 0) && (ezxts.y_pre == 0)) -+ || ( (ezxts.x_pre != 0) && (ezxts.y_pre != 0) -+ &&(!((abs(ezxts.x_pre - x) > X_DIFF) || (abs(ezxts.y_pre - y) > Y_DIFF))) ) -+ ) -+ { -+ //TS_DPRINTK("ezx_ts_datareadok_irq: diff <= XY_DIFF.\n"); -+ -+ ezxts.x_pre = x; -+ ezxts.y_pre = y; -+ -+ TS_DPRINTK("ezx_ts_datareadok_irq:x_pre=%d,y_pre=%d\n", ezxts.x_pre, ezxts.y_pre); -+ ezxts.x_cur = x; -+ ezxts.y_cur = y; -+ ezx_ts_evt_add(pressure, ezxts.x_cur, ezxts.y_cur); -+ //printk("ezx_ts_datareadok_irq_custom add pressure0x%x,x_cur%d,y_cur%d\n",pressure,ezxts.x_cur,ezxts.y_cur); -+ ezx_ts_custom_timer_start(); -+ } -+ else -+ { -+ //TS_DPRINTK("ezx_ts_datareadok_irq: DIFF > XY_DIFF\n"); -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ TS_DPRINTK("ezx_ts_datareadok_irq:x_pre=%d,y_pre=%d, x=%d,y=%d\n", ezxts.x_pre, ezxts.y_pre,x,y); -+ } -+ -+ -+ /* -+ if ( ezx_ts_shake_samples_count < EZX_TS_SHAKE_SAMPLES ) -+ { -+ ezx_ts_shake_samples[ezx_ts_shake_samples_count].x = x; -+ ezx_ts_shake_samples[ezx_ts_shake_samples_count].y = y; -+ ezx_ts_shake_samples[ezx_ts_shake_samples_count++].pressure = PEN_DOWN; -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ TS_DPRINTK("ezx_ts_read_shake_samples%d:x=%d,y=%d\n", ezx_ts_shake_samples_count,x,y); -+ } -+ if (ezx_ts_shake_samples_count >= EZX_TS_SHAKE_SAMPLES) -+ { -+ if ( (abs(ezx_ts_shake_samples[0].x - ezx_ts_shake_samples[1].x) > X_DIFF) || -+ (abs(ezx_ts_shake_samples[0].y - ezx_ts_shake_samples[1].y) > Y_DIFF) || -+ (abs(ezx_ts_shake_samples[1].x - ezx_ts_shake_samples[2].x) > X_DIFF) || -+ (abs(ezx_ts_shake_samples[1].y - ezx_ts_shake_samples[2].y) > Y_DIFF) -+ ) -+ { -+ // throw these data and re-read -+ ezx_ts_shake_samples_count = 0; -+ } -+ else //save to ts_event queue -+ { -+ ezxts.x_pre = ezxts.x_cur; -+ ezxts.y_pre = ezxts.y_cur; -+ TS_DPRINTK("ezx_ts_datareadok_irq:x_pre=%d,y_pre=%d\n", ezxts.x_pre, ezxts.y_pre); -+ ezxts.x_cur = (ezx_ts_shake_samples[0].x + ezx_ts_shake_samples[1].x + ezx_ts_shake_samples[2].x) / 3; -+ ezxts.y_cur = (ezx_ts_shake_samples[0].y + ezx_ts_shake_samples[1].y + ezx_ts_shake_samples[2].y) / 3;; -+ ezx_ts_shake_samples_count = 0; -+ ezx_ts_evt_add(pressure, ezxts.x_cur, ezxts.y_cur); -+ } -+ ezx_ts_custom_timer_start(); -+ } -+ */ -+ } -+ else -+ { -+ /* ezxts.x_pre and ezxts.y_pre store the last position */ -+ tspenSampleCount ++; -+ if(1 == tspenSampleCount) -+ { -+ ezxts.x_cur = x; -+ ezxts.y_cur = y; -+ if( 0 == bSetPenupTimer ) -+ { -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ } -+ } -+ else if (2 == tspenSampleCount) -+ { -+ tspenSampleCount = 0; -+ -+ tempx = (ezxts.x_cur > x? ezxts.x_cur - x:x - ezxts.x_cur); -+ tempy = (ezxts.y_cur > y? ezxts.y_cur - y:y - ezxts.y_cur); -+ if(tempx <= X_DIFF && tempy <= Y_DIFF ) -+ { -+ x = (x+ezxts.x_cur)/2; -+ y = (y+ezxts.y_cur)/2; -+ if( 1 == bFirstPen) -+ { -+ bFirstPen = 0; -+ ezxts.x_pre = x; -+ ezxts.y_pre = y; -+ } -+ tempx = ( ezxts.x_pre > x? ezxts.x_pre -x:x - ezxts.x_pre); -+ tempy = ( ezxts.y_pre > y? ezxts.y_pre -y:y - ezxts.y_pre); -+ if(tempx <= X_DIFF && tempy <= Y_DIFF ) -+ { -+ tsDiscardDataCount = 0; -+ if(tempx > MIN_X_HOLD || tempy > MIN_Y_HOLD) -+ { -+ ezxts.x_pre = x; -+ ezxts.y_pre = y; -+ } -+ ezx_ts_evt_add(pressure, ezxts.x_pre, ezxts.y_pre); -+ if ( bSetPenupTimer == 0 ) -+ { -+ ezx_ts_set_timer(&ezx_ts_penup_timer, ezx_ts_penup_timeout, -+ EZX_TS_PENSAMPLE_TIMEOUT_MS); -+ TS_DPRINTK("ezx_ts_datareadok_irq: set timer pen sample\n"); -+ bSetPenupTimer = 1; -+ } -+ } -+ else -+ { -+ -+ tsDiscardDataCount ++; -+ if(tsDiscardDataCount > SAMPLE_COUNT_NOT_JUMPER) -+ { -+ tsDiscardDataCount = 0; -+ ezxts.x_pre = x; -+ ezxts.y_pre = y; -+ ezx_ts_evt_add(pressure, ezxts.x_pre, ezxts.y_pre); -+ if ( bSetPenupTimer == 0 ) -+ { -+ ezx_ts_set_timer(&ezx_ts_penup_timer, ezx_ts_penup_timeout, -+ EZX_TS_PENSAMPLE_TIMEOUT_MS); -+ TS_DPRINTK("ezx_ts_datareadok_irq: set timer pen sample\n"); -+ bSetPenupTimer = 1; -+ } -+ } -+ else if( 0 == bSetPenupTimer ) -+ { -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ } -+ } -+ } -+ else -+ { -+ if( 0 == bSetPenupTimer ) -+ { -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ } -+ } -+ } -+ else /* discard the case */ -+ { -+ tspenSampleCount = 0; -+ if( 0 == bSetPenupTimer ) -+ { -+ SSP_PCAP_TSI_mode_set(PCAP_TS_POSITION_XY_MEASUREMENT); -+ SSP_PCAP_TSI_start_XY_read(); -+ } -+ } -+ } -+ /*if (penSampleCount >= gPenSamplesNum) -+ { -+ penSampleCount = 0; -+ }*/ -+ //TS_DPRINTK("ezx_ts_datareadok_irq: read XY finished.\n"); -+ } -+ -+} -+ -+ -+static struct file_operations ezx_ts_fops = { -+ .owner = THIS_MODULE, -+ .read = ezx_ts_read, -+ .poll = ezx_ts_poll, -+ .open = ezx_ts_open, -+ .release = ezx_ts_release, -+ .fasync = ezx_ts_fasync, -+ .ioctl = ezx_ts_ioctl, -+}; -+ -+/* -+ * miscdevice structure for misc driver registration. -+ */ -+static struct miscdevice ezx_ts_dev = -+{ -+ .minor = EZX_TS_MINOR_ID, -+ .name = "ezx_ts", -+ .fops = &ezx_ts_fops, -+}; -+ -+/*Register touch screen device in misc devices.*/ -+static int ezx_ts_init(void) -+{ -+ int ret; -+ -+ init_waitqueue_head(&ezxts.read_wait); -+ ret = misc_register(&ezx_ts_dev); -+ -+ if (ret<0) -+ { -+ printk("ezx_ts_dev: failed to registering the device\n"); -+ } -+ ezx_ts_custom_setup_timer(); -+ -+ TS_DPRINTK("ezx_ts_init done.\n"); -+ return ret; -+} -+ -+/*Unregister touch screen device.*/ -+static void ezx_ts_exit(void) -+{ -+ -+ if (bSetPenupTimer) -+ { -+ del_timer(&ezx_ts_penup_timer); -+ bSetPenupTimer = 0; -+ } -+ -+ ezx_ts_custom_timer_stop(); -+ -+ misc_deregister(&ezx_ts_dev); -+ -+ TS_DPRINTK("ezx touch screen driver removed\n"); -+} -+ -+module_init(ezx_ts_init); -+module_exit(ezx_ts_exit); -+ -+MODULE_DESCRIPTION("ezx touchscreen driver"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.16.5-a/drivers/misc/ezx/ezx-ts.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/ezx-ts.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,22 @@ -+/*
-+ * linux/drivers/char/ezx-ts.c
-+ *
-+ * Copyright (C) 2002 Lili Jiang, All Rights Reserved.
-+ *
-+ *
-+ * June, 2002 Lili Jiang, create
-+ */
-+
-+#ifndef _EZXTS_H
-+#define _EZXTS_H
-+
-+#define EZX_TS_MINOR_ID 14
-+
-+#define PEN_UP 0
-+#define PEN_DOWN 0xffff
-+
-+/* extern functio nfor PCAP */
-+void ezx_ts_touch_interrupt(int irq, void* dev_id, struct pt_regs *regs);
-+void ezx_ts_dataReadok_interrupt(int irq, void* dev_id, struct pt_regs *regs);
-+
-+#endif //_EZXTS_H
-Index: linux-2.6.16.5-a/drivers/misc/ezx/fmradio.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/fmradio.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,249 @@ -+/* -+ * linux/drivers/i2c/fmradio.c -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Jay Jia -+ * Created: Nov 25, 2003 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include <linux/tty.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/poll.h> -+#include <linux/miscdevice.h> -+#include <linux/bitops.h> -+#include <linux/param.h> -+ -+#include <asm/hardware.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <linux/pm.h> -+#include <linux/apm_bios.h> -+#include <asm/arch-pxa/irqs.h> -+#include <linux/kernel.h> -+#include <linux/sched.h> -+#include <linux/string.h> -+#include <linux/timer.h> -+#include <linux/delay.h> -+#include <linux/errno.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/videodev.h> -+#include <linux/kdev_t.h> -+#include <asm/semaphore.h> -+ -+#include <linux/sound.h> -+#include <linux/soundcard.h> -+#include <asm/uaccess.h> -+#include <asm/irq.h> -+ -+#include "../../../sound/oss/ezx-common.h" -+#include "fmradio.h" -+ -+#define I2C_FMRADIO 0x81 -+ -+static int fmradio_adapter_attach(struct i2c_adapter *adap); -+static int fmradio_detach(struct i2c_client *client); -+static int fmradio_client_register(struct i2c_client *client); -+static int fmradio_client_unregister(struct i2c_client *client); -+/* ----------------------------------------------------------------------- */ -+static struct i2c_driver driver = { -+ .owner = THIS_MODULE, -+ .name = "fmradio driver", -+ .id = I2C_FMRADIO, -+ //.flags = I2C_DF_DUMMY, -+ .attach_adapter = fmradio_adapter_attach, -+ .detach_client = fmradio_detach, -+}; -+ -+static struct i2c_adapter fmradio_adapter = { -+ .owner = THIS_MODULE, -+ .name = "fmradio adapter", -+ .id = I2C_FMRADIO, -+ .client_register = fmradio_client_register, -+ .client_unregister = fmradio_client_unregister, -+}; -+ -+static struct i2c_client client_template = { -+ .name = "(unset)", -+ .adapter = &fmradio_adapter, -+}; -+ -+struct i2c_client *fmradio_client; -+ -+static int fmradio_open(struct inode *inode, struct file *file) -+{ -+ if( audioonflag & (DSP16_DEVICE|PHONE_DEVICE) ){ -+#ifdef EZX_OSS_DEBUG -+ printk(EZXOSS_DEBUG "E680 open FM EBUSY because 0x%X device is using the sound hardware.\n",audioonflag ); -+#endif -+ return -EBUSY; -+ } -+ -+ -+ poweron_mixer(FM_DEVICE); -+ //MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+static int fmradio_close(struct inode * inode, struct file *file) -+{ -+ unsigned int flags; -+ unsigned char standby[5] = {0x2a, 0x48, 0xa1, 0xdf, 0x40}; -+ -+ //MOD_DEC_USE_COUNT; -+ //e680_boomer_path_tmp_mono_lineout (); //mute boomer -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_AUD_RX_AMPS_PGA_IN_SW); -+ -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ //write standby command -+ i2c_master_send (fmradio_client, standby, 5); -+ local_irq_restore(flags); -+ shutdown_mixer(FM_DEVICE); -+ -+ return 0; -+} -+ -+ -+static int fmradio_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ return mixer_ioctl(inode, file, cmd, arg); -+} -+ -+static ssize_t fmradio_read(struct file *file, char *buf, size_t count, loff_t *ptr) -+{ -+ char *tmp; -+ int ret; -+ unsigned int flags; -+ -+ /* copy user space data to kernel space. */ -+ tmp = kmalloc(count,GFP_KERNEL); -+ if (tmp==NULL) -+ return -ENOMEM; -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_recv(fmradio_client,tmp,count); -+ local_irq_restore(flags); -+ if (ret >= 0) -+ copy_to_user(buf,tmp,count); -+ kfree(tmp); -+ return ret; -+} -+static ssize_t fmradio_write(struct file *file, const char *buf, size_t count, loff_t *ptr) -+{ -+ int ret; -+ char *tmp; -+// char data[4]={0x18,0x7d,0xbd,0xcd}; -+// char freq[5]={0x2e,0x56,0x41,0x11,0x40}; -+// unsigned char s[5]={0, 0, 0, 0, 0}; -+ -+// mixer_write(data,4); -+// i2c_master_send(fmradio_client,freq,5); -+// printk("fmradio test code\n"); -+// mdelay(300); -+// i2c_master_recv(fmradio_client, s, 5); -+// printk("s0=%02x s1=%02x s2=%02x s3=%02x s4=%02x \n",s[0],s[1],s[2],s[3],s[4]); -+ -+ unsigned int flags; -+ /* copy user space data to kernel space. */ -+ tmp = kmalloc(count,GFP_KERNEL); -+ if (tmp==NULL) -+ return -ENOMEM; -+ if (copy_from_user(tmp,buf,count)) { -+ kfree(tmp); -+ return -EFAULT; -+ } -+ local_irq_save(flags); -+ enable_irq(IRQ_I2C); -+ ret = i2c_master_send(fmradio_client,tmp,count); -+ local_irq_restore(flags); -+ kfree(tmp); -+ return ret; -+} -+ -+static int fmradio_client_register(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+ -+static int fmradio_client_unregister(struct i2c_client *client) -+{ -+ -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+static struct file_operations fmradio_fops = { -+ read: fmradio_read, -+ write: fmradio_write, -+ ioctl: fmradio_ioctl, -+ open: fmradio_open, -+ release: fmradio_close, -+}; -+ -+static struct miscdevice fmradio_misc_device = { -+ FMRADIO_MINOR, -+ FMRADIO_NAME, -+ &fmradio_fops, -+}; -+ -+/* ----------------------------------------------------------------------- */ -+ -+static int fmradio_adapter_attach(struct i2c_adapter *adap) -+{ -+ if(! (fmradio_client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) -+ return -ENOMEM; -+ memcpy(fmradio_client,&client_template,sizeof(struct i2c_client)); -+ fmradio_client->adapter = adap; -+ -+ fmradio_client->addr = 0x60; -+ -+ printk("adapter %s\n",adap->name); -+ i2c_attach_client(fmradio_client); -+ -+ return 0; -+} -+ -+static int fmradio_detach(struct i2c_client *client) -+{ -+ i2c_detach_client(fmradio_client); -+ return 0; -+} -+/* ----------------------------------------------------------------------- */ -+ -+static int fmradio_init_module(void) -+{ -+ int res; -+ -+ res = i2c_add_driver(&driver); -+ if( res < 0 ) -+ { -+ printk("error in add fmradio i2c driver\n"); -+ return res; -+ } -+ -+ if (misc_register (&fmradio_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register fmradio driver\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+static void fmradio_cleanup_module(void) -+{ -+ i2c_del_driver(&driver); -+ misc_deregister(&fmradio_misc_device); -+} -+ -+module_init(fmradio_init_module); -+module_exit(fmradio_cleanup_module); -+MODULE_AUTHOR("Jay Jia"); -+MODULE_LICENSE("GPL"); -Index: linux-2.6.16.5-a/drivers/misc/ezx/fmradio.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/fmradio.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,7 @@ -+#ifndef __FMRADIO_H -+#define __FMRADIO_H -+ -+#define FMRADIO_NAME "fmradio" -+#define FMRADIO_MINOR 198 -+ -+#endif -Index: linux-2.6.16.5-a/drivers/misc/ezx/keylight.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/keylight.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,236 @@ -+/* -+ * linux/drivers/misc/keylight.c --- key backlight driver on ezx -+ * -+ * Support for the Motorola Ezx A780 Development Platform. -+ * -+ * Author: Jay Jia -+ * Created: Feb 16, 2004 -+ * Copyright: Motorola Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <asm/hardware.h> -+#include <asm/irq.h> -+#include <linux/init.h> -+#include <linux/miscdevice.h> -+#include <linux/interrupt.h> -+#include <linux/pm.h> -+#include "keylight.h" -+#include "ssp_pcap.h" -+#include <linux/delay.h> -+ -+static int keylight_open_cnt = 0; -+static int main_current_brightness = 0xf; -+static int aux_current_brightness = 0x1f; -+ -+MODULE_LICENSE("GPL"); -+ -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+#endif -+ -+static int keylight_open(struct inode *inode,struct file *file) -+{ -+ keylight_open_cnt++; -+ -+ return 0; -+} -+ -+static int keylight_close(struct inode *inode,struct file *file) -+{ -+ keylight_open_cnt--; -+ -+ if ( keylight_open_cnt == 0 ) -+ { -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL0); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL1); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL2); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL3); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL4); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL0); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL1); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL2); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL3); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL4); -+ } -+ -+ return 0; -+} -+ -+static void keylight_main_turn_off(void) -+{ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL0); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL1); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL2); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL3); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL4); -+} -+ -+static void keylight_aux_turn_off(void) -+{ -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL0); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL1); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL2); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL3); -+ SSP_PCAP_bit_clean(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL4); -+} -+ -+static void keylight_main_turn_on(void) -+{ -+ int i,count; -+ -+ for( i=0; i<5; i++) -+ { -+ count = 1<<i; -+ switch ( main_current_brightness & count ) -+ { -+ case 1: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL0); -+ break; -+ case 2: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL1); -+ break; -+ case 4: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL2); -+ break; -+ case 8: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL3); -+ break; -+ case 16: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL_CTRL4); -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+static void keylight_aux_turn_on(void) -+{ -+ int i,count; -+ -+ for( i=0; i<5; i++) -+ { -+ count = 1<<i; -+ switch ( aux_current_brightness & count ) -+ { -+ case 1: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL0); -+ break; -+ case 2: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL1); -+ break; -+ case 4: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL2); -+ break; -+ case 8: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL3); -+ break; -+ case 16: -+ SSP_PCAP_bit_set(SSP_PCAP_ADJ_BIT_PERIPH_BL2_CTRL4); -+ break; -+ default: -+ break; -+ } -+ } -+} -+ -+static int keylight_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) -+{ -+ int ret = 0; -+ -+ switch( cmd ) -+ { -+ case KEYLIGHT_MAIN_ON: -+ keylight_main_turn_on(); -+ break; -+ case KEYLIGHT_MAIN_OFF: -+ keylight_main_turn_off(); -+ break; -+ case KEYLIGHT_MAIN_SETTING: -+ main_current_brightness = arg & 0x1f; -+ break; -+ case KEYLIGHT_AUX_ON: -+ keylight_aux_turn_on(); -+ break; -+ case KEYLIGHT_AUX_OFF: -+ keylight_aux_turn_off(); -+ break; -+ case KEYLIGHT_AUX_SETTING: -+ ret = -EINVAL; -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_PM -+static int ezx_keylight_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ break; -+ case PM_RESUME: -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+ -+static struct file_operations keylight_fops = { -+ .owner = THIS_MODULE, -+ .ioctl = keylight_ioctl, -+ .open = keylight_open, -+ .release = keylight_close, -+}; -+ -+static struct miscdevice keylight_dev = { -+ KEYLIGHT_MINOR, -+ "keylight", -+ &keylight_fops, -+}; -+ -+int init_keylight(void) -+{ -+ int ret; -+ -+ ret = misc_register(&keylight_dev); -+ if( ret < 0 ){ -+ printk("Sorry,registering the keylight device failed.\n"); -+ return ret; -+ } -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, ezx_keylight_pm_callback); -+#endif -+#if 0 -+ for(ret=0;ret<32;ret++) -+ { -+ aux_current_brightness=ret; -+ keylight_aux_turn_on(); -+ main_current_brightness=ret; -+ keylight_main_turn_on(); -+ mdelay(2000); -+ } -+#endif -+ return 0; -+} -+void clean_keylight(void) -+{ -+ misc_deregister(&keylight_dev); -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+} -+ -+module_init(init_keylight); -+module_exit(clean_keylight); -Index: linux-2.6.16.5-a/drivers/misc/ezx/keylight.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/keylight.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,20 @@ -+#ifndef KEYLIGHT_H -+#define KEYLIGHT_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#define KEYLIGHT_MINOR 168 -+#define KEYLIGHT_MAIN_ON 0xf0 -+#define KEYLIGHT_AUX_ON 0xf1 -+#define KEYLIGHT_MAIN_OFF 0xf2 -+#define KEYLIGHT_AUX_OFF 0xf3 -+#define KEYLIGHT_MAIN_SETTING 0xf4 -+#define KEYLIGHT_AUX_SETTING 0xf5 -+ -+#ifdef __cplusplus -+} -+#endif -+#endif -+ -Index: linux-2.6.16.5-a/drivers/misc/ezx/keypad-e398.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/keypad-e398.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,1497 @@ -+/* -+ * linux/drivers/char/keypad.c -+ * -+ * (c) Copyright Motorola 2003, All rights reserved. -+ */ -+ -+/* -+ * This driver is for three devices: /dev/keypad, /dev/keypadB and -+ * /dev/keypadI. -+ * /dev/keypad would be used for reading the key event buffer. -+ * It can be opened by one process at a time. -+ * /dev/keypadB would be used for ioctl(KEYPAD_IOC_GETBITMAP). -+ * It can be opened by one process at a time. -+ * /dev/keypadI would be used for ioctl(KEYPAD_IOC_INSERT_EVENT). -+ * It can be opened any number of times simultaneously. -+ * -+ * The bulverde specification is ambiguous about when interrupts happen -+ * for released keys. We were told by Intel that we won't -+ * get interrupts for released keys except in the case when multiple -+ * keys were down and they've all been released. So we implemented -+ * a timer to poll for changes in key states. -+ * -+ * The E680 P2 hardware gives us interrupts when any key is released, -+ * whether it was the only key down or not, and whether it's the last -+ * of multiple keys to be released or not. We don't know whether this -+ * behavior will continue in future hardware releases, so the release -+ * timer is still in the code, #ifdef'd with USE_RELEASE_TIMER. On the -+ * P2 hardware, the code works with or without USE_RELEASE_TIMER defined. -+ * If the release interrupts are always going to happen, we can remove -+ * the #ifdef'd code. -+ * -+ * With the P2 hardware, the power key bit in the KPDK register is always -+ * on. We don't know if this is correct behavior or not, but in any case -+ * it certainly causes trouble to have that key autorepeating indefinitely, -+ * or to be checking indefinitely for the key to be released (if we're doing -+ * release polling). -+ * -+ * For now, any_keys_down() returns 0 if the power key is the only one down. -+ * . At interrupt time, if the power key is the only one down we don't -+ * set the autorepeat timer or release timer. -+ * . When the release timer goes off, if the power key is the only one -+ * still down we don't set the timer again. -+ * . When the autorepeat timer goes off, if the power key is the only -+ * one down we don't generate any events. -+ * In autorepeat_timer_went_off, if there are non-power keys down, while we're -+ * looking through the whole bitmap of keys down we ignore the power key. -+ */ -+ -+#include <linux/tty.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/poll.h> -+#include <linux/miscdevice.h> -+#include <linux/bitops.h> -+#include <linux/param.h> -+ -+#include <asm/hardware.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <linux/pm.h> -+#include <linux/apm_bios.h> -+#include "keypad.h" -+#include <asm/arch/irqs.h> -+#include "asm/arch/ezx.h" -+ -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+static struct pm_dev *keypadI_pm_dev; -+static int kpc_res,kpkdi_res; -+static int GPIO_TC_MM_STATE = 1; -+extern unsigned char pxafb_ezx_getLCD_status(void); -+#endif -+/* -+ * This is the number of microseconds we wait before checking to see if any -+ * keys have been released. -+ */ -+#define RDELAY 200 -+ -+#define KEYBUF_EMPTY() (keybuf_start == keybuf_end) -+#define KEYBUF_FULL() ( ((keybuf_end+1)%KEYBUF_SIZE) == keybuf_start) -+#define KEYBUF_INC(x) ((x) = (((x)+1) % KEYBUF_SIZE)) -+ -+static int keypad_open (struct inode *, struct file *); -+static int keypad_close (struct inode *, struct file *); -+static int keypad_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+static unsigned int keypad_poll (struct file *, poll_table *); -+static ssize_t keypad_read (struct file *, char *, size_t, loff_t *); -+ -+static int keypadB_open (struct inode *, struct file *); -+static int keypadB_close (struct inode *, struct file *); -+static int keypadB_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+static unsigned int keypadB_poll (struct file *, poll_table *); -+ -+static int keypadI_open(struct inode *, struct file *); -+static int keypadI_close(struct inode *, struct file *); -+static int keypadI_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+ -+static void kp_interrupt (int, void *, struct pt_regs *); -+#ifdef USE_RELEASE_TIMER -+static void release_timer_went_off (unsigned long); -+static void do_scan(void); -+#endif -+static void autorepeat_timer_went_off (unsigned long); -+ -+static int add_to_keybuf (unsigned short); -+static int add_events (unsigned long *, unsigned long *); -+static int insert_event (unsigned short); -+static unsigned short get_from_keybuf (void); -+static void scan_to_bitmap -+ (unsigned long, unsigned long, unsigned long, unsigned long *); -+static inline void set_bitmap_to_zero(unsigned long b[]); -+static inline void copy_bitmap(unsigned long dest[], unsigned long source[]); -+static inline void turn_on_bit(unsigned long map[], int); -+static inline void turn_off_bit(unsigned long map[], int); -+static inline int any_keys_down (unsigned long *); -+ -+/* -+ * keybuf is a circular buffer to hold keypad events. -+ * keybuf_start is the index of the first event. -+ * keybuf_end is one more than the index of the last event. -+ * The buffer is empty when keybuf_start == keybuf_end. -+ * We only use KEYBUF_SIZE-1 entries in the buffer so we can tell -+ * when it's full without needing another variable to tell us. -+ * The buffer is full when (keybuf_end+1)%KEYBUF_SIZE == keybuf_start. -+ */ -+static unsigned short keybuf[KEYBUF_SIZE]; -+static int keybuf_start = 0; -+static int keybuf_end = 0; -+ -+static DECLARE_WAIT_QUEUE_HEAD(keypad_wait); -+static spinlock_t keypad_lock = SPIN_LOCK_UNLOCKED; -+ -+static int reading_opens = 0; -+static int bitmap_opens = 0; -+ -+/* previous bitmap of keys down */ -+static unsigned long oldkeybitmap[NUM_WORDS_IN_BITMAP]; -+/* current bitmap of keys down */ -+static unsigned long keybitmap[NUM_WORDS_IN_BITMAP]; -+/* last bitmap read by ioctl */ -+static unsigned long lastioctlbitmap[NUM_WORDS_IN_BITMAP]; -+ -+static unsigned long kpas = 0; /* last value of kpas */ -+static unsigned long kpasmkp0 = 0; /* last value of kpasmkp0 */ -+static unsigned long kpasmkp1 = 0; /* last value of kpasmkp1 */ -+static unsigned long kpasmkp2 = 0; /* last value of kpasamkp2*/ -+static unsigned long kpdk = 0; /* last value of kpdk */ -+ -+#ifdef USE_RELEASE_TIMER -+static struct timer_list key_release_timer; -+static int key_release_interval = RDELAY * HZ/1000; -+#endif -+ -+static int do_autorepeat = 1; -+static long jiffies_to_first_repeat = 30; -+static long jiffies_to_next_repeat = 30; -+static struct timer_list autorepeat_timer; -+ -+extern int lockscreen_flag; -+ -+static int -+keypad_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypad_open\n"); -+#endif -+ spin_lock(keypad_lock); -+ if (reading_opens > 0) -+ { -+ spin_unlock(keypad_lock); -+ return -EBUSY; -+ } -+ reading_opens++; -+ spin_unlock(keypad_lock); -+ -+ return 0; -+} -+ -+static int -+keypadB_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypadB_open\n"); -+#endif -+ spin_lock(keypad_lock); -+ if (bitmap_opens > 0) -+ { -+ spin_unlock(keypad_lock); -+ return -EBUSY; -+ } -+ bitmap_opens++; -+ /* -+ * poll returns when lastioctlbitmap is different from keybitmap. -+ * we set lastioctlbitmap to keybitmap here so that a poll right -+ * after an open returns when the bitmap is different from when -+ * the open was done, not when the bitmap is different from the -+ * last time some other process read it -+ */ -+ copy_bitmap(lastioctlbitmap, keybitmap); -+ spin_unlock(keypad_lock); -+ -+ return 0; -+} -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+static int keypadI_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ break; -+ case PM_RESUME: -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ if(GPIO_TC_MM_STATE == 1) -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ else -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+#endif -+ -+static int -+keypadI_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypadI_open\n"); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ -+ return 0; -+} -+ -+static int -+keypad_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_close\n"); -+#endif -+ /* -+ * this decrement of reading_opens doesn't have to be protected because -+ * it can only be executed to close the single open of /dev/keypad -+ */ -+ reading_opens--; -+ return 0; -+} -+ -+static int -+keypadB_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadB_close\n"); -+#endif -+ /* -+ * this decrement of bitmap_opens doesn't have to be protected because -+ * it can only be executed to close the single open of /dev/keypadB -+ */ -+ bitmap_opens--; -+ return 0; -+} -+ -+static int -+keypadI_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadI_close\n"); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ -+ return 0; -+} -+ -+/** -+ * Add the specified event to the key buffer. -+ * This should be called with keypad_lock locked. -+ */ -+static int -+add_to_keybuf (unsigned short event) -+{ -+ if (KEYBUF_FULL()) -+ { -+ return -ENOMEM; -+ } -+ -+ keybuf[keybuf_end] = event; -+ KEYBUF_INC (keybuf_end); -+ -+#if CONFIG_APM -+ queue_apm_event(KRNL_KEYPAD, NULL); -+#endif -+ printk("add keypad event = %x\n", event); -+ return 0; -+} -+ -+/* -+ * code[c*8+r] is the key code for the key that's down when there's a 1 -+ * in column c, row r of the scan registers. -+ */ -+ -+#if defined(CONFIG_KEYPAD_V700) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_LEFT, KEYPAD_RIGHT, -+ KEYPAD_POUND, KEYPAD_0, KEYPAD_9, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_2, KEYPAD_4, KEYPAD_6, KEYPAD_8, -+ KEYPAD_7, KEYPAD_SLEFT, KEYPAD_SRIGHT, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_MENU, KEYPAD_1, KEYPAD_3, KEYPAD_5, -+ KEYPAD_STAR, KEYPAD_VOLUP, KEYPAD_VOLDOWN, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_CAMERA, KEYPAD_CLEAR, KEYPAD_CARRIER, KEYPAD_ACTIVATE, -+ KEYPAD_SEND, KEYPAD_SMART, KEYPAD_VAVR, KEYPAD_NONE -+}; -+ -+/* end CONFIG_KEYPAD_V700 */ -+#elif defined(CONFIG_E680_P4A) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_LEFT, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_RIGHT, KEYPAD_CENTER, KEYPAD_HOME, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_GAME_R, KEYPAD_NONE, KEYPAD_GAME_L, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_A, KEYPAD_B, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+}; -+ -+/* end CONFIG_E680_P4A */ -+#elif defined(CONFIG_KEYPAD_E680) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_RIGHT, KEYPAD_LEFT, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_NONE, KEYPAD_GAME_R, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_HOME, KEYPAD_GAME_L, KEYPAD_CENTER, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ -+}; -+/*end CONFIG_KEYPAD_E680 */ -+#elif defined(CONFIG_KEYPAD_A780) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_OK, KEYPAD_1, KEYPAD_4, KEYPAD_7, -+ KEYPAD_STAR, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_MENU, KEYPAD_2, KEYPAD_5, KEYPAD_8, -+ KEYPAD_0, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_CANCEL, KEYPAD_3, KEYPAD_6, KEYPAD_9, -+ KEYPAD_POUND, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_JOG_UP, KEYPAD_JOG_MIDDLE, KEYPAD_PTT, KEYPAD_HOME, -+ KEYPAD_JOG_DOWN, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 4 */ -+ KEYPAD_UP, KEYPAD_CENTER, KEYPAD_LEFT, KEYPAD_RIGHT, -+ KEYPAD_DOWN, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+}; -+#endif -+ -+/* -+ * Decode the specified scan register values into the bitmap pointed -+ * to by the last argument. The bitmap will contain a 1 -+ * for each key that's down. -+ * -+ * Only the 1st two of the four scan registers are used. -+ */ -+static void -+scan_to_bitmap(unsigned long kpas, unsigned long kpasmkp0, -+ unsigned long kpasmkp1, unsigned long bitmap[]) -+{ -+ int row, col; -+ int bitnum; -+ unsigned long scanmap; -+#if defined(CONFIG_KEYPAD_A780) -+ int keep; -+#endif -+ -+ set_bitmap_to_zero (bitmap); -+ -+ if ((kpas & KPAS_MUKP) == MUKP_NO_KEYS) -+ { -+ return; -+ } -+ -+ if ((kpas & KPAS_MUKP) == MUKP_ONE_KEY) -+ { -+ row = (kpas & KPAS_RP) >> 4; -+ col = kpas & KPAS_CP; -+ turn_on_bit (bitmap, scanbit_to_keycode[col*8 + row]); -+ return; -+ } -+ -+ /* reach here if multiple keys */ -+ scanmap = (kpasmkp0 & 0x7f) | ((kpasmkp0 & 0x7f0000) >> 8) | -+ ((kpasmkp1 & 0x7f) << 16) | ((kpasmkp1 & 0x7f0000) << 8); -+ while ((bitnum = ffs(scanmap)) != 0) -+ { -+ /* -+ * ffs returns bit numbers starting with 1, so subtract 1 to index -+ * into scanbit_to_keycode[] -+ */ -+ turn_on_bit (bitmap, scanbit_to_keycode[bitnum-1]); -+ scanmap &= ~(1<<(bitnum-1)); -+ } -+#if defined(CONFIG_KEYPAD_A780) -+ kpasmkp2 = KPASMKP2; -+ printk("kpasmkp0 = 0x\n", kpasmkp0); -+ printk("kpasmkp1 = 0x\n", kpasmkp1); -+ printk("kpasmkp2 = 0x\n", kpasmkp2); -+ if( (kpasmkp2 != 1) || (kpasmkp2 != 2) | (kpasmkp2 != 4) | (kpasmkp2 != 8) | (kpasmkp2 != 16) ) -+ return; -+ while ((bitnum = ffs(kpasmkp2)) !=0) -+ { -+ turn_on_bit (bitmap, scanbit_to_keycode[32+bitnum-1]); -+ kpasmkp2 &= ~(1<<(bitnum-1)); -+ } -+#endif -+} -+ -+/* -+ * Add events indicated by the difference between the last scan (oldbitmap) -+ * and this one (newbitmap) to the input buffer. -+ * Return nonzero right away if any of the events can't be added. -+ * A zero return means all the events were added. -+ * This should be called with keypad_lock locked. -+ */ -+static int -+add_events (unsigned long *oldbitmap, unsigned long *newbitmap) -+{ -+ unsigned long tmpmap, onebitmap; -+ int bitnum, i, ret; -+ -+ /* generate events for keys that were down before and are up now */ -+ for (i=NUM_WORDS_IN_BITMAP-1;i>=0;i--) -+ { -+ tmpmap = oldbitmap[i]; -+ while ((bitnum = ffs(tmpmap)) != 0) -+ { -+ onebitmap = 1<<(bitnum-1); -+ if ((newbitmap[i] & onebitmap) == 0) -+ { -+ ret = add_to_keybuf(bitnum + (32*(NUM_WORDS_IN_BITMAP-1-i) | KEYUP)); -+ if (ret < 0) -+ { -+ return ret; -+ } -+ } -+ tmpmap &= ~onebitmap; -+ } -+ } -+ /* generate events for down keys that were up before */ -+ for (i=NUM_WORDS_IN_BITMAP-1;i>=0;i--) -+ { -+ tmpmap = newbitmap[i]; -+ while ((bitnum = ffs(tmpmap)) != 0) -+ { -+ onebitmap = 1<<(bitnum-1); -+ if ((oldbitmap[i] & onebitmap) == 0) -+ { -+ ret = add_to_keybuf -+ (bitnum + (32*(NUM_WORDS_IN_BITMAP-1-i) | KEYDOWN)); -+ if (ret < 0) -+ { -+ return ret; -+ } -+ } -+ tmpmap &= ~onebitmap; -+ } -+ } -+ return 0; -+} -+ -+/* -+ * do the INSERT_EVENT ioctl -+ */ -+static int -+insert_event (unsigned short event) -+{ -+ unsigned long flags; -+ int ret; -+ -+ if (KEYCODE(event) > KEYPAD_MAXCODE) -+ { -+ printk(KERN_WARNING " inserted key code %d too big\n", -+ KEYCODE(event)); -+ return -EINVAL; -+ } -+ spin_lock_irqsave(&keypad_lock, flags); -+ if (KEY_IS_DOWN(event)) -+ { -+ turn_on_bit(keybitmap, KEYCODE(event)); -+ } -+ else -+ { -+ turn_off_bit (keybitmap, event); -+ } -+ if ((ret = add_to_keybuf(event)) < 0) -+ { -+ spin_unlock_irqrestore(&keypad_lock,flags); -+ return ret; -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ return 0; -+} -+ -+static int -+keypad_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int interval; /* debounce interval */ -+ int imkp; /* Ignore Multiple Key Press bit */ -+ struct autorepeatinfo ar; /* autorepeat information */ -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypad_ioctl: 0x%x\n", cmd); -+#endif -+ switch (cmd) -+ { -+ case KEYPAD_IOC_INSERT_EVENT: -+ return insert_event ((unsigned short)arg); -+ break; -+ case KEYPAD_IOC_GET_DEBOUNCE_INTERVAL: -+ interval = KPKDI & KPKDI_BITS; -+ return put_user(interval, (unsigned long *)arg); -+ break; -+ case KEYPAD_IOC_SET_DEBOUNCE_INTERVAL: -+ interval = (unsigned short)arg; -+ if (interval > KPKDI_BITS) -+ { -+ return -EINVAL; -+ } -+ KPKDI &= ~KPKDI_BITS; -+ KPKDI |= interval; -+ break; -+ case KEYPAD_IOC_GET_IMKP_SETTING: -+ imkp = ((KPC & KPC_IMKP) == KPC_IMKP); -+ return put_user(imkp, (unsigned char *)arg); -+ break; -+ case KEYPAD_IOC_SET_IMKP_SETTING: -+ imkp = (unsigned char)arg; -+ if (imkp) -+ { -+ KPC |= KPC_IMKP; -+ } -+ else -+ { -+ KPC &= ~KPC_IMKP; -+ } -+ break; -+ case KEYPAD_IOC_SET_AUTOREPEAT: -+ if (copy_from_user (&ar, (void *)arg, -+ sizeof(struct autorepeatinfo)) != 0) -+ { -+ return -EFAULT; -+ } -+ do_autorepeat = ar.r_repeat; -+ /* times are specified in milliseconds; convert to jiffies */ -+ jiffies_to_first_repeat = ar.r_time_to_first_repeat * HZ/1000; -+ jiffies_to_next_repeat = ar.r_time_between_repeats * HZ/1000; -+ break; -+ default: -+ return -ENOTTY; -+ } -+ return 0; -+} -+ -+static int -+keypadB_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned long flags; -+ int ret; -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypadB_ioctl: 0x%x\n", cmd); -+#endif -+ if (cmd == KEYPAD_IOC_INSERT_EVENT) -+ { -+ return insert_event ((unsigned short)arg); -+ } -+ else if (cmd == KEYPAD_IOC_GETBITMAP) -+ { -+ spin_lock_irqsave(&keypad_lock, flags); -+ ret = copy_to_user ((void *)arg, keybitmap, -+ NUM_WORDS_IN_BITMAP * sizeof(unsigned long)); -+ copy_bitmap (lastioctlbitmap, keybitmap); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return (ret != 0) ? -EFAULT : 0; -+ } -+ else -+ { -+ return -ENOTTY; -+ } -+} -+ -+static int -+keypadI_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned long flags; -+ int ret; -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypadI_ioctl: 0x%x\n", cmd); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ if( cmd == KEYPADI_TURN_ON_LED ) -+ { -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ GPIO_TC_MM_STATE = 0; -+ PGSR3 &= ~GPIO_bit(GPIO_TC_MM_EN); -+ return 0; -+ } -+ if( cmd == KEYPADI_TURN_OFF_LED ) -+ { -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ GPIO_TC_MM_STATE = 1; -+ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); -+ return 0; -+ } -+#endif -+ -+ if (cmd == KEYPAD_IOC_INSERT_EVENT) -+ { -+ return insert_event ((unsigned short)arg); -+ } -+ else if (cmd == KEYPAD_IOC_GETBITMAP) -+ { -+ spin_lock_irqsave(&keypad_lock, flags); -+ ret = copy_to_user ((void *)arg, keybitmap, -+ NUM_WORDS_IN_BITMAP * sizeof(unsigned long)); -+ copy_bitmap (lastioctlbitmap, keybitmap); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return (ret != 0) ? -EFAULT : 0; -+ } -+ else -+ { -+ return -ENOTTY; -+ } -+} -+ -+static unsigned int -+keypad_poll( struct file *file, poll_table * wait ) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_poll\n"); -+#endif -+ poll_wait(file, &keypad_wait, wait); -+ -+ if (!KEYBUF_EMPTY()) -+ { -+ return (POLLIN | POLLRDNORM); -+ } -+ return 0; -+} -+ -+static unsigned int -+keypadB_poll( struct file *file, poll_table * wait ) -+{ -+ int i; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadB_poll\n"); -+#endif -+ poll_wait(file, &keypad_wait, wait); -+ -+ for (i=0; i < NUM_WORDS_IN_BITMAP; i++) -+ { -+ if (lastioctlbitmap[i] != keybitmap[i]) -+ { -+ return (POLLIN | POLLRDNORM); -+ } -+ } -+ return 0; -+} -+ -+static unsigned short -+get_from_keybuf(void) -+{ -+ unsigned short event; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock, flags); -+ event = keybuf[keybuf_start]; -+ KEYBUF_INC (keybuf_start); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return event; -+} -+ -+static ssize_t -+keypad_read(struct file *file, char *buf, size_t count, loff_t *ptr) -+{ -+ int i, ret; -+ unsigned short event; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_read\n"); -+#endif -+ /* Can't seek (pread) on this device */ -+ if (ptr != &file->f_pos) -+ { -+ return -ESPIPE; -+ } -+ -+ if (count == 0) -+ { -+ return 0; -+ } -+ -+ if (KEYBUF_EMPTY()) -+ { -+ /* buffer is empty */ -+ /* if not blocking return */ -+ if (file->f_flags & O_NONBLOCK) -+ { -+ return -EAGAIN; -+ } -+ /* blocking, so wait for input */ -+ ret = wait_event_interruptible(keypad_wait, !KEYBUF_EMPTY()); -+ if (ret) -+ { -+ return ret; -+ } -+ } -+ -+ i = 0; -+ /* copy events until we have what the user asked for or we run out */ -+ while ((i+1 < count) && !KEYBUF_EMPTY()) -+ { -+ event = get_from_keybuf(); -+ if ((ret = put_user(event, (unsigned short *)buf)) != 0) -+ { -+ return ret; -+ } -+ buf += EVENTSIZE; -+ i += EVENTSIZE; -+ } -+ return i; -+} -+ -+#ifdef CONFIG_PM -+static int button_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ int pksr; -+ -+ pksr = PKSR; -+ PKSR = 0xfffff; -+ switch(req) -+ { -+ case PM_SUSPEND: -+ kpc_res = KPC; -+ kpkdi_res = KPKDI; -+ set_bitmap_to_zero (oldkeybitmap); -+ set_bitmap_to_zero (keybitmap); -+ set_bitmap_to_zero (lastioctlbitmap); -+ kpas = 0; -+ kpasmkp0 = 0; -+ kpasmkp1 = 0; -+ kpasmkp2 = 0; -+ kpdk = 0; -+ break; -+ case PM_RESUME: -+ KPC = kpc_res; -+ KPKDI = kpkdi_res; -+#if CONFIG_APM -+#if defined(CONFIG_E680_P4A) -+ if (pksr & 0xe4400) /*93 97 100 101 102 key is pressed (switch on) */ -+ { -+ queue_apm_event(KRNL_KEYPAD, NULL); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ if (pksr & 0xee400) /*93 96 97 98 190 101 102 key is pressed */ -+ { -+ queue_apm_event(KRNL_KEYPAD, NULL); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ if (pksr & 0x2000) -+ turn_on_bit (keybitmap, KEYPAD_A); -+ if (pksr & 0x8000) -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+ printk("pksr = %x\n",pksr); -+ if (pksr & 0xec400) /* 93 97 98 100 101 102 key is pressed */ -+ { -+ queue_apm_event(KRNL_KEYPAD, NULL); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#endif -+ -+ break; -+ } -+ return 0; -+} -+#endif -+ -+/* for /dev/keypad */ -+static struct file_operations -+keypad_fops = { -+ read: keypad_read, -+ llseek: no_llseek, -+ poll: keypad_poll, -+ ioctl: keypad_ioctl, -+ open: keypad_open, -+ release: keypad_close, -+}; -+ -+static struct miscdevice -+keypad_misc_device = { -+ KEYPAD_MINOR, -+ KEYPAD_NAME, -+ &keypad_fops, -+}; -+ -+/* -+ * for /dev/keypadB. -+ * read() isn't defined here. calls to read() will return -1 with EINVAL. -+ */ -+static struct file_operations -+keypadB_fops = { -+ llseek: no_llseek, -+ poll: keypadB_poll, -+ ioctl: keypadB_ioctl, -+ open: keypadB_open, -+ release: keypadB_close, -+}; -+ -+static struct miscdevice -+keypadB_misc_device = { -+ KEYPAD_BITMAP_MINOR, -+ KEYPAD_BITMAP_NAME, -+ &keypadB_fops, -+}; -+ -+/* -+ * for /dev/keypadI. -+ * read() isn't defined here. calls to read() will return -1 with EINVAL. -+ */ -+static struct file_operations -+keypadI_fops = { -+ llseek: no_llseek, -+ ioctl: keypadI_ioctl, -+ open: keypadI_open, -+ release: keypadI_close, -+}; -+ -+static struct miscdevice -+keypadI_misc_device = { -+ KEYPAD_INSERT_MINOR, -+ KEYPAD_INSERT_NAME, -+ &keypadI_fops, -+}; -+ -+#ifdef CONFIG_PANIC_LOG -+static u32 panic_bug_used =0; -+#endif -+ -+/* Interrupt Handler for KEYPAD */ -+static void -+kp_interrupt(int irq, void *ptr, struct pt_regs *regs) -+{ -+ unsigned long flags; -+ unsigned long kpc_val; -+ -+#ifdef USE_RELEASE_TIMER -+ del_timer (&key_release_timer); -+#endif -+ del_timer (&autorepeat_timer); -+ spin_lock_irqsave(&keypad_lock,flags); -+ -+ /* ack interrupt */ -+ kpc_val = KPC; -+ -+ /* matrix interrupt */ -+ if (kpc_val & KPC_MI) -+ { -+/* -+ * The Intel driver turned on KPC_AS here. It doesn't seem that we -+ * would need to do that, because getting an interrupt means that -+ * a scan was just done. For now, I've commented out the setting -+ * and clearing of this bit. -+ KPC |= KPC_AS; -+ */ -+ while (KPAS & KPAS_SO) -+ { -+ /* Wait for the Scan On bit to go off before */ -+ /* reading the scan registers. */ -+ NULL; -+ }; -+ -+ kpas = KPAS; -+ kpasmkp0 = KPASMKP0; -+ kpasmkp1 = KPASMKP1; -+ kpasmkp2 = KPASMKP2; -+ -+ } -+ -+ /* direct interrupt */ -+ if (kpc_val & KPC_DI) -+ { -+ kpdk = KPDK; -+ /* -+ * reading the register turns off the "key pressed since last read" -+ * bit if it was on, so we turn it off -+ */ -+ kpdk &= ~KPDK_DKP; -+ } -+ -+ copy_bitmap (oldkeybitmap, keybitmap); -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1, keybitmap); -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* VR key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* VR key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+ if (kpdk & KPDK_DK3) -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+ -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ -+#ifdef CONFIG_PANIC_LOG -+ if ((kpdk & KPDK_DK0)&&(kpasmkp1& 0x00020000)) -+ { -+ if(0 == panic_bug_used) -+ { -+ panic_bug_used = 1; -+ BUG(); -+ } -+ } -+#endif -+ -+ (void) add_events (oldkeybitmap, keybitmap); -+ -+ /* If any keys are down, set a timer to check for key release */ -+ /* and one for autorepeat if that's on. */ -+ if (any_keys_down (keybitmap)) -+ { -+#ifdef USE_RELEASE_TIMER -+ key_release_timer.expires = (jiffies + key_release_interval); -+ add_timer (&key_release_timer); -+#endif -+ if (do_autorepeat) -+ { -+ autorepeat_timer.expires = (jiffies + jiffies_to_first_repeat); -+ add_timer (&autorepeat_timer); -+ } -+ } -+ -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ printk("keypad interrupt occurred\n"); -+} -+ -+#ifdef USE_RELEASE_TIMER -+/* -+ * This is called when the key release timer goes off. That's the -+ * only time it should be called. Check for changes in what keys -+ * are down. -+ */ -+static void -+release_timer_went_off(unsigned long unused) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock,flags); -+ do_scan(); -+ /* If any keys are still down, set the timer going again. */ -+ if (any_keys_down (keybitmap)) -+ { -+ mod_timer (&key_release_timer, jiffies + key_release_interval); -+ } -+ else -+ { -+ del_timer (&autorepeat_timer); -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+} -+#endif -+ -+/* -+ * This is called when the autorepeat timer goes off. -+ */ -+static void -+autorepeat_timer_went_off(unsigned long unused) -+{ -+ int i, bitnum; -+ unsigned long tmp; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock,flags); -+ if (!any_keys_down (keybitmap)) -+ { -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return; -+ } -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ tmp = keybitmap[NUM_WORDS_IN_BITMAP-i-1]; -+ while ((bitnum = ffs(tmp)) != 0) -+ { -+ tmp &= ~(1<<(bitnum-1)); -+ /* see explanation at top of file */ -+ if ( (bitnum + (32*i)) == KEYPAD_POWER ) -+ { -+ continue; -+ } -+ (void) add_to_keybuf( (bitnum + (32*i)) | KEYDOWN ); -+ } -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ -+ mod_timer (&autorepeat_timer, jiffies + jiffies_to_next_repeat); -+} -+ -+#ifdef USE_RELEASE_TIMER -+/* -+ * Do a scan and add key events for anything that's different from the -+ * last scan. We assume keypad_lock is locked when this is called -+ * (by release_timer_went_off). -+ */ -+static void -+do_scan(void) -+{ -+ unsigned long kpas_new, kpasmkp0_new, kpasmkp1_new; -+ unsigned long kpdk_new; -+ int change; -+ -+ /* Initiate an automatic scan */ -+ KPC |= KPC_AS; -+ /* Wait for the Scan On bit to go off before */ -+ /* reading the scan registers. */ -+ while (KPAS & KPAS_SO) -+ { -+ NULL; -+ }; -+ kpas_new = KPAS; -+ kpasmkp0_new = KPASMKP0; -+ kpasmkp1_new = KPASMKP1; -+ kpdk_new = KPDK; -+ /* -+ * reading the register turns off the "key pressed since last read" bit -+ * if it was on, so we turn it off -+ */ -+ kpdk_new &= ~KPDK_DKP; -+ KPC &= ~KPC_AS; -+ -+ change = ((kpas_new != kpas) || -+ (kpasmkp0_new != kpasmkp0) || -+ (kpasmkp1_new != kpasmkp1) || -+ (kpdk_new != kpdk)); -+ -+ if (change) -+ { -+ kpas = kpas_new; -+ kpasmkp0 = kpasmkp0_new; -+ kpasmkp1 = kpasmkp1_new; -+ kpdk = kpdk_new; -+ -+ copy_bitmap (oldkeybitmap, keybitmap); -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1, keybitmap); -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* screen lock key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* screen lock key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+ if (kpdk & KPDK_DK3) -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+ -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ add_events (oldkeybitmap, keybitmap); -+ -+ wake_up_interruptible (&keypad_wait); -+ } -+} -+#endif -+ -+/* -+ * set all words in the specified bitmap to 0 -+ */ -+static inline void set_bitmap_to_zero(unsigned long b[]) { -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ b[i]=0; -+ } -+} -+ -+/* -+ * copy source bitmap to destination bitmap -+ */ -+static inline void copy_bitmap(unsigned long dest[], unsigned long source[]) { -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ dest[i]=source[i]; -+ } -+} -+ -+/* -+ * Turn on the bit position in map for the specified key code. -+ * Bit numbers start with 1 (not 0) and increase moving left within -+ * words and within the array. -+ * Bit 1 is the rightmost bit in map[NUM_WORDS_IN_BITMAP-1]. -+ * Bit 33 is the rightmost bit in map[NUM_WORDS_IN_BITMAP-2]. -+ */ -+static inline void -+turn_on_bit(unsigned long map[], int code) -+{ -+ int word, pos, p; -+ -+ /* if we have 2 words, bits 1-32 are in map[1], 33-64 in map[0] */ -+ word = (NUM_WORDS_IN_BITMAP - 1) - ((code-1) / 32); -+ /* -+ * bit 1 is 1<<0, bit 2 is 1<<1, ... bit 32 is 1 << 31, all in map[1] -+ * bit 33 is 1<<0, bit 34 is 1<<1, ... in map[0] -+ * we want this: -+ * code pos -+ * 1 0 -+ * 2 1 -+ * ... -+ * 31 30 -+ * 32 31 -+ * 33 0 -+ * 34 1 -+ * ... -+ */ -+ pos = (p = (code % 32)) == 0 ? 31 : p-1; -+ map[word] |= (1<<pos); -+} -+ -+/* -+ * Turn off the bit position in map for the specified key code. -+ * Bit positions start with 1 (not 0). -+ */ -+static inline void -+turn_off_bit(unsigned long map[], int code) -+{ -+ int word, pos, p; -+ -+ word = (NUM_WORDS_IN_BITMAP - 1) - ((code-1) / 32); -+ pos = (p = (code % 32)) == 0 ? 31 : p-1; -+ map[word] &= ~(1<<pos); -+} -+ -+/* -+ * Return 1 if any bits are down in map[] -+ */ -+static inline int -+any_keys_down (unsigned long *map) -+{ -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ /* don't count the power key */ -+ if ((i == 0) && (*map == 0x10)) -+ { -+ map++; -+ continue; -+ } -+ if (*map++) -+ { -+ return 1; -+ } -+ } -+ return 0; -+} -+static int -+__init keypad_init(void) -+{ -+ int err; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_init\n"); -+#endif -+ -+ set_bitmap_to_zero (oldkeybitmap); -+ set_bitmap_to_zero (keybitmap); -+ set_bitmap_to_zero (lastioctlbitmap); -+ -+ /* set up gpio */ -+#if defined (CONFIG_KEYPAD_V700) -+ pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN); /* KP_MKIN<6> */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_MKIN<3> */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_MKIN<4> */ -+ pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); /* KP_MKIN<5> */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#elif defined(CONFIG_E680_P4A) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#elif defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -+ pxa_gpio_mode(96 | GPIO_ALT_FN_1_IN); /* KP_DKIN<3>, GAME_A */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_DKIN<5>, GAME_B */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); -+#elif defined (CONFIG_KEYPAD_A780) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, voice_rec */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_3_IN); /* KP_MKIN<3> */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_3_IN); /* KP_MKIN<4> */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+ pxa_gpio_mode(107 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<4> */ -+#elif defined(CONFIG_KEYPAD_MAINSTONE) -+ /* from Intel driver */ -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(94 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#endif -+ -+ /* set keypad control register */ -+ KPC = (KPC_ASACT | /* automatic scan on activity */ -+ KPC_ME | KPC_DE | /* matrix and direct keypad enabled */ -+#if defined (CONFIG_KEYPAD_V700) -+ (3<<23) | /* 4 columns */ -+ (6<<26) | /* 7 rows */ -+#elif defined(CONFIG_E680_P4A) -+ (3<<23) | /* 4 columns */ -+ (2<<26) | /* 3 rows */ -+ (4<<6) | /* 4# direct key */ -+#elif defined(CONFIG_KEYPAD_E680) -+ (5<<23) | /* 4 columns */ -+ (4<<26) | /* 3 rows */ -+ (5<<6) | /* 5# direct keys */ -+#elif defined(CONFIG_KEYPAD_A780) -+ (4<<23) | /* 5 columns */ -+ (4<<26) | /* 5 rows */ -+ (0<<6) | /* 1# direct keys */ -+#endif -+ KPC_MS7_0); /* scan all columns */ -+ -+ CKEN |= CKEN19_KEYPAD; -+ -+ err = request_irq (IRQ_KEYPAD, kp_interrupt, 0, "Keypad", NULL); -+ if (err) -+ { -+ printk (KERN_CRIT "can't register IRQ%d for keypad, error %d\n", -+ IRQ_KEYPAD, err); -+ CKEN &= ~CKEN19_KEYPAD; -+ return -ENODEV; -+ } -+ -+ if (misc_register (&keypad_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypad driver\n"); -+ return -EIO; -+ } -+ if (misc_register (&keypadB_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypadB driver\n"); -+ misc_deregister(&keypad_misc_device); -+ return -EIO; -+ } -+ if (misc_register (&keypadI_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypadI driver\n"); -+ misc_deregister(&keypad_misc_device); -+ misc_deregister(&keypadB_misc_device); -+ return -EIO; -+ } -+ -+#ifdef USE_RELEASE_TIMER -+ init_timer (&key_release_timer); -+ key_release_timer.function = release_timer_went_off; -+#endif -+ init_timer (&autorepeat_timer); -+ autorepeat_timer.function = autorepeat_timer_went_off; -+ -+ /* -+ * we want the phone to be able to tell the status of the screen -+ * lock switch at power-up time -+ */ -+ kpdk = KPDK; /* read direct key register */ -+ /* -+ * reading the register turns off the "key pressed since last read" bit -+ * if it was on, so we turn it off -+ */ -+ kpdk &= ~KPDK_DKP; -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* VR key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) /* Power key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* VR key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) /* Power key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ if (kpdk & KPDK_DK3) /* GAME_A key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) /* GAME_B key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, button_pm_callback); -+#if defined(CONFIG_E680_P4A) -+/*93,97,100,101,102*/ -+ PKWR = 0xe4400; -+/*103 104 105 106*/ -+ PGSR3 |= 0x780; -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+/*93,96,97,98,100,101,102*/ -+ PKWR = 0xee400; -+/*103 104 105 106*/ -+ PGSR3 |= 0x780; -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+/*93,97,98,100,101,102*/ -+ PKWR = 0xec400; -+/*103 104 105 106 107*/ -+ PGSR3 |= 0xf80; -+#endif -+#endif -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+ keypadI_pm_dev = pm_register(PM_SYS_DEV, 0, keypadI_pm_callback); -+ PGSR3 |= 0x8; -+#endif -+#endif -+ -+ KPC |= (KPC_DIE | KPC_MIE); -+ KPKDI = 0x40; -+ return 0; -+} -+ -+static void -+__exit keypad_exit(void) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_exit\n"); -+#endif -+ misc_deregister(&keypad_misc_device); -+ misc_deregister(&keypadB_misc_device); -+ misc_deregister(&keypadI_misc_device); -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+ pm_unregister(keypadI_pm_dev); -+#endif -+#endif -+ -+ CKEN &= ~CKEN19_KEYPAD; -+} -+ -+module_init (keypad_init); -+module_exit (keypad_exit); -Index: linux-2.6.16.5-a/drivers/misc/ezx/keypad-panasonic.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/keypad-panasonic.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,1569 @@ -+/* -+ * linux/drivers/char/keypad.c -+ * -+ * (c) Copyright Motorola 2003, All rights reserved. -+ */ -+ -+/* -+ * This driver is for three devices: /dev/keypad, /dev/keypadB and -+ * /dev/keypadI. -+ * /dev/keypad would be used for reading the key event buffer. -+ * It can be opened by one process at a time. -+ * /dev/keypadB would be used for ioctl(KEYPAD_IOC_GETBITMAP). -+ * It can be opened by one process at a time. -+ * /dev/keypadI would be used for ioctl(KEYPAD_IOC_INSERT_EVENT). -+ * It can be opened any number of times simultaneously. -+ * -+ * The bulverde specification is ambiguous about when interrupts happen -+ * for released keys. We were told by Intel that we won't -+ * get interrupts for released keys except in the case when multiple -+ * keys were down and they've all been released. So we implemented -+ * a timer to poll for changes in key states. -+ * -+ * The E680 P2 hardware gives us interrupts when any key is released, -+ * whether it was the only key down or not, and whether it's the last -+ * of multiple keys to be released or not. We don't know whether this -+ * behavior will continue in future hardware releases, so the release -+ * timer is still in the code, #ifdef'd with USE_RELEASE_TIMER. On the -+ * P2 hardware, the code works with or without USE_RELEASE_TIMER defined. -+ * If the release interrupts are always going to happen, we can remove -+ * the #ifdef'd code. -+ * -+ * With the P2 hardware, the power key bit in the KPDK register is always -+ * on. We don't know if this is correct behavior or not, but in any case -+ * it certainly causes trouble to have that key autorepeating indefinitely, -+ * or to be checking indefinitely for the key to be released (if we're doing -+ * release polling). -+ * -+ * For now, any_keys_down() returns 0 if the power key is the only one down. -+ * . At interrupt time, if the power key is the only one down we don't -+ * set the autorepeat timer or release timer. -+ * . When the release timer goes off, if the power key is the only one -+ * still down we don't set the timer again. -+ * . When the autorepeat timer goes off, if the power key is the only -+ * one down we don't generate any events. -+ * In autorepeat_timer_went_off, if there are non-power keys down, while we're -+ * looking through the whole bitmap of keys down we ignore the power key. -+ */ -+ -+#include <linux/tty.h> -+#include <linux/init.h> -+#include <linux/module.h> -+#include <linux/poll.h> -+#include <linux/miscdevice.h> -+#include <linux/bitops.h> -+#include <linux/param.h> -+ -+#include <asm/hardware.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <linux/pm.h> -+#include <linux/apm_bios.h> -+#include "keypad.h" -+#include <asm/arch/irqs.h> -+#include "asm/arch/ezx.h" -+#include <linux/delay.h> -+ -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+static struct pm_dev *keypadI_pm_dev; -+static int kpc_res,kpkdi_res; -+static int GPIO_TC_MM_STATE = 1; -+extern unsigned char pxafb_ezx_getLCD_status(void); -+#endif -+/* -+ * This is the number of microseconds we wait before checking to see if any -+ * keys have been released. -+ */ -+#define RDELAY 200 -+ -+#define KEYBUF_EMPTY() (keybuf_start == keybuf_end) -+#define KEYBUF_FULL() ( ((keybuf_end+1)%KEYBUF_SIZE) == keybuf_start) -+#define KEYBUF_INC(x) ((x) = (((x)+1) % KEYBUF_SIZE)) -+ -+static int keypad_open (struct inode *, struct file *); -+static int keypad_close (struct inode *, struct file *); -+static int keypad_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+static unsigned int keypad_poll (struct file *, poll_table *); -+static ssize_t keypad_read (struct file *, char *, size_t, loff_t *); -+ -+static int keypadB_open (struct inode *, struct file *); -+static int keypadB_close (struct inode *, struct file *); -+static int keypadB_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+static unsigned int keypadB_poll (struct file *, poll_table *); -+ -+static int keypadI_open(struct inode *, struct file *); -+static int keypadI_close(struct inode *, struct file *); -+static int keypadI_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+ -+static void kp_interrupt (int, void *, struct pt_regs *); -+#ifdef USE_RELEASE_TIMER -+static void release_timer_went_off (unsigned long); -+static void do_scan(void); -+#endif -+static void autorepeat_timer_went_off (unsigned long); -+ -+static int add_to_keybuf (unsigned short); -+static int add_events (unsigned long *, unsigned long *); -+static int insert_event (unsigned short); -+static unsigned short get_from_keybuf (void); -+static void scan_to_bitmap -+ (unsigned long, unsigned long, unsigned long, unsigned long *); -+static inline void set_bitmap_to_zero(unsigned long b[]); -+static inline void copy_bitmap(unsigned long dest[], unsigned long source[]); -+static inline void turn_on_bit(unsigned long map[], int); -+static inline void turn_off_bit(unsigned long map[], int); -+static inline int any_keys_down (unsigned long *); -+ -+/* -+ * keybuf is a circular buffer to hold keypad events. -+ * keybuf_start is the index of the first event. -+ * keybuf_end is one more than the index of the last event. -+ * The buffer is empty when keybuf_start == keybuf_end. -+ * We only use KEYBUF_SIZE-1 entries in the buffer so we can tell -+ * when it's full without needing another variable to tell us. -+ * The buffer is full when (keybuf_end+1)%KEYBUF_SIZE == keybuf_start. -+ */ -+static unsigned short keybuf[KEYBUF_SIZE]; -+static int keybuf_start = 0; -+static int keybuf_end = 0; -+ -+static DECLARE_WAIT_QUEUE_HEAD(keypad_wait); -+static spinlock_t keypad_lock = SPIN_LOCK_UNLOCKED; -+ -+static int reading_opens = 0; -+static int bitmap_opens = 0; -+ -+/* previous bitmap of keys down */ -+static unsigned long oldkeybitmap[NUM_WORDS_IN_BITMAP]; -+/* current bitmap of keys down */ -+static unsigned long keybitmap[NUM_WORDS_IN_BITMAP]; -+/* last bitmap read by ioctl */ -+static unsigned long lastioctlbitmap[NUM_WORDS_IN_BITMAP]; -+ -+static unsigned long kpas = 0; /* last value of kpas */ -+static unsigned long kpasmkp0 = 0; /* last value of kpasmkp0 */ -+static unsigned long kpasmkp1 = 0; /* last value of kpasmkp1 */ -+static unsigned long kpasmkp2 = 0; /* last value of kpasmkp2 */ -+static unsigned long kpdk = 0; /* last value of kpdk */ -+ -+#ifdef USE_RELEASE_TIMER -+static struct timer_list key_release_timer; -+static int key_release_interval = RDELAY * HZ/1000; -+#endif -+ -+static int do_autorepeat = 1; -+static long jiffies_to_first_repeat = 30; -+static long jiffies_to_next_repeat = 30; -+static struct timer_list autorepeat_timer; -+ -+extern int lockscreen_flag; -+ -+static int -+keypad_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypad_open\n"); -+#endif -+ spin_lock(keypad_lock); -+ if (reading_opens > 0) -+ { -+ spin_unlock(keypad_lock); -+ return -EBUSY; -+ } -+ reading_opens++; -+ spin_unlock(keypad_lock); -+ -+ return 0; -+} -+ -+static int -+keypadB_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypadB_open\n"); -+#endif -+ spin_lock(keypad_lock); -+ if (bitmap_opens > 0) -+ { -+ spin_unlock(keypad_lock); -+ return -EBUSY; -+ } -+ bitmap_opens++; -+ /* -+ * poll returns when lastioctlbitmap is different from keybitmap. -+ * we set lastioctlbitmap to keybitmap here so that a poll right -+ * after an open returns when the bitmap is different from when -+ * the open was done, not when the bitmap is different from the -+ * last time some other process read it -+ */ -+ copy_bitmap(lastioctlbitmap, keybitmap); -+ spin_unlock(keypad_lock); -+ -+ return 0; -+} -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+static int keypadI_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ break; -+ case PM_RESUME: -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ if(GPIO_TC_MM_STATE == 1) -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ else -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+#endif -+ -+static int -+keypadI_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypadI_open\n"); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ -+ return 0; -+} -+ -+static int -+keypad_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_close\n"); -+#endif -+ /* -+ * this decrement of reading_opens doesn't have to be protected because -+ * it can only be executed to close the single open of /dev/keypad -+ */ -+ reading_opens--; -+ return 0; -+} -+ -+static int -+keypadB_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadB_close\n"); -+#endif -+ /* -+ * this decrement of bitmap_opens doesn't have to be protected because -+ * it can only be executed to close the single open of /dev/keypadB -+ */ -+ bitmap_opens--; -+ return 0; -+} -+ -+static int -+keypadI_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadI_close\n"); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ -+ return 0; -+} -+ -+/** -+ * Add the specified event to the key buffer. -+ * This should be called with keypad_lock locked. -+ */ -+static int -+add_to_keybuf (unsigned short event) -+{ -+ if (KEYBUF_FULL()) -+ { -+ return -ENOMEM; -+ } -+ keybuf[keybuf_end] = event; -+ KEYBUF_INC (keybuf_end); -+ -+#if CONFIG_APM -+ queue_apm_event(KRNL_KEYPAD, NULL); -+#endif -+ printk("add keypad event = %x\n", event); -+ return 0; -+} -+ -+/* -+ * code[c*8+r] is the key code for the key that's down when there's a 1 -+ * in column c, row r of the scan registers. -+ */ -+ -+#if defined(CONFIG_KEYPAD_V700) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_LEFT, KEYPAD_RIGHT, -+ KEYPAD_POUND, KEYPAD_0, KEYPAD_9, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_2, KEYPAD_4, KEYPAD_6, KEYPAD_8, -+ KEYPAD_7, KEYPAD_SLEFT, KEYPAD_SRIGHT, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_MENU, KEYPAD_1, KEYPAD_3, KEYPAD_5, -+ KEYPAD_STAR, KEYPAD_VOLUP, KEYPAD_VOLDOWN, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_CAMERA, KEYPAD_CLEAR, KEYPAD_CARRIER, KEYPAD_ACTIVATE, -+ KEYPAD_SEND, KEYPAD_SMART, KEYPAD_VAVR, KEYPAD_NONE -+}; -+ -+/* end CONFIG_KEYPAD_V700 */ -+#elif defined(CONFIG_E680_P4A) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_LEFT, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_RIGHT, KEYPAD_CENTER, KEYPAD_HOME, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_GAME_R, KEYPAD_NONE, KEYPAD_GAME_L, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_A, KEYPAD_B, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+}; -+ -+/* end CONFIG_E680_P4A */ -+#elif defined(CONFIG_KEYPAD_E680) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_RIGHT, KEYPAD_LEFT, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_NONE, KEYPAD_GAME_R, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_HOME, KEYPAD_GAME_L, KEYPAD_CENTER, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ -+}; -+/*end CONFIG_KEYPAD_E680 */ -+#elif defined(CONFIG_KEYPAD_A780) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_OK, KEYPAD_1, KEYPAD_4, KEYPAD_7, -+ KEYPAD_STAR, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_MENU, KEYPAD_2, KEYPAD_5, KEYPAD_8, -+ KEYPAD_0, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_CANCEL, KEYPAD_3, KEYPAD_6, KEYPAD_9, -+ KEYPAD_POUND, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_JOG_UP, KEYPAD_JOG_MIDDLE, KEYPAD_PTT, KEYPAD_NONE, -+ KEYPAD_JOG_DOWN, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 4 */ -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_HOME, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+}; -+#endif -+ -+/* -+ * Decode the specified scan register values into the bitmap pointed -+ * to by the last argument. The bitmap will contain a 1 -+ * for each key that's down. -+ * -+ * Only the 1st two of the four scan registers are used. -+ */ -+static void -+scan_to_bitmap(unsigned long kpas, unsigned long kpasmkp0, -+ unsigned long kpasmkp1, unsigned long bitmap[]) -+{ -+ int row, col; -+ int bitnum; -+ unsigned long scanmap; -+ -+ set_bitmap_to_zero (bitmap); -+ -+ if ((kpas & KPAS_MUKP) == MUKP_NO_KEYS) -+ { -+ return; -+ } -+ -+ if ((kpas & KPAS_MUKP) == MUKP_ONE_KEY) -+ { -+ row = (kpas & KPAS_RP) >> 4; -+ col = kpas & KPAS_CP; -+#if defined(CONFIG_KEYPAD_A780) -+ if( !((row == 3)&&(col == 3)) ) -+ { -+#endif -+ turn_on_bit (bitmap, scanbit_to_keycode[col*8 + row]); -+#if defined(CONFIG_KEYPAD_A780) -+ } -+#endif -+ -+ return; -+ } -+ -+ /* reach here if multiple keys */ -+ scanmap = (kpasmkp0 & 0x7f) | ((kpasmkp0 & 0x7f0000) >> 8) | -+ ((kpasmkp1 & 0x7f) << 16) | ((kpasmkp1 & 0x7f0000) << 8); -+ while ((bitnum = ffs(scanmap)) != 0) -+ { -+ /* -+ * ffs returns bit numbers starting with 1, so subtract 1 to index -+ * into scanbit_to_keycode[] -+ */ -+ turn_on_bit (bitmap, scanbit_to_keycode[bitnum-1]); -+ scanmap &= ~(1<<(bitnum-1)); -+ } -+#if defined(CONFIG_KEYPAD_A780) -+ kpasmkp2 = KPASMKP2; -+ kpasmkp2 &= 0x8; -+ while ((bitnum = ffs(kpasmkp2)) !=0) -+ { -+ turn_on_bit (bitmap, scanbit_to_keycode[32+bitnum-1]); -+ kpasmkp2 &= ~(1<<(bitnum-1)); -+ } -+#endif -+} -+ -+/* -+ * Add events indicated by the difference between the last scan (oldbitmap) -+ * and this one (newbitmap) to the input buffer. -+ * Return nonzero right away if any of the events can't be added. -+ * A zero return means all the events were added. -+ * This should be called with keypad_lock locked. -+ */ -+static int -+add_events (unsigned long *oldbitmap, unsigned long *newbitmap) -+{ -+ unsigned long tmpmap, onebitmap; -+ int bitnum, i, ret; -+ -+ /* generate events for keys that were down before and are up now */ -+ for (i=NUM_WORDS_IN_BITMAP-1;i>=0;i--) -+ { -+ tmpmap = oldbitmap[i]; -+ while ((bitnum = ffs(tmpmap)) != 0) -+ { -+ onebitmap = 1<<(bitnum-1); -+ if ((newbitmap[i] & onebitmap) == 0) -+ { -+ ret = add_to_keybuf(bitnum + (32*(NUM_WORDS_IN_BITMAP-1-i) | KEYUP)); -+ if (ret < 0) -+ { -+ return ret; -+ } -+ } -+ tmpmap &= ~onebitmap; -+ } -+ } -+ /* generate events for down keys that were up before */ -+ for (i=NUM_WORDS_IN_BITMAP-1;i>=0;i--) -+ { -+ tmpmap = newbitmap[i]; -+ while ((bitnum = ffs(tmpmap)) != 0) -+ { -+ onebitmap = 1<<(bitnum-1); -+ if ((oldbitmap[i] & onebitmap) == 0) -+ { -+ ret = add_to_keybuf -+ (bitnum + (32*(NUM_WORDS_IN_BITMAP-1-i) | KEYDOWN)); -+ if (ret < 0) -+ { -+ return ret; -+ } -+ } -+ tmpmap &= ~onebitmap; -+ } -+ } -+ return 0; -+} -+ -+/* -+ * do the INSERT_EVENT ioctl -+ */ -+static int -+insert_event (unsigned short event) -+{ -+ unsigned long flags; -+ int ret; -+ -+ if (KEYCODE(event) > KEYPAD_MAXCODE) -+ { -+ printk(KERN_WARNING " inserted key code %d too big\n", -+ KEYCODE(event)); -+ return -EINVAL; -+ } -+ spin_lock_irqsave(&keypad_lock, flags); -+ if (KEY_IS_DOWN(event)) -+ { -+ turn_on_bit(keybitmap, KEYCODE(event)); -+ } -+ else -+ { -+ turn_off_bit (keybitmap, event); -+ } -+ if ((ret = add_to_keybuf(event)) < 0) -+ { -+ spin_unlock_irqrestore(&keypad_lock,flags); -+ return ret; -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ return 0; -+} -+ -+static int -+keypad_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int interval; /* debounce interval */ -+ int imkp; /* Ignore Multiple Key Press bit */ -+ struct autorepeatinfo ar; /* autorepeat information */ -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypad_ioctl: 0x%x\n", cmd); -+#endif -+ switch (cmd) -+ { -+ case KEYPAD_IOC_INSERT_EVENT: -+ return insert_event ((unsigned short)arg); -+ break; -+ case KEYPAD_IOC_GET_DEBOUNCE_INTERVAL: -+ interval = KPKDI & KPKDI_BITS; -+ return put_user(interval, (unsigned long *)arg); -+ break; -+ case KEYPAD_IOC_SET_DEBOUNCE_INTERVAL: -+ interval = (unsigned short)arg; -+ if (interval > KPKDI_BITS) -+ { -+ return -EINVAL; -+ } -+ KPKDI &= ~KPKDI_BITS; -+ KPKDI |= interval; -+ break; -+ case KEYPAD_IOC_GET_IMKP_SETTING: -+ imkp = ((KPC & KPC_IMKP) == KPC_IMKP); -+ return put_user(imkp, (unsigned char *)arg); -+ break; -+ case KEYPAD_IOC_SET_IMKP_SETTING: -+ imkp = (unsigned char)arg; -+ if (imkp) -+ { -+ KPC |= KPC_IMKP; -+ } -+ else -+ { -+ KPC &= ~KPC_IMKP; -+ } -+ break; -+ case KEYPAD_IOC_SET_AUTOREPEAT: -+ if (copy_from_user (&ar, (void *)arg, -+ sizeof(struct autorepeatinfo)) != 0) -+ { -+ return -EFAULT; -+ } -+ do_autorepeat = ar.r_repeat; -+ /* times are specified in milliseconds; convert to jiffies */ -+ jiffies_to_first_repeat = ar.r_time_to_first_repeat * HZ/1000; -+ jiffies_to_next_repeat = ar.r_time_between_repeats * HZ/1000; -+ break; -+ default: -+ return -ENOTTY; -+ } -+ return 0; -+} -+ -+static int -+keypadB_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned long flags; -+ int ret; -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypadB_ioctl: 0x%x\n", cmd); -+#endif -+ if (cmd == KEYPAD_IOC_INSERT_EVENT) -+ { -+ return insert_event ((unsigned short)arg); -+ } -+ else if (cmd == KEYPAD_IOC_GETBITMAP) -+ { -+ spin_lock_irqsave(&keypad_lock, flags); -+ ret = copy_to_user ((void *)arg, keybitmap, -+ NUM_WORDS_IN_BITMAP * sizeof(unsigned long)); -+ copy_bitmap (lastioctlbitmap, keybitmap); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return (ret != 0) ? -EFAULT : 0; -+ } -+ else -+ { -+ return -ENOTTY; -+ } -+} -+ -+static int -+keypadI_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned long flags; -+ int ret; -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypadI_ioctl: 0x%x\n", cmd); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ if( cmd == KEYPADI_TURN_ON_LED ) -+ { -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ GPIO_TC_MM_STATE = 0; -+ PGSR3 &= ~GPIO_bit(GPIO_TC_MM_EN); -+ return 0; -+ } -+ if( cmd == KEYPADI_TURN_OFF_LED ) -+ { -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ GPIO_TC_MM_STATE = 1; -+ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); -+ return 0; -+ } -+#endif -+ -+ if (cmd == KEYPAD_IOC_INSERT_EVENT) -+ { -+ return insert_event ((unsigned short)arg); -+ } -+ else if (cmd == KEYPAD_IOC_GETBITMAP) -+ { -+ spin_lock_irqsave(&keypad_lock, flags); -+ ret = copy_to_user ((void *)arg, keybitmap, -+ NUM_WORDS_IN_BITMAP * sizeof(unsigned long)); -+ copy_bitmap (lastioctlbitmap, keybitmap); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return (ret != 0) ? -EFAULT : 0; -+ } -+ else -+ { -+ return -ENOTTY; -+ } -+} -+ -+static unsigned int -+keypad_poll( struct file *file, poll_table * wait ) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_poll\n"); -+#endif -+ poll_wait(file, &keypad_wait, wait); -+ -+ if (!KEYBUF_EMPTY()) -+ { -+ return (POLLIN | POLLRDNORM); -+ } -+ return 0; -+} -+ -+static unsigned int -+keypadB_poll( struct file *file, poll_table * wait ) -+{ -+ int i; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadB_poll\n"); -+#endif -+ poll_wait(file, &keypad_wait, wait); -+ -+ for (i=0; i < NUM_WORDS_IN_BITMAP; i++) -+ { -+ if (lastioctlbitmap[i] != keybitmap[i]) -+ { -+ return (POLLIN | POLLRDNORM); -+ } -+ } -+ return 0; -+} -+ -+static unsigned short -+get_from_keybuf(void) -+{ -+ unsigned short event; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock, flags); -+ event = keybuf[keybuf_start]; -+ KEYBUF_INC (keybuf_start); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return event; -+} -+ -+static ssize_t -+keypad_read(struct file *file, char *buf, size_t count, loff_t *ptr) -+{ -+ int i, ret; -+ unsigned short event; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_read\n"); -+#endif -+ /* Can't seek (pread) on this device */ -+ if (ptr != &file->f_pos) -+ { -+ return -ESPIPE; -+ } -+ -+ if (count == 0) -+ { -+ return 0; -+ } -+ -+ if (KEYBUF_EMPTY()) -+ { -+ /* buffer is empty */ -+ /* if not blocking return */ -+ if (file->f_flags & O_NONBLOCK) -+ { -+ return -EAGAIN; -+ } -+ /* blocking, so wait for input */ -+ ret = wait_event_interruptible(keypad_wait, !KEYBUF_EMPTY()); -+ if (ret) -+ { -+ return ret; -+ } -+ } -+ -+ i = 0; -+ /* copy events until we have what the user asked for or we run out */ -+ while ((i+1 < count) && !KEYBUF_EMPTY()) -+ { -+ event = get_from_keybuf(); -+ if ((ret = put_user(event, (unsigned short *)buf)) != 0) -+ { -+ return ret; -+ } -+ buf += EVENTSIZE; -+ i += EVENTSIZE; -+ } -+ return i; -+} -+ -+#ifdef CONFIG_PM -+static int button_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ int pksr; -+ -+ pksr = PKSR; -+ PKSR = 0xfffff; -+ switch(req) -+ { -+ case PM_SUSPEND: -+ kpc_res = KPC; -+ kpkdi_res = KPKDI; -+ set_bitmap_to_zero (oldkeybitmap); -+ set_bitmap_to_zero (keybitmap); -+ set_bitmap_to_zero (lastioctlbitmap); -+ kpas = 0; -+ kpasmkp0 = 0; -+ kpasmkp1 = 0; -+ kpasmkp2 = 0; -+ kpdk = 0; -+ break; -+ case PM_RESUME: -+ KPC = kpc_res; -+ KPKDI = kpkdi_res; -+#if CONFIG_APM -+#if defined(CONFIG_E680_P4A) -+ if (pksr & 0xe4400) /*93 97 100 101 102 key is pressed (switch on) */ -+ { -+ queue_apm_event(KRNL_KEYPAD, NULL); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ if (pksr & 0xee400) /*93 96 97 98 190 101 102 key is pressed */ -+ { -+ queue_apm_event(KRNL_KEYPAD, NULL); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ if (pksr & 0x2000) -+ turn_on_bit (keybitmap, KEYPAD_A); -+ if (pksr & 0x8000) -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+ printk("pksr = %x\n",pksr); -+ if (pksr & 0xec400) /* 93 97 98 100 101 102 key is pressed */ -+ { -+ queue_apm_event(KRNL_KEYPAD, NULL); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#endif -+ -+ break; -+ } -+ return 0; -+} -+#endif -+ -+/* for /dev/keypad */ -+static struct file_operations -+keypad_fops = { -+ read: keypad_read, -+ llseek: no_llseek, -+ poll: keypad_poll, -+ ioctl: keypad_ioctl, -+ open: keypad_open, -+ release: keypad_close, -+}; -+ -+static struct miscdevice -+keypad_misc_device = { -+ KEYPAD_MINOR, -+ KEYPAD_NAME, -+ &keypad_fops, -+}; -+ -+/* -+ * for /dev/keypadB. -+ * read() isn't defined here. calls to read() will return -1 with EINVAL. -+ */ -+static struct file_operations -+keypadB_fops = { -+ llseek: no_llseek, -+ poll: keypadB_poll, -+ ioctl: keypadB_ioctl, -+ open: keypadB_open, -+ release: keypadB_close, -+}; -+ -+static struct miscdevice -+keypadB_misc_device = { -+ KEYPAD_BITMAP_MINOR, -+ KEYPAD_BITMAP_NAME, -+ &keypadB_fops, -+}; -+ -+/* -+ * for /dev/keypadI. -+ * read() isn't defined here. calls to read() will return -1 with EINVAL. -+ */ -+static struct file_operations -+keypadI_fops = { -+ llseek: no_llseek, -+ ioctl: keypadI_ioctl, -+ open: keypadI_open, -+ release: keypadI_close, -+}; -+ -+static struct miscdevice -+keypadI_misc_device = { -+ KEYPAD_INSERT_MINOR, -+ KEYPAD_INSERT_NAME, -+ &keypadI_fops, -+}; -+ -+#ifdef CONFIG_PANIC_LOG -+static u32 panic_bug_used =0; -+static int panic_key = 0; -+#endif -+ -+/* Interrupt Handler for KEYPAD */ -+static void -+kp_interrupt(int irq, void *ptr, struct pt_regs *regs) -+{ -+ unsigned long flags; -+ unsigned long kpc_val; -+ -+#ifdef USE_RELEASE_TIMER -+ del_timer (&key_release_timer); -+#endif -+ del_timer (&autorepeat_timer); -+ spin_lock_irqsave(&keypad_lock,flags); -+ -+ /* ack interrupt */ -+ kpc_val = KPC; -+ -+ /* matrix interrupt */ -+ if (kpc_val & KPC_MI) -+ { -+/* -+ * The Intel driver turned on KPC_AS here. It doesn't seem that we -+ * would need to do that, because getting an interrupt means that -+ * a scan was just done. For now, I've commented out the setting -+ * and clearing of this bit. -+ KPC |= KPC_AS; -+ */ -+ while (KPAS & KPAS_SO) -+ { -+ /* Wait for the Scan On bit to go off before */ -+ /* reading the scan registers. */ -+ NULL; -+ }; -+ -+ kpas = KPAS; -+ kpasmkp0 = KPASMKP0; -+ kpasmkp1 = KPASMKP1; -+ kpasmkp2 = KPASMKP2; -+ -+ } -+ -+ /* direct interrupt */ -+ if (kpc_val & KPC_DI) -+ { -+ kpdk = KPDK; -+ /* -+ * reading the register turns off the "key pressed since last read" -+ * bit if it was on, so we turn it off -+ */ -+ kpdk &= ~KPDK_DKP; -+ } -+ -+ copy_bitmap (oldkeybitmap, keybitmap); -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* VR key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+#elif defined(CONFIG_KEYPAD_E680) -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1, keybitmap); -+ if (kpdk & KPDK_DK0) /* VR key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+ if (kpdk & KPDK_DK3) -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+ -+#elif defined(CONFIG_KEYPAD_A780) -+#ifdef CONFIG_PANIC_LOG -+ panic_key = 0; -+#endif -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1 & 0xfff7ffff, keybitmap); -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+#ifdef CONFIG_PANIC_LOG -+ panic_key = 1; -+#endif -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+ kpasmkp2 = KPASMKP2; -+ if ( (kpasmkp2 & 0x17) || (kpasmkp1 & 0x80000) ) -+ { -+ if( kpasmkp2 == 0x5 && kpasmkp1 == 0x80000 ) -+ { -+ printk("Jay Up key pressed\n"); -+ turn_on_bit(keybitmap, KEYPAD_UP); -+ } -+ else -+ { -+ if( kpasmkp2 == 0x14 && kpasmkp1 == 0x80000) -+ { -+ printk("Jay Right key pressed\n"); -+ turn_on_bit(keybitmap, KEYPAD_RIGHT); -+ } -+ else -+ { -+ if( kpasmkp2 == 0x12 && kpasmkp1 == 0x80000) -+ { -+ printk("Jay Down key pressed\n"); -+ turn_on_bit(keybitmap, KEYPAD_DOWN); -+ } -+ else -+ { -+ if( kpasmkp2 == 0x3 && kpasmkp1 == 0x80000) -+ { -+ printk("Jay Left key pressed\n"); -+ turn_on_bit(keybitmap, KEYPAD_LEFT); -+ } -+ else -+ { -+ if( kpasmkp1 == 0x80000 && (kpasmkp2 & 0x17) == 0) -+ -+ { -+ printk("Jay Center key pressed\n"); -+ turn_on_bit(keybitmap, KEYPAD_CENTER); -+ } -+ } -+ } -+ } -+ } -+ } -+#endif -+ -+ -+ (void) add_events (oldkeybitmap, keybitmap); -+ -+ /* If any keys are down, set a timer to check for key release */ -+ /* and one for autorepeat if that's on. */ -+ if (any_keys_down (keybitmap)) -+ { -+#ifdef USE_RELEASE_TIMER -+ key_release_timer.expires = (jiffies + key_release_interval); -+ add_timer (&key_release_timer); -+#endif -+ if (do_autorepeat) -+ { -+ autorepeat_timer.expires = (jiffies + jiffies_to_first_repeat); -+ add_timer (&autorepeat_timer); -+ } -+ } -+ -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ printk("keypad interrupt occurred\n"); -+} -+ -+#ifdef USE_RELEASE_TIMER -+/* -+ * This is called when the key release timer goes off. That's the -+ * only time it should be called. Check for changes in what keys -+ * are down. -+ */ -+static void -+release_timer_went_off(unsigned long unused) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock,flags); -+ do_scan(); -+ /* If any keys are still down, set the timer going again. */ -+ if (any_keys_down (keybitmap)) -+ { -+ mod_timer (&key_release_timer, jiffies + key_release_interval); -+ } -+ else -+ { -+ del_timer (&autorepeat_timer); -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+} -+#endif -+ -+/* -+ * This is called when the autorepeat timer goes off. -+ */ -+static void -+autorepeat_timer_went_off(unsigned long unused) -+{ -+ int i, bitnum; -+ unsigned long tmp; -+ unsigned long flags; -+ -+#ifdef CONFIG_PANIC_LOG -+ int temp_key; -+ if( panic_key == 1 ) -+ { -+ kpc_res = KPC; -+ /* Initiate a manual scan */ -+ KPC &= ~(KPC_AS | KPC_ASACT | KPC_MIE | KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7); -+ /* reading the scan registers. */ -+ KPC |= 0x10000; -+ mdelay(0x64); -+ temp_key = KPMK & 0xff; -+// KPC |= (KPC_ASACT | KPC_MS0 | KPC_MS1 | KPC_MS2 | KPC_MS3 | KPC_MS4 | KPC_MS5 | KPC_MS6 | KPC_MS7); -+ KPC = kpc_res; -+ -+ printk("temp_key = %x\n", temp_key); -+ -+ if ( temp_key == 0x2 ) -+ { -+ if(0 == panic_bug_used) -+ { -+ panic_bug_used = 1; -+ BUG(); -+ } -+ } -+ } -+#endif -+ -+ spin_lock_irqsave(&keypad_lock,flags); -+ if (!any_keys_down (keybitmap)) -+ { -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return; -+ } -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ tmp = keybitmap[NUM_WORDS_IN_BITMAP-i-1]; -+ while ((bitnum = ffs(tmp)) != 0) -+ { -+ tmp &= ~(1<<(bitnum-1)); -+ /* see explanation at top of file */ -+ if ( (bitnum + (32*i)) == KEYPAD_POWER ) -+ { -+ continue; -+ } -+ (void) add_to_keybuf( (bitnum + (32*i)) | KEYDOWN ); -+ } -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ -+ mod_timer (&autorepeat_timer, jiffies + jiffies_to_next_repeat); -+} -+ -+#ifdef USE_RELEASE_TIMER -+/* -+ * Do a scan and add key events for anything that's different from the -+ * last scan. We assume keypad_lock is locked when this is called -+ * (by release_timer_went_off). -+ */ -+static void -+do_scan(void) -+{ -+ unsigned long kpas_new, kpasmkp0_new, kpasmkp1_new; -+ unsigned long kpdk_new; -+ int change; -+ -+ /* Initiate an automatic scan */ -+ KPC |= KPC_AS; -+ /* Wait for the Scan On bit to go off before */ -+ /* reading the scan registers. */ -+ while (KPAS & KPAS_SO) -+ { -+ NULL; -+ }; -+ kpas_new = KPAS; -+ kpasmkp0_new = KPASMKP0; -+ kpasmkp1_new = KPASMKP1; -+ kpdk_new = KPDK; -+ /* -+ * reading the register turns off the "key pressed since last read" bit -+ * if it was on, so we turn it off -+ */ -+ kpdk_new &= ~KPDK_DKP; -+ KPC &= ~KPC_AS; -+ -+ change = ((kpas_new != kpas) || -+ (kpasmkp0_new != kpasmkp0) || -+ (kpasmkp1_new != kpasmkp1) || -+ (kpdk_new != kpdk)); -+ -+ if (change) -+ { -+ kpas = kpas_new; -+ kpasmkp0 = kpasmkp0_new; -+ kpasmkp1 = kpasmkp1_new; -+ kpdk = kpdk_new; -+ -+ copy_bitmap (oldkeybitmap, keybitmap); -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1, keybitmap); -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* screen lock key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* screen lock key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+ if (kpdk & KPDK_DK3) -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+ -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ add_events (oldkeybitmap, keybitmap); -+ -+ wake_up_interruptible (&keypad_wait); -+ } -+} -+#endif -+ -+/* -+ * set all words in the specified bitmap to 0 -+ */ -+static inline void set_bitmap_to_zero(unsigned long b[]) { -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ b[i]=0; -+ } -+} -+ -+/* -+ * copy source bitmap to destination bitmap -+ */ -+static inline void copy_bitmap(unsigned long dest[], unsigned long source[]) { -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ dest[i]=source[i]; -+ } -+} -+ -+/* -+ * Turn on the bit position in map for the specified key code. -+ * Bit numbers start with 1 (not 0) and increase moving left within -+ * words and within the array. -+ * Bit 1 is the rightmost bit in map[NUM_WORDS_IN_BITMAP-1]. -+ * Bit 33 is the rightmost bit in map[NUM_WORDS_IN_BITMAP-2]. -+ */ -+static inline void -+turn_on_bit(unsigned long map[], int code) -+{ -+ int word, pos, p; -+ -+ /* if we have 2 words, bits 1-32 are in map[1], 33-64 in map[0] */ -+ word = (NUM_WORDS_IN_BITMAP - 1) - ((code-1) / 32); -+ /* -+ * bit 1 is 1<<0, bit 2 is 1<<1, ... bit 32 is 1 << 31, all in map[1] -+ * bit 33 is 1<<0, bit 34 is 1<<1, ... in map[0] -+ * we want this: -+ * code pos -+ * 1 0 -+ * 2 1 -+ * ... -+ * 31 30 -+ * 32 31 -+ * 33 0 -+ * 34 1 -+ * ... -+ */ -+ pos = (p = (code % 32)) == 0 ? 31 : p-1; -+ map[word] |= (1<<pos); -+} -+ -+/* -+ * Turn off the bit position in map for the specified key code. -+ * Bit positions start with 1 (not 0). -+ */ -+static inline void -+turn_off_bit(unsigned long map[], int code) -+{ -+ int word, pos, p; -+ -+ word = (NUM_WORDS_IN_BITMAP - 1) - ((code-1) / 32); -+ pos = (p = (code % 32)) == 0 ? 31 : p-1; -+ map[word] &= ~(1<<pos); -+} -+ -+/* -+ * Return 1 if any bits are down in map[] -+ */ -+static inline int -+any_keys_down (unsigned long *map) -+{ -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ /* don't count the power key */ -+ if ((i == 0) && (*map == 0x10)) -+ { -+ map++; -+ continue; -+ } -+ if (*map++) -+ { -+ return 1; -+ } -+ } -+ return 0; -+} -+static int -+__init keypad_init(void) -+{ -+ int err; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_init\n"); -+#endif -+ -+ set_bitmap_to_zero (oldkeybitmap); -+ set_bitmap_to_zero (keybitmap); -+ set_bitmap_to_zero (lastioctlbitmap); -+ -+ /* set up gpio */ -+#if defined(CONFIG_KEYPAD_V700) -+ pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN); /* KP_MKIN<6> */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_MKIN<3> */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_MKIN<4> */ -+ pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); /* KP_MKIN<5> */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#elif defined(CONFIG_E680_P4A) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#elif defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -+ pxa_gpio_mode(96 | GPIO_ALT_FN_1_IN); /* KP_DKIN<3>, GAME_A */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_DKIN<5>, GAME_B */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); -+#elif defined(CONFIG_KEYPAD_A780) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, voice_rec */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_3_IN); /* KP_MKIN<3> */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_3_IN); /* KP_MKIN<4> */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+ pxa_gpio_mode(107 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<4> */ -+#elif defined(CONFIG_KEYPAD_MAINSTONE) -+ /* from Intel driver */ -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(94 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#endif -+ -+ /* set keypad control register */ -+ KPC = (KPC_ASACT | /* automatic scan on activity */ -+ KPC_ME | KPC_DE | /* matrix and direct keypad enabled */ -+#if defined(CONFIG_KEYPAD_V700) -+ (3<<23) | /* 4 columns */ -+ (6<<26) | /* 7 rows */ -+#elif defined(CONFIG_E680_P4A) -+ (3<<23) | /* 4 columns */ -+ (2<<26) | /* 3 rows */ -+ (4<<6) | /* 4# direct key */ -+#elif defined(CONFIG_KEYPAD_E680) -+ (5<<23) | /* 4 columns */ -+ (4<<26) | /* 3 rows */ -+ (5<<6) | /* 5# direct keys */ -+#elif defined(CONFIG_KEYPAD_A780) -+ KPC_IMKP | -+ (4<<23) | /* 5 columns */ -+ (4<<26) | /* 5 rows */ -+ (0<<6) | /* 1# direct keys */ -+#endif -+ KPC_MS7_0); /* scan all columns */ -+ -+ CKEN |= CKEN19_KEYPAD; -+ -+ err = request_irq (IRQ_KEYPAD, kp_interrupt, 0, "Keypad", NULL); -+ if (err) -+ { -+ printk (KERN_CRIT "can't register IRQ%d for keypad, error %d\n", -+ IRQ_KEYPAD, err); -+ CKEN &= ~CKEN19_KEYPAD; -+ return -ENODEV; -+ } -+ -+ if (misc_register (&keypad_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypad driver\n"); -+ return -EIO; -+ } -+ if (misc_register (&keypadB_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypadB driver\n"); -+ misc_deregister(&keypad_misc_device); -+ return -EIO; -+ } -+ if (misc_register (&keypadI_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypadI driver\n"); -+ misc_deregister(&keypad_misc_device); -+ misc_deregister(&keypadB_misc_device); -+ return -EIO; -+ } -+ -+#ifdef USE_RELEASE_TIMER -+ init_timer (&key_release_timer); -+ key_release_timer.function = release_timer_went_off; -+#endif -+ init_timer (&autorepeat_timer); -+ autorepeat_timer.function = autorepeat_timer_went_off; -+ -+ /* -+ * we want the phone to be able to tell the status of the screen -+ * lock switch at power-up time -+ */ -+ kpdk = KPDK; /* read direct key register */ -+ /* -+ * reading the register turns off the "key pressed since last read" bit -+ * if it was on, so we turn it off -+ */ -+ kpdk &= ~KPDK_DKP; -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* VR key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) /* Power key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* VR key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) /* Power key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ if (kpdk & KPDK_DK3) /* GAME_A key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) /* GAME_B key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, button_pm_callback); -+#if defined(CONFIG_E680_P4A) -+/*93,97,100,101,102*/ -+ PKWR = 0xe4400; -+/*103 104 105 106*/ -+ PGSR3 |= 0x780; -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+/*93,96,97,98,100,101,102*/ -+ PKWR = 0xee400; -+/*103 104 105 106*/ -+ PGSR3 |= 0x780; -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+/*93,97,98,100,101,102*/ -+ PKWR = 0xec400; -+/*103 104 105 106 107*/ -+ PGSR3 |= 0xf80; -+#endif -+#endif -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+ keypadI_pm_dev = pm_register(PM_SYS_DEV, 0, keypadI_pm_callback); -+ PGSR3 |= 0x8; -+#endif -+#endif -+ -+ KPC |= (KPC_DIE | KPC_MIE); -+ KPKDI = 0x40; -+ return 0; -+ -+} -+ -+static void -+__exit keypad_exit(void) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_exit\n"); -+#endif -+ misc_deregister(&keypad_misc_device); -+ misc_deregister(&keypadB_misc_device); -+ misc_deregister(&keypadI_misc_device); -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+ pm_unregister(keypadI_pm_dev); -+#endif -+#endif -+ -+ CKEN &= ~CKEN19_KEYPAD; -+} -+ -+module_init (keypad_init); -+module_exit (keypad_exit); -Index: linux-2.6.16.5-a/drivers/misc/ezx/keypad.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/keypad.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,1499 @@ -+/* -+ * linux/drivers/char/keypad.c -+ * -+ * (c) Copyright Motorola 2003, All rights reserved. -+ */ -+ -+/* -+ * This driver is for three devices: /dev/keypad, /dev/keypadB and -+ * /dev/keypadI. -+ * /dev/keypad would be used for reading the key event buffer. -+ * It can be opened by one process at a time. -+ * /dev/keypadB would be used for ioctl(KEYPAD_IOC_GETBITMAP). -+ * It can be opened by one process at a time. -+ * /dev/keypadI would be used for ioctl(KEYPAD_IOC_INSERT_EVENT). -+ * It can be opened any number of times simultaneously. -+ * -+ * The bulverde specification is ambiguous about when interrupts happen -+ * for released keys. We were told by Intel that we won't -+ * get interrupts for released keys except in the case when multiple -+ * keys were down and they've all been released. So we implemented -+ * a timer to poll for changes in key states. -+ * -+ * The E680 P2 hardware gives us interrupts when any key is released, -+ * whether it was the only key down or not, and whether it's the last -+ * of multiple keys to be released or not. We don't know whether this -+ * behavior will continue in future hardware releases, so the release -+ * timer is still in the code, #ifdef'd with USE_RELEASE_TIMER. On the -+ * P2 hardware, the code works with or without USE_RELEASE_TIMER defined. -+ * If the release interrupts are always going to happen, we can remove -+ * the #ifdef'd code. -+ * -+ * With the P2 hardware, the power key bit in the KPDK register is always -+ * on. We don't know if this is correct behavior or not, but in any case -+ * it certainly causes trouble to have that key autorepeating indefinitely, -+ * or to be checking indefinitely for the key to be released (if we're doing -+ * release polling). -+ * -+ * For now, any_keys_down() returns 0 if the power key is the only one down. -+ * . At interrupt time, if the power key is the only one down we don't -+ * set the autorepeat timer or release timer. -+ * . When the release timer goes off, if the power key is the only one -+ * still down we don't set the timer again. -+ * . When the autorepeat timer goes off, if the power key is the only -+ * one down we don't generate any events. -+ * In autorepeat_timer_went_off, if there are non-power keys down, while we're -+ * looking through the whole bitmap of keys down we ignore the power key. -+ */ -+ -+#include <linux/tty.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/poll.h> -+#include <linux/miscdevice.h> -+#include <linux/bitops.h> -+#include <linux/param.h> -+ -+#include <asm/hardware.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <linux/pm.h> -+#include <linux/apm_bios.h> -+#include "keypad.h" -+#include <asm/arch/irqs.h> -+#include <asm/arch/pxa-regs.h> -+ -+#include <asm/arch/ezx.h> -+ -+#ifdef CONFIG_PM -+static struct pm_dev *pm_dev; -+static struct pm_dev *keypadI_pm_dev; -+static int kpc_res,kpkdi_res; -+#endif -+static int GPIO_TC_MM_STATE = 1; -+/* -+ * This is the number of microseconds we wait before checking to see if any -+ * keys have been released. -+ */ -+#define RDELAY 200 -+ -+#define KEYBUF_EMPTY() (keybuf_start == keybuf_end) -+#define KEYBUF_FULL() ( ((keybuf_end+1)%KEYBUF_SIZE) == keybuf_start) -+#define KEYBUF_INC(x) ((x) = (((x)+1) % KEYBUF_SIZE)) -+ -+static int keypad_open (struct inode *, struct file *); -+static int keypad_close (struct inode *, struct file *); -+static int keypad_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+static unsigned int keypad_poll (struct file *, poll_table *); -+static ssize_t keypad_read (struct file *, char *, size_t, loff_t *); -+ -+static int keypadB_open (struct inode *, struct file *); -+static int keypadB_close (struct inode *, struct file *); -+static int keypadB_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+static unsigned int keypadB_poll (struct file *, poll_table *); -+ -+static int keypadI_open(struct inode *, struct file *); -+static int keypadI_close(struct inode *, struct file *); -+static int keypadI_ioctl (struct inode *, struct file *, -+ unsigned int, unsigned long); -+ -+static irqreturn_t kp_interrupt (int, void *, struct pt_regs *); -+#ifdef USE_RELEASE_TIMER -+static void release_timer_went_off (unsigned long); -+static void do_scan(void); -+#endif -+static void autorepeat_timer_went_off (unsigned long); -+ -+static int add_to_keybuf (unsigned short); -+static int add_events (unsigned long *, unsigned long *); -+static int insert_event (unsigned short); -+static unsigned short get_from_keybuf (void); -+static void scan_to_bitmap -+ (unsigned long, unsigned long, unsigned long, unsigned long *); -+static inline void set_bitmap_to_zero(unsigned long b[]); -+static inline void copy_bitmap(unsigned long dest[], unsigned long source[]); -+static inline void turn_on_bit(unsigned long map[], int); -+static inline void turn_off_bit(unsigned long map[], int); -+static inline int any_keys_down (unsigned long *); -+ -+/* -+ * keybuf is a circular buffer to hold keypad events. -+ * keybuf_start is the index of the first event. -+ * keybuf_end is one more than the index of the last event. -+ * The buffer is empty when keybuf_start == keybuf_end. -+ * We only use KEYBUF_SIZE-1 entries in the buffer so we can tell -+ * when it's full without needing another variable to tell us. -+ * The buffer is full when (keybuf_end+1)%KEYBUF_SIZE == keybuf_start. -+ */ -+static unsigned short keybuf[KEYBUF_SIZE]; -+static int keybuf_start = 0; -+static int keybuf_end = 0; -+ -+static DECLARE_WAIT_QUEUE_HEAD(keypad_wait); -+static spinlock_t keypad_lock = SPIN_LOCK_UNLOCKED; -+ -+static int reading_opens = 0; -+static int bitmap_opens = 0; -+ -+/* previous bitmap of keys down */ -+static unsigned long oldkeybitmap[NUM_WORDS_IN_BITMAP]; -+/* current bitmap of keys down */ -+static unsigned long keybitmap[NUM_WORDS_IN_BITMAP]; -+/* last bitmap read by ioctl */ -+static unsigned long lastioctlbitmap[NUM_WORDS_IN_BITMAP]; -+ -+static unsigned long kpas = 0; /* last value of kpas */ -+static unsigned long kpasmkp0 = 0; /* last value of kpasmkp0 */ -+static unsigned long kpasmkp1 = 0; /* last value of kpasmkp1 */ -+static unsigned long kpasmkp2 = 0; /* last value of kpasamkp2*/ -+static unsigned long kpdk = 0; /* last value of kpdk */ -+ -+#ifdef USE_RELEASE_TIMER -+static struct timer_list key_release_timer; -+static int key_release_interval = RDELAY * HZ/1000; -+#endif -+ -+static int do_autorepeat = 1; -+static long jiffies_to_first_repeat = 30; -+static long jiffies_to_next_repeat = 30; -+static struct timer_list autorepeat_timer; -+ -+extern int lockscreen_flag; -+ -+static int -+keypad_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypad_open\n"); -+#endif -+ spin_lock(keypad_lock); -+ if (reading_opens > 0) -+ { -+ spin_unlock(keypad_lock); -+ return -EBUSY; -+ } -+ reading_opens++; -+ spin_unlock(keypad_lock); -+ -+ return 0; -+} -+ -+static int -+keypadB_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypadB_open\n"); -+#endif -+ spin_lock(keypad_lock); -+ if (bitmap_opens > 0) -+ { -+ spin_unlock(keypad_lock); -+ return -EBUSY; -+ } -+ bitmap_opens++; -+ /* -+ * poll returns when lastioctlbitmap is different from keybitmap. -+ * we set lastioctlbitmap to keybitmap here so that a poll right -+ * after an open returns when the bitmap is different from when -+ * the open was done, not when the bitmap is different from the -+ * last time some other process read it -+ */ -+ copy_bitmap(lastioctlbitmap, keybitmap); -+ spin_unlock(keypad_lock); -+ -+ return 0; -+} -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+static int keypadI_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ switch(req) -+ { -+ case PM_SUSPEND: -+ break; -+ case PM_RESUME: -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ if(GPIO_TC_MM_STATE == 1) -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ else -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+#endif -+#endif -+ -+static int -+keypadI_open(struct inode *inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG "keypadI_open\n"); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ -+ return 0; -+} -+ -+static int -+keypad_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_close\n"); -+#endif -+ /* -+ * this decrement of reading_opens doesn't have to be protected because -+ * it can only be executed to close the single open of /dev/keypad -+ */ -+ reading_opens--; -+ return 0; -+} -+ -+static int -+keypadB_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadB_close\n"); -+#endif -+ /* -+ * this decrement of bitmap_opens doesn't have to be protected because -+ * it can only be executed to close the single open of /dev/keypadB -+ */ -+ bitmap_opens--; -+ return 0; -+} -+ -+static int -+keypadI_close(struct inode * inode, struct file *file) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadI_close\n"); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+#endif -+ -+ return 0; -+} -+ -+/** -+ * Add the specified event to the key buffer. -+ * This should be called with keypad_lock locked. -+ */ -+static int -+add_to_keybuf (unsigned short event) -+{ -+ if (KEYBUF_FULL()) -+ { -+ return -ENOMEM; -+ } -+ -+ keybuf[keybuf_end] = event; -+ KEYBUF_INC (keybuf_end); -+ -+#ifdef CONFIG_APM -+ apm_queue_event(KRNL_KEYPAD, NULL); -+#endif -+ //printk("add keypad event = %x\n", event); -+ return 0; -+} -+ -+/* -+ * code[c*8+r] is the key code for the key that's down when there's a 1 -+ * in column c, row r of the scan registers. -+ */ -+ -+#if defined(CONFIG_KEYPAD_V700) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_LEFT, KEYPAD_RIGHT, -+ KEYPAD_POUND, KEYPAD_0, KEYPAD_9, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_2, KEYPAD_4, KEYPAD_6, KEYPAD_8, -+ KEYPAD_7, KEYPAD_SLEFT, KEYPAD_SRIGHT, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_MENU, KEYPAD_1, KEYPAD_3, KEYPAD_5, -+ KEYPAD_STAR, KEYPAD_VOLUP, KEYPAD_VOLDOWN, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_CAMERA, KEYPAD_CLEAR, KEYPAD_CARRIER, KEYPAD_ACTIVATE, -+ KEYPAD_SEND, KEYPAD_SMART, KEYPAD_VAVR, KEYPAD_NONE -+}; -+ -+/* end CONFIG_KEYPAD_V700 */ -+#elif defined(CONFIG_E680_P4A) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_LEFT, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_RIGHT, KEYPAD_CENTER, KEYPAD_HOME, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_GAME_R, KEYPAD_NONE, KEYPAD_GAME_L, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_A, KEYPAD_B, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+}; -+ -+/* end CONFIG_E680_P4A */ -+#elif defined(CONFIG_KEYPAD_E680) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_UP, KEYPAD_DOWN, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_RIGHT, KEYPAD_LEFT, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_NONE, KEYPAD_GAME_R, KEYPAD_NONE, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_HOME, KEYPAD_GAME_L, KEYPAD_CENTER, KEYPAD_NONE, -+ KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ -+}; -+/*end CONFIG_KEYPAD_E680 */ -+#elif defined(CONFIG_KEYPAD_A780) -+int -+scanbit_to_keycode[] = { -+ /* col 0 */ -+ KEYPAD_OK, KEYPAD_1, KEYPAD_4, KEYPAD_7, -+ KEYPAD_STAR, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 1 */ -+ KEYPAD_MENU, KEYPAD_2, KEYPAD_5, KEYPAD_8, -+ KEYPAD_0, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 2 */ -+ KEYPAD_CANCEL, KEYPAD_3, KEYPAD_6, KEYPAD_9, -+ KEYPAD_POUND, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 3 */ -+ KEYPAD_JOG_UP, KEYPAD_JOG_MIDDLE, KEYPAD_JOG_DOWN, KEYPAD_LEFT, -+ KEYPAD_DOWN, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+ /* col 4 */ -+ KEYPAD_CENTER, KEYPAD_HOME, KEYPAD_PTT, KEYPAD_UP, -+ KEYPAD_RIGHT, KEYPAD_NONE, KEYPAD_NONE, KEYPAD_NONE, -+}; -+#endif -+ -+/* -+ * Decode the specified scan register values into the bitmap pointed -+ * to by the last argument. The bitmap will contain a 1 -+ * for each key that's down. -+ * -+ * Only the 1st two of the four scan registers are used. -+ */ -+static void -+scan_to_bitmap(unsigned long kpas, unsigned long kpasmkp0, -+ unsigned long kpasmkp1, unsigned long bitmap[]) -+{ -+ int row, col; -+ int bitnum; -+ unsigned long scanmap; -+#if defined(CONFIG_KEYPAD_A780) -+ int keep; -+#endif -+ -+ set_bitmap_to_zero (bitmap); -+ -+ if ((kpas & KPAS_MUKP) == MUKP_NO_KEYS) -+ { -+ return; -+ } -+ -+ if ((kpas & KPAS_MUKP) == MUKP_ONE_KEY) -+ { -+ row = (kpas & KPAS_RP) >> 4; -+ col = kpas & KPAS_CP; -+ turn_on_bit (bitmap, scanbit_to_keycode[col*8 + row]); -+ return; -+ } -+ -+ /* reach here if multiple keys */ -+ scanmap = (kpasmkp0 & 0x7f) | ((kpasmkp0 & 0x7f0000) >> 8) | -+ ((kpasmkp1 & 0x7f) << 16) | ((kpasmkp1 & 0x7f0000) << 8); -+ while ((bitnum = ffs(scanmap)) != 0) -+ { -+ /* -+ * ffs returns bit numbers starting with 1, so subtract 1 to index -+ * into scanbit_to_keycode[] -+ */ -+ turn_on_bit (bitmap, scanbit_to_keycode[bitnum-1]); -+ scanmap &= ~(1<<(bitnum-1)); -+ } -+#if defined(CONFIG_KEYPAD_A780) -+ kpasmkp2 = KPASMKP2; -+ if ((kpasmkp1 & 0x180000) || (kpasmkp2 & 0x18)) -+ keep = 1; -+ else -+ keep = 0; -+ if ( keep ) -+ kpasmkp2 &= 0xfffffffe; -+ while ((bitnum = ffs(kpasmkp2)) !=0) -+ { -+ turn_on_bit (bitmap, scanbit_to_keycode[32+bitnum-1]); -+ kpasmkp2 &= ~(1<<(bitnum-1)); -+ } -+#endif -+} -+ -+/* -+ * Add events indicated by the difference between the last scan (oldbitmap) -+ * and this one (newbitmap) to the input buffer. -+ * Return nonzero right away if any of the events can't be added. -+ * A zero return means all the events were added. -+ * This should be called with keypad_lock locked. -+ */ -+static int -+add_events (unsigned long *oldbitmap, unsigned long *newbitmap) -+{ -+ unsigned long tmpmap, onebitmap; -+ int bitnum, i, ret; -+ -+ /* generate events for keys that were down before and are up now */ -+ for (i=NUM_WORDS_IN_BITMAP-1;i>=0;i--) -+ { -+ tmpmap = oldbitmap[i]; -+ while ((bitnum = ffs(tmpmap)) != 0) -+ { -+ onebitmap = 1<<(bitnum-1); -+ if ((newbitmap[i] & onebitmap) == 0) -+ { -+ ret = add_to_keybuf(bitnum + (32*(NUM_WORDS_IN_BITMAP-1-i) | KEYUP)); -+ if (ret < 0) -+ { -+ return ret; -+ } -+ } -+ tmpmap &= ~onebitmap; -+ } -+ } -+ /* generate events for down keys that were up before */ -+ for (i=NUM_WORDS_IN_BITMAP-1;i>=0;i--) -+ { -+ tmpmap = newbitmap[i]; -+ while ((bitnum = ffs(tmpmap)) != 0) -+ { -+ onebitmap = 1<<(bitnum-1); -+ if ((oldbitmap[i] & onebitmap) == 0) -+ { -+ ret = add_to_keybuf -+ (bitnum + (32*(NUM_WORDS_IN_BITMAP-1-i) | KEYDOWN)); -+ if (ret < 0) -+ { -+ return ret; -+ } -+ } -+ tmpmap &= ~onebitmap; -+ } -+ } -+ return 0; -+} -+ -+/* -+ * do the INSERT_EVENT ioctl -+ */ -+static int -+insert_event (unsigned short event) -+{ -+ unsigned long flags; -+ int ret; -+ -+ if (KEYCODE(event) > KEYPAD_MAXCODE) -+ { -+ printk(KERN_WARNING " inserted key code %d too big\n", -+ KEYCODE(event)); -+ return -EINVAL; -+ } -+ spin_lock_irqsave(&keypad_lock, flags); -+ if (KEY_IS_DOWN(event)) -+ { -+ turn_on_bit(keybitmap, KEYCODE(event)); -+ } -+ else -+ { -+ turn_off_bit (keybitmap, event); -+ } -+ if ((ret = add_to_keybuf(event)) < 0) -+ { -+ spin_unlock_irqrestore(&keypad_lock,flags); -+ return ret; -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ return 0; -+} -+ -+static int -+keypad_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int interval; /* debounce interval */ -+ int imkp; /* Ignore Multiple Key Press bit */ -+ struct autorepeatinfo ar; /* autorepeat information */ -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypad_ioctl: 0x%x\n", cmd); -+#endif -+ switch (cmd) -+ { -+ case KEYPAD_IOC_INSERT_EVENT: -+ return insert_event ((unsigned short)arg); -+ break; -+ case KEYPAD_IOC_GET_DEBOUNCE_INTERVAL: -+ interval = KPKDI & KPKDI_BITS; -+ return put_user(interval, (unsigned long *)arg); -+ break; -+ case KEYPAD_IOC_SET_DEBOUNCE_INTERVAL: -+ interval = (unsigned short)arg; -+ if (interval > KPKDI_BITS) -+ { -+ return -EINVAL; -+ } -+ KPKDI &= ~KPKDI_BITS; -+ KPKDI |= interval; -+ break; -+ case KEYPAD_IOC_GET_IMKP_SETTING: -+ imkp = ((KPC & KPC_IMKP) == KPC_IMKP); -+ return put_user(imkp, (unsigned char *)arg); -+ break; -+ case KEYPAD_IOC_SET_IMKP_SETTING: -+ imkp = (unsigned char)arg; -+ if (imkp) -+ { -+ KPC |= KPC_IMKP; -+ } -+ else -+ { -+ KPC &= ~KPC_IMKP; -+ } -+ break; -+ case KEYPAD_IOC_SET_AUTOREPEAT: -+ if (copy_from_user (&ar, (void *)arg, -+ sizeof(struct autorepeatinfo)) != 0) -+ { -+ return -EFAULT; -+ } -+ do_autorepeat = ar.r_repeat; -+ /* times are specified in milliseconds; convert to jiffies */ -+ jiffies_to_first_repeat = ar.r_time_to_first_repeat * HZ/1000; -+ jiffies_to_next_repeat = ar.r_time_between_repeats * HZ/1000; -+ break; -+ default: -+ return -ENOTTY; -+ } -+ return 0; -+} -+ -+static int -+keypadB_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned long flags; -+ int ret; -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypadB_ioctl: 0x%x\n", cmd); -+#endif -+ if (cmd == KEYPAD_IOC_INSERT_EVENT) -+ { -+ return insert_event ((unsigned short)arg); -+ } -+ else if (cmd == KEYPAD_IOC_GETBITMAP) -+ { -+ spin_lock_irqsave(&keypad_lock, flags); -+ ret = copy_to_user ((void *)arg, keybitmap, -+ NUM_WORDS_IN_BITMAP * sizeof(unsigned long)); -+ copy_bitmap (lastioctlbitmap, keybitmap); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return (ret != 0) ? -EFAULT : 0; -+ } -+ else -+ { -+ return -ENOTTY; -+ } -+} -+ -+static int -+keypadI_ioctl (struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ unsigned long flags; -+ int ret; -+ -+#ifdef KDEBUG -+ printk (KERN_DEBUG "keypadI_ioctl: 0x%x\n", cmd); -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ if( cmd == KEYPADI_TURN_ON_LED ) -+ { -+ GPCR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ GPIO_TC_MM_STATE = 0; -+ PGSR3 &= ~GPIO_bit(GPIO_TC_MM_EN); -+ return 0; -+ } -+ if( cmd == KEYPADI_TURN_OFF_LED ) -+ { -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ GPIO_TC_MM_STATE = 1; -+ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); -+ return 0; -+ } -+#endif -+ -+ if (cmd == KEYPAD_IOC_INSERT_EVENT) -+ { -+ return insert_event ((unsigned short)arg); -+ } -+ else if (cmd == KEYPAD_IOC_GETBITMAP) -+ { -+ spin_lock_irqsave(&keypad_lock, flags); -+ ret = copy_to_user ((void *)arg, keybitmap, -+ NUM_WORDS_IN_BITMAP * sizeof(unsigned long)); -+ copy_bitmap (lastioctlbitmap, keybitmap); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return (ret != 0) ? -EFAULT : 0; -+ } -+ else -+ { -+ return -ENOTTY; -+ } -+} -+ -+static unsigned int -+keypad_poll( struct file *file, poll_table * wait ) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_poll\n"); -+#endif -+ poll_wait(file, &keypad_wait, wait); -+ -+ if (!KEYBUF_EMPTY()) -+ { -+ return (POLLIN | POLLRDNORM); -+ } -+ return 0; -+} -+ -+static unsigned int -+keypadB_poll( struct file *file, poll_table * wait ) -+{ -+ int i; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypadB_poll\n"); -+#endif -+ poll_wait(file, &keypad_wait, wait); -+ -+ for (i=0; i < NUM_WORDS_IN_BITMAP; i++) -+ { -+ if (lastioctlbitmap[i] != keybitmap[i]) -+ { -+ return (POLLIN | POLLRDNORM); -+ } -+ } -+ return 0; -+} -+ -+static unsigned short -+get_from_keybuf(void) -+{ -+ unsigned short event; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock, flags); -+ event = keybuf[keybuf_start]; -+ KEYBUF_INC (keybuf_start); -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return event; -+} -+ -+static ssize_t -+keypad_read(struct file *file, char *buf, size_t count, loff_t *ptr) -+{ -+ int i, ret; -+ unsigned short event; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_read\n"); -+#endif -+ /* Can't seek (pread) on this device */ -+ if (ptr != &file->f_pos) -+ { -+ return -ESPIPE; -+ } -+ -+ if (count == 0) -+ { -+ return 0; -+ } -+ -+ if (KEYBUF_EMPTY()) -+ { -+ /* buffer is empty */ -+ /* if not blocking return */ -+ if (file->f_flags & O_NONBLOCK) -+ { -+ return -EAGAIN; -+ } -+ /* blocking, so wait for input */ -+ ret = wait_event_interruptible(keypad_wait, !KEYBUF_EMPTY()); -+ if (ret) -+ { -+ return ret; -+ } -+ } -+ -+ i = 0; -+ /* copy events until we have what the user asked for or we run out */ -+ while ((i+1 < count) && !KEYBUF_EMPTY()) -+ { -+ event = get_from_keybuf(); -+ if ((ret = put_user(event, (unsigned short *)buf)) != 0) -+ { -+ return ret; -+ } -+ buf += EVENTSIZE; -+ i += EVENTSIZE; -+ } -+ return i; -+} -+ -+#ifdef CONFIG_PM -+static int button_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) -+{ -+ int pksr; -+ -+ pksr = PKSR; -+ PKSR = 0xfffff; -+ switch(req) -+ { -+ case PM_SUSPEND: -+ kpc_res = KPC; -+ kpkdi_res = KPKDI; -+ set_bitmap_to_zero (oldkeybitmap); -+ set_bitmap_to_zero (keybitmap); -+ set_bitmap_to_zero (lastioctlbitmap); -+ kpas = 0; -+ kpasmkp0 = 0; -+ kpasmkp1 = 0; -+ kpasmkp2 = 0; -+ kpdk = 0; -+ break; -+ case PM_RESUME: -+ KPC = kpc_res; -+ KPKDI = kpkdi_res; -+#ifdef CONFIG_APM -+#if defined(CONFIG_E680_P4A) -+ if (pksr & 0xe4400) /*93 97 100 101 102 key is pressed (switch on) */ -+ { -+ apm_queue_event(KRNL_KEYPAD); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+ if (pksr & 0xee400) /*93 96 97 98 190 101 102 key is pressed */ -+ { -+ apm_queue_event(KRNL_KEYPAD); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ if (pksr & 0x2000) -+ turn_on_bit (keybitmap, KEYPAD_A); -+ if (pksr & 0x8000) -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+ printk("pksr = %x\n",pksr); -+ if (pksr & 0xec400) /* 93 97 98 100 101 102 key is pressed */ -+ { -+ apm_queue_event(KRNL_KEYPAD); -+ if (pksr & 0x400) -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+#endif -+ -+ break; -+ } -+ return 0; -+} -+#endif -+ -+/* for /dev/keypad */ -+static struct file_operations -+keypad_fops = { -+ read: keypad_read, -+ llseek: no_llseek, -+ poll: keypad_poll, -+ ioctl: keypad_ioctl, -+ open: keypad_open, -+ release: keypad_close, -+}; -+ -+static struct miscdevice -+keypad_misc_device = { -+ KEYPAD_MINOR, -+ KEYPAD_NAME, -+ &keypad_fops, -+}; -+ -+/* -+ * for /dev/keypadB. -+ * read() isn't defined here. calls to read() will return -1 with EINVAL. -+ */ -+static struct file_operations -+keypadB_fops = { -+ llseek: no_llseek, -+ poll: keypadB_poll, -+ ioctl: keypadB_ioctl, -+ open: keypadB_open, -+ release: keypadB_close, -+}; -+ -+static struct miscdevice -+keypadB_misc_device = { -+ KEYPAD_BITMAP_MINOR, -+ KEYPAD_BITMAP_NAME, -+ &keypadB_fops, -+}; -+ -+/* -+ * for /dev/keypadI. -+ * read() isn't defined here. calls to read() will return -1 with EINVAL. -+ */ -+static struct file_operations -+keypadI_fops = { -+ llseek: no_llseek, -+ ioctl: keypadI_ioctl, -+ open: keypadI_open, -+ release: keypadI_close, -+}; -+ -+static struct miscdevice -+keypadI_misc_device = { -+ KEYPAD_INSERT_MINOR, -+ KEYPAD_INSERT_NAME, -+ &keypadI_fops, -+}; -+ -+#ifdef CONFIG_PANIC_LOG -+static u32 panic_bug_used =0; -+#endif -+ -+/* Interrupt Handler for KEYPAD */ -+static irqreturn_t -+kp_interrupt(int irq, void *ptr, struct pt_regs *regs) -+{ -+ unsigned long flags; -+ unsigned long kpc_val; -+ -+#ifdef USE_RELEASE_TIMER -+ del_timer (&key_release_timer); -+#endif -+ del_timer (&autorepeat_timer); -+ spin_lock_irqsave(&keypad_lock,flags); -+ -+ /* ack interrupt */ -+ kpc_val = KPC; -+ -+ /* matrix interrupt */ -+ if (kpc_val & KPC_MI) -+ { -+/* -+ * The Intel driver turned on KPC_AS here. It doesn't seem that we -+ * would need to do that, because getting an interrupt means that -+ * a scan was just done. For now, I've commented out the setting -+ * and clearing of this bit. -+ KPC |= KPC_AS; -+ */ -+ while (KPAS & KPAS_SO) -+ { -+ /* Wait for the Scan On bit to go off before */ -+ /* reading the scan registers. */ -+ NULL; -+ }; -+ -+ kpas = KPAS; -+ kpasmkp0 = KPASMKP0; -+ kpasmkp1 = KPASMKP1; -+ kpasmkp2 = KPASMKP2; -+ -+ } -+ -+ /* direct interrupt */ -+ if (kpc_val & KPC_DI) -+ { -+ kpdk = KPDK; -+ /* -+ * reading the register turns off the "key pressed since last read" -+ * bit if it was on, so we turn it off -+ */ -+ kpdk &= ~KPDK_DKP; -+ } -+#ifdef CONFIG_PANIC_LOG -+ if ((kpdk & KPDK_DK0)&&(kpasmkp1& 0x00020000)) -+ { -+ if(0 == panic_bug_used) -+ { -+ panic_bug_used = 1; -+ BUG(); -+ } -+ } -+#endif -+ copy_bitmap (oldkeybitmap, keybitmap); -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1, keybitmap); -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* VR key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* VR key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+ if (kpdk & KPDK_DK3) -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+ -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ -+ (void) add_events (oldkeybitmap, keybitmap); -+ -+ /* If any keys are down, set a timer to check for key release */ -+ /* and one for autorepeat if that's on. */ -+ if (any_keys_down (keybitmap)) -+ { -+#ifdef USE_RELEASE_TIMER -+ key_release_timer.expires = (jiffies + key_release_interval); -+ add_timer (&key_release_timer); -+#endif -+ if (do_autorepeat) -+ { -+ autorepeat_timer.expires = (jiffies + jiffies_to_first_repeat); -+ add_timer (&autorepeat_timer); -+ } -+ } -+ -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ //printk("keypad interrupt occurred\n"); -+ return IRQ_HANDLED; -+} -+ -+#ifdef USE_RELEASE_TIMER -+/* -+ * This is called when the key release timer goes off. That's the -+ * only time it should be called. Check for changes in what keys -+ * are down. -+ */ -+static void -+release_timer_went_off(unsigned long unused) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock,flags); -+ do_scan(); -+ /* If any keys are still down, set the timer going again. */ -+ if (any_keys_down (keybitmap)) -+ { -+ mod_timer (&key_release_timer, jiffies + key_release_interval); -+ } -+ else -+ { -+ del_timer (&autorepeat_timer); -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+} -+#endif -+ -+/* -+ * This is called when the autorepeat timer goes off. -+ */ -+static void -+autorepeat_timer_went_off(unsigned long unused) -+{ -+ int i, bitnum; -+ unsigned long tmp; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&keypad_lock,flags); -+ if (!any_keys_down (keybitmap)) -+ { -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ return; -+ } -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ tmp = keybitmap[NUM_WORDS_IN_BITMAP-i-1]; -+ while ((bitnum = ffs(tmp)) != 0) -+ { -+ tmp &= ~(1<<(bitnum-1)); -+ /* see explanation at top of file */ -+ if ( (bitnum + (32*i)) == KEYPAD_POWER ) -+ { -+ continue; -+ } -+ (void) add_to_keybuf( (bitnum + (32*i)) | KEYDOWN ); -+ } -+ } -+ spin_unlock_irqrestore(&keypad_lock, flags); -+ wake_up_interruptible (&keypad_wait); -+ -+ mod_timer (&autorepeat_timer, jiffies + jiffies_to_next_repeat); -+} -+ -+#ifdef USE_RELEASE_TIMER -+/* -+ * Do a scan and add key events for anything that's different from the -+ * last scan. We assume keypad_lock is locked when this is called -+ * (by release_timer_went_off). -+ */ -+static void -+do_scan(void) -+{ -+ unsigned long kpas_new, kpasmkp0_new, kpasmkp1_new; -+ unsigned long kpdk_new; -+ int change; -+ -+ /* Initiate an automatic scan */ -+ KPC |= KPC_AS; -+ /* Wait for the Scan On bit to go off before */ -+ /* reading the scan registers. */ -+ while (KPAS & KPAS_SO) -+ { -+ NULL; -+ }; -+ kpas_new = KPAS; -+ kpasmkp0_new = KPASMKP0; -+ kpasmkp1_new = KPASMKP1; -+ kpdk_new = KPDK; -+ /* -+ * reading the register turns off the "key pressed since last read" bit -+ * if it was on, so we turn it off -+ */ -+ kpdk_new &= ~KPDK_DKP; -+ KPC &= ~KPC_AS; -+ -+ change = ((kpas_new != kpas) || -+ (kpasmkp0_new != kpasmkp0) || -+ (kpasmkp1_new != kpasmkp1) || -+ (kpdk_new != kpdk)); -+ -+ if (change) -+ { -+ kpas = kpas_new; -+ kpasmkp0 = kpasmkp0_new; -+ kpasmkp1 = kpasmkp1_new; -+ kpdk = kpdk_new; -+ -+ copy_bitmap (oldkeybitmap, keybitmap); -+ scan_to_bitmap (kpas, kpasmkp0, kpasmkp1, keybitmap); -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* screen lock key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* screen lock key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ /* power key is connected to GPIO97 as GPIO input */ -+ if (kpdk & KPDK_DK3) -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+ -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ add_events (oldkeybitmap, keybitmap); -+ -+ wake_up_interruptible (&keypad_wait); -+ } -+} -+#endif -+ -+/* -+ * set all words in the specified bitmap to 0 -+ */ -+static inline void set_bitmap_to_zero(unsigned long b[]) { -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ b[i]=0; -+ } -+} -+ -+/* -+ * copy source bitmap to destination bitmap -+ */ -+static inline void copy_bitmap(unsigned long dest[], unsigned long source[]) { -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ dest[i]=source[i]; -+ } -+} -+ -+/* -+ * Turn on the bit position in map for the specified key code. -+ * Bit numbers start with 1 (not 0) and increase moving left within -+ * words and within the array. -+ * Bit 1 is the rightmost bit in map[NUM_WORDS_IN_BITMAP-1]. -+ * Bit 33 is the rightmost bit in map[NUM_WORDS_IN_BITMAP-2]. -+ */ -+static inline void -+turn_on_bit(unsigned long map[], int code) -+{ -+ int word, pos, p; -+ -+ /* if we have 2 words, bits 1-32 are in map[1], 33-64 in map[0] */ -+ word = (NUM_WORDS_IN_BITMAP - 1) - ((code-1) / 32); -+ /* -+ * bit 1 is 1<<0, bit 2 is 1<<1, ... bit 32 is 1 << 31, all in map[1] -+ * bit 33 is 1<<0, bit 34 is 1<<1, ... in map[0] -+ * we want this: -+ * code pos -+ * 1 0 -+ * 2 1 -+ * ... -+ * 31 30 -+ * 32 31 -+ * 33 0 -+ * 34 1 -+ * ... -+ */ -+ pos = (p = (code % 32)) == 0 ? 31 : p-1; -+ map[word] |= (1<<pos); -+} -+ -+/* -+ * Turn off the bit position in map for the specified key code. -+ * Bit positions start with 1 (not 0). -+ */ -+static inline void -+turn_off_bit(unsigned long map[], int code) -+{ -+ int word, pos, p; -+ -+ word = (NUM_WORDS_IN_BITMAP - 1) - ((code-1) / 32); -+ pos = (p = (code % 32)) == 0 ? 31 : p-1; -+ map[word] &= ~(1<<pos); -+} -+ -+/* -+ * Return 1 if any bits are down in map[] -+ */ -+static inline int -+any_keys_down (unsigned long *map) -+{ -+ int i; -+ for (i=0;i<NUM_WORDS_IN_BITMAP;i++) -+ { -+ /* don't count the power key */ -+ if ((i == 0) && (*map == 0x10)) -+ { -+ map++; -+ continue; -+ } -+ if (*map++) -+ { -+ return 1; -+ } -+ } -+ return 0; -+} -+static int -+__init keypad_init(void) -+{ -+ int err; -+ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_init\n"); -+#endif -+ -+ set_bitmap_to_zero (oldkeybitmap); -+ set_bitmap_to_zero (keybitmap); -+ set_bitmap_to_zero (lastioctlbitmap); -+ -+ /* set up gpio */ -+#if defined (CONFIG_KEYPAD_V700) -+ pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN); /* KP_MKIN<6> */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_MKIN<3> */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_MKIN<4> */ -+ pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); /* KP_MKIN<5> */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#elif defined(CONFIG_E680_P4A) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#elif defined(CONFIG_KEYPAD_E680) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, VR Key */ -+ pxa_gpio_mode(96 | GPIO_ALT_FN_1_IN); /* KP_DKIN<3>, GAME_A */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_1_IN); /* KP_DKIN<4>, power key */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); /* KP_DKIN<5>, GAME_B */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+ pxa_gpio_mode(GPIO_TC_MM_EN); -+ GPDR(GPIO_TC_MM_EN) |= GPIO_bit(GPIO_TC_MM_EN); -+ GPSR(GPIO_TC_MM_EN) = GPIO_bit(GPIO_TC_MM_EN); -+ PGSR3 |= GPIO_bit(GPIO_TC_MM_EN); -+#elif defined (CONFIG_KEYPAD_A780) -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); /* KP_DKIN<0>, voice_rec */ -+ pxa_gpio_mode(97 | GPIO_ALT_FN_3_IN); /* KP_MKIN<3> */ -+ pxa_gpio_mode(98 | GPIO_ALT_FN_3_IN); /* KP_MKIN<4> */ -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+ pxa_gpio_mode(107 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<4> */ -+#elif defined(CONFIG_KEYPAD_MAINSTONE) -+ /* from Intel driver */ -+ pxa_gpio_mode(93 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(94 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(95 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(98 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(99 | GPIO_ALT_FN_1_IN); -+ pxa_gpio_mode(100 | GPIO_ALT_FN_1_IN); /* KP_MKIN<0> */ -+ pxa_gpio_mode(101 | GPIO_ALT_FN_1_IN); /* KP_MKIN<1> */ -+ pxa_gpio_mode(102 | GPIO_ALT_FN_1_IN); /* KP_MKIN<2> */ -+ pxa_gpio_mode(103 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<0> */ -+ pxa_gpio_mode(104 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<1> */ -+ pxa_gpio_mode(105 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<2> */ -+ pxa_gpio_mode(106 | GPIO_ALT_FN_2_OUT); /* KP_MKOUT<3> */ -+#endif -+ -+ /* set keypad control register */ -+ KPC = (KPC_ASACT | /* automatic scan on activity */ -+ KPC_ME | KPC_DE | /* matrix and direct keypad enabled */ -+#if defined (CONFIG_KEYPAD_V700) -+ (3<<23) | /* 4 columns */ -+ (6<<26) | /* 7 rows */ -+#elif defined(CONFIG_E680_P4A) -+ (3<<23) | /* 4 columns */ -+ (2<<26) | /* 3 rows */ -+ (4<<6) | /* 4# direct key */ -+#elif defined(CONFIG_KEYPAD_E680) -+ (5<<23) | /* 4 columns */ -+ (4<<26) | /* 3 rows */ -+ (5<<6) | /* 5# direct keys */ -+#elif defined(CONFIG_KEYPAD_A780) -+ (4<<23) | /* 5 columns */ -+ (4<<26) | /* 5 rows */ -+ (0<<6) | /* 1# direct keys */ -+#endif -+ KPC_MS_ALL); /* scan all columns */ -+ -+ CKEN |= CKEN19_KEYPAD; -+ -+ err = request_irq (IRQ_KEYPAD, kp_interrupt, 0, "Keypad", NULL); -+ if (err) -+ { -+ printk (KERN_CRIT "can't register IRQ%d for keypad, error %d\n", -+ IRQ_KEYPAD, err); -+ CKEN &= ~CKEN19_KEYPAD; -+ return -ENODEV; -+ } -+ -+ if (misc_register (&keypad_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypad driver\n"); -+ return -EIO; -+ } -+ if (misc_register (&keypadB_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypadB driver\n"); -+ misc_deregister(&keypad_misc_device); -+ return -EIO; -+ } -+ if (misc_register (&keypadI_misc_device)) -+ { -+ printk(KERN_ERR "Couldn't register keypadI driver\n"); -+ misc_deregister(&keypad_misc_device); -+ misc_deregister(&keypadB_misc_device); -+ return -EIO; -+ } -+ -+#ifdef USE_RELEASE_TIMER -+ init_timer (&key_release_timer); -+ key_release_timer.function = release_timer_went_off; -+#endif -+ init_timer (&autorepeat_timer); -+ autorepeat_timer.function = autorepeat_timer_went_off; -+ -+ /* -+ * we want the phone to be able to tell the status of the screen -+ * lock switch at power-up time -+ */ -+ kpdk = KPDK; /* read direct key register */ -+ /* -+ * reading the register turns off the "key pressed since last read" bit -+ * if it was on, so we turn it off -+ */ -+ kpdk &= ~KPDK_DKP; -+#if defined(CONFIG_E680_P4A) -+ if (kpdk & KPDK_DK0) /* VR key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) /* Power key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+#elif defined(CONFIG_KEYPAD_E680) -+ if (kpdk & KPDK_DK0) /* VR key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+ if (kpdk & KPDK_DK4) /* Power key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_POWER); -+ } -+ if (kpdk & KPDK_DK3) /* GAME_A key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_A); -+ } -+ if (kpdk & KPDK_DK5) /* GAME_B key is pressed (switch on) */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_B); -+ } -+#elif defined(CONFIG_KEYPAD_A780) -+ if (kpdk & KPDK_DK0) /* voice/camera key is pressed */ -+ { -+ turn_on_bit (keybitmap, KEYPAD_CAMERA_VOICE); -+ } -+#endif -+ -+#ifdef CONFIG_PM -+ pm_dev = pm_register(PM_SYS_DEV, 0, button_pm_callback); -+#if defined(CONFIG_E680_P4A) -+/*93,97,100,101,102*/ -+ PKWR = 0xe4400; -+/*103 104 105 106*/ -+ PGSR3 |= 0x780; -+#endif -+#if defined(CONFIG_KEYPAD_E680) -+/*93,96,97,98,100,101,102*/ -+ PKWR = 0xee400; -+/*103 104 105 106*/ -+ PGSR3 |= 0x780; -+#endif -+#if defined(CONFIG_KEYPAD_A780) -+/*93,97,98,100,101,102*/ -+ PKWR = 0xec400; -+/*103 104 105 106 107*/ -+ PGSR3 |= 0xf80; -+#endif -+#endif -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+ keypadI_pm_dev = pm_register(PM_SYS_DEV, 0, keypadI_pm_callback); -+ PGSR3 |= 0x8; -+#endif -+#endif -+ -+ KPC |= (KPC_DIE | KPC_MIE); -+ KPKDI = 0x40; -+ return 0; -+} -+ -+static void -+__exit keypad_exit(void) -+{ -+#ifdef KDEBUG -+ printk(KERN_DEBUG " keypad_exit\n"); -+#endif -+ misc_deregister(&keypad_misc_device); -+ misc_deregister(&keypadB_misc_device); -+ misc_deregister(&keypadI_misc_device); -+ -+#ifdef CONFIG_PM -+ pm_unregister(pm_dev); -+#endif -+ -+#if defined(CONFIG_KEYPAD_E680) -+#ifdef CONFIG_PM -+ pm_unregister(keypadI_pm_dev); -+#endif -+#endif -+ -+ CKEN &= ~CKEN19_KEYPAD; -+} -+ -+module_init (keypad_init); -+module_exit (keypad_exit); -Index: linux-2.6.16.5-a/drivers/misc/ezx/keypad.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/keypad.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,104 @@ -+#ifndef __DRIVER_CHAR_KEYPAD_H -+#define __DRIVER_CHAR_KEYPAD_H -+ -+/* -+ * linux/drivers/char/keypad.h -+ * -+ * (c) Copyright Motorola 2003, All rights reserved. -+ */ -+ -+#include <asm/hardware.h> -+#include <linux/keypad.h> -+ -+/** -+ * /dev/keypad is the main keypad device. Opening this device provides access -+ * for read(), ioctl() and poll()/select(). Only one process at a time -+ * can open this device. -+ */ -+#define KEYPAD_NAME "keypad" -+#define KEYPAD_MINOR 0xf0 /* 240 */ -+ -+/** -+ * /dev/keypadB can be opened for ioctl() and poll()/select(). -+ * Only one process at a time can open this device. -+ */ -+#define KEYPAD_BITMAP_NAME "keypadB" -+#define KEYPAD_BITMAP_MINOR 0xf1 /* 241 */ -+ -+/** -+ * /dev/keypadI can be opened for ioctl(INSERT_EVENT). -+ * Any number of devices can open this simultaneously. -+ */ -+#define KEYPAD_INSERT_NAME "keypadI" -+#define KEYPAD_INSERT_MINOR 0xf2 /* 242 */ -+ -+/* -+ * KEYBUF_SIZE must be a power of 2 to avoid performance-destroying -+ * integer divisions in the compiled code. -+ * Each keypad event is a short, so a buffer n bytes long can hold -+ * n/2 keypad events. -+ */ -+#define KEYBUF_SIZE 256 -+ -+#if 0 -+#define KPC __REG(0x41500000) /* control register */ -+#define KPDK __REG(0x41500008) /* direct key register */ -+#define KPAS __REG(0x41500020) /* automatic scan register */ -+#define KPASMKP0 __REG(0x41500028) /* auto scan multiple key press reg 0 */ -+#define KPASMKP1 __REG(0x41500030) /* auto scan multiple key press reg 1 */ -+#define KPKDI __REG(0x41500048) /* debounce interval register */ -+ -+#define KPC_RSRVD0 0x80000000 /* reserved */ -+#define KPC_AS 0x40000000 /* automatic scan */ -+#define KPC_ASACT 0x20000000 /* automatic scan on activity */ -+#define KPC_MKRN 0x1c000000 /* number of matrix keypad rows - 1 */ -+#define KPC_MKCN 0x03800000 /* number of matrix keypad columns - 1 */ -+#define KPC_MI 0x00400000 /* matrix interrupt, reset when read */ -+#define KPC_IMKP 0x00200000 /* ignore multiple key press */ -+#define KPC_MS7_0 0x001fe000 /* MS7-MS0 assert to scan columns */ -+#define KPC_MS7 0x00100000 /* MS7 assert to scan column */ -+#define KPC_MS6 0x00080000 /* MS6 assert to scan column */ -+#define KPC_MS5 0x00040000 /* MS5 assert to scan column */ -+#define KPC_MS4 0x00020000 /* MS4 assert to scan column */ -+#define KPC_MS3 0x00010000 /* MS3 assert to scan column */ -+#define KPC_MS2 0x00008000 /* MS2 assert to scan column */ -+#define KPC_MS1 0x00004000 /* MS1 assert to scan column */ -+#define KPC_MS0 0x00002000 /* MS0 assert to scan column */ -+#define KPC_ME 0x00001000 /* matrix keypad enable */ -+#define KPC_MIE 0x00000800 /* matrix interrupt enable */ -+#define KPC_RSRVD1 0x00000600 /* reserved */ -+#define KPC_DKN 0x000001c0 /* number of direct keys - 1 */ -+#define KPC_DI 0x00000020 /* direct interrupt bit, reset when read */ -+#define KPC_RSRVD2 0x00000010 /* reserved */ -+#define KPC_REE1 0x00000008 /* rotary encoder 1 enable */ -+#define KPC_REE0 0x00000004 /* rotary encoder 0 enable */ -+#define KPC_DE 0x00000002 /* direct keypad enable */ -+#define KPC_DIE 0x00000001 /* direct keypad interrupt enable */ -+ -+#define KPC_7rows 0x18000000 /* 6 in KPC_MKRN */ -+#define KPC_4cols 0x01800000 /* 3 in KPC_MKCN */ -+/* -+ * bits in Direct Key register -+ */ -+#define KPDK_DKP (0x1 << 31) /* on if direct key pressed since last read */ -+#define KPDK_DK7 (0x1 << 7) -+#define KPDK_DK6 (0x1 << 6) -+#define KPDK_DK5 (0x1 << 5) -+#define KPDK_DK4 (0x1 << 4) -+#define KPDK_DK3 (0x1 << 3) -+#define KPDK_DK2 (0x1 << 2) -+#define KPDK_DK1 (0x1 << 1) -+#define KPDK_DK0 (0x1 << 0) -+ -+ -+#endif -+ -+#define KPKDI_BITS 0xff /* bits in KPKDI register for debounce interval */ -+#define KPAS_MUKP 0x7c000000 /* KPAS bits 30-26 */ -+#define MUKP_NO_KEYS 0x00000000 /* value of MUKP if no keys are down */ -+#define MUKP_ONE_KEY 0x04000000 /* value of MUKP if one key is down */ -+#define KPAS_SO 0x80000000 /* scan on bit */ -+#define KPAS_RP 0x000000f0 /* row of single key */ -+#define KPAS_CP 0x0000000f /* column of single key */ -+ -+#endif /* __DRIVER_CHAR_KEYPAD_H */ -Index: linux-2.6.16.5-a/drivers/misc/ezx/log.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/log.c 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,287 @@ -+/* -+ * Kernel panic log interface for Linux. -+ * -+ * Copyright (c) 2000 Motorola -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * 0.01 2003-07-01 zxf <w19962@motorola.com> -+ * - initial release -+ */ -+ -+#include <linux/module.h> -+#include <linux/fs.h> -+#include <linux/miscdevice.h> -+#include <linux/string.h> -+#include <linux/init.h> -+#include <linux/poll.h> -+#include <linux/rtc.h> -+#include <linux/notifier.h> -+#include <asm/bitops.h> -+#include <asm/hardware.h> -+#include <asm/irq.h> -+ -+#include "log.h" -+ -+#include <linux/fb.h> -+#include "../video/pxafb.h" -+ -+#define LOGDRV_MINOR 188 -+ -+static struct log_area *log = NULL; -+struct log_cmdline log_cmdline; -+ -+static int __init log_setup(char *str) -+{ -+ struct log_cmdline *c; -+ -+ c = &log_cmdline; -+ memcpy(c->name, str, sizeof(c->name)); -+ -+ return 1; -+} -+ -+__setup("paniclog=", log_setup); -+ -+void panic_trig(const char *str, struct pt_regs *regs, int err) -+{ -+ if (log) -+ die(str, regs, err); -+} -+EXPORT_SYMBOL(panic_trig); -+ -+int log_register(struct log_area *log_f) -+{ -+ if (strcmp(log_cmdline.name, log_f->name) == 0) -+ log = log_f; -+ return 0; -+} -+ -+int log_unregister(struct log_area *log_f) -+{ -+ log = NULL; -+ return 0; -+} -+ -+static loff_t logdrv_lseek(struct file *file, loff_t offset, int orig) -+{ -+ switch (orig) { -+ case 0: -+ /* SEEK_SET */ -+ file->f_pos = offset; -+ break; -+ case 1: -+ /* SEEK_CUR */ -+ file->f_pos += offset; -+ break; -+ case 2: -+ /* SEEK_END */ -+ file->f_pos = log->size + offset; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (file->f_pos < 0) -+ file->f_pos = 0; -+ else if (file->f_pos >= log->size) -+ file->f_pos = log->size - 1; -+ -+ return file->f_pos; -+} -+ -+static int logdrv_open(struct inode *inode, struct file *file) -+{ -+ if (!log) { -+ printk("Not register mechine specific log structure!\n"); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static int logdrv_close(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+static ssize_t logdrv_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ unsigned long p = *ppos; -+ -+ if (count < 0) -+ return -EINVAL; -+ -+ if (count > log->size - p) -+ count = log->size - p; -+ if (log->read) -+ return log->read(buf, count, ppos); -+ -+ if (copy_to_user((void *)buf, (void *)(log->start + *ppos), count)) -+ return -EFAULT; -+ -+ *ppos += count; -+ return count; -+} -+ -+static struct file_operations logdrv_fops = { -+ owner: THIS_MODULE, -+ llseek: logdrv_lseek, -+ read: logdrv_read, -+ open: logdrv_open, -+ release: logdrv_close, -+}; -+ -+static struct miscdevice logdrv_miscdev = { -+ LOGDRV_MINOR, -+ "log drv", -+ &logdrv_fops -+}; -+ -+extern void logbuf_info(char **st, unsigned long *cnt); -+extern struct pxafb_info *pxafbi; -+extern int get_irq_list(char *buf); -+ -+extern atomic_t vm_committed_space; -+void dump_proc_meminfo(void) -+{ -+ struct sysinfo i; -+ char buf[1024]; -+ int len; -+ int pg_size, committed; -+ -+#define K(x) ((x) << (PAGE_SHIFT - 10)) -+#define B(x) ((unsigned long long)(x) << PAGE_SHIFT) -+ -+ si_meminfo(&i); -+ si_swapinfo(&i); -+ -+ pg_size = atomic_read(&page_cache_size) - i.bufferram ; -+ committed = atomic_read(&vm_committed_space); -+ -+ len = sprintf(buf, " total: used: free: shared: buffers: cached:\n" -+ "Mem: %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n" -+ "Swap: %8Lu %8Lu %8Lu\n", -+ B(i.totalram), B(i.totalram-i.freeram), B(i.freeram), -+ B(i.sharedram), B(i.bufferram), -+ B(pg_size), B(i.totalswap), -+ B(i.totalswap-i.freeswap), B(i.freeswap)); -+ -+ len += sprintf(buf+len, -+ "MemTotal: %8lu kB\n" -+ "MemFree: %8lu kB\n" -+ "MemShared: %8lu kB\n" -+ "Buffers: %8lu kB\n" -+ "Cached: %8lu kB\n" -+ "SwapCached: %8lu kB\n" -+ "Active: %8u kB\n" -+ "Inactive: %8u kB\n" -+ "HighTotal: %8lu kB\n" -+ "HighFree: %8lu kB\n" -+ "LowTotal: %8lu kB\n" -+ "LowFree: %8lu kB\n" -+ "SwapTotal: %8lu kB\n" -+ "SwapFree: %8lu kB\n" -+ "Committed_AS: %8u kB\n", -+ K(i.totalram), -+ K(i.freeram), -+ K(i.sharedram), -+ K(i.bufferram), -+ K(pg_size - swapper_space.nrpages), -+ K(swapper_space.nrpages), -+ K(nr_active_pages), -+ K(nr_inactive_pages), -+ K(i.totalhigh), -+ K(i.freehigh), -+ K(i.totalram-i.totalhigh), -+ K(i.freeram-i.freehigh), -+ K(i.totalswap), -+ K(i.freeswap), -+ K(committed)); -+ -+ printk(KERN_EMERG " [meminfo] len 0x%x\n %s\n", len, buf); -+} -+ -+int panic_log_notify(struct notifier_block *self, unsigned long code, void *unused) -+{ -+ unsigned long count; -+ char *start; -+ -+ printk(KERN_EMERG "****** panic time: %d ******\n", OSCR); //RCNR); -+ -+ if(pxafbi) -+ { -+ int i; -+ unsigned long *p; -+ printk(KERN_EMERG " pxafbi->map_cpu: 0x%x, size 0x%x\n", pxafbi->map_cpu, pxafbi->map_size); -+ p = (unsigned long)(pxafbi->map_cpu); -+ for(i=0; i<(pxafbi->map_size/sizeof(unsigned long)); i++) -+ *p++ = 0x0; -+ printk(KERN_EMERG "****** panic time: %d ******\n", OSCR); -+ } -+ -+ if(1) -+ { -+ // cat /proc/interrupts -+ char buf[1024]; -+ int len; -+ -+ len = get_irq_list(buf); -+ printk(KERN_EMERG " [interrupts] len 0x%x\n", len); -+ printk(KERN_EMERG "%s\n", buf); -+ } -+ -+ if(1) -+ { -+ // cat /proc/meminfo -+ dump_proc_meminfo(); -+ } -+ -+ /* Below 2 lines will overwrite useful information if log_buf is not large enough */ -+ printk(KERN_EMERG "****** show task state when panic *******\n"); -+ show_state(); -+ -+ /* get syslog buf info: start position, number of chars */ -+ logbuf_info(&start, &count); -+ -+ /* write information to log area */ -+ if (log && log->write) -+ log->write(start, count); -+ -+ printk(KERN_EMERG "OK, Now we exit panic log function!\n"); -+ -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block panic_log_nb = { -+ panic_log_notify, -+ NULL, -+ 0 -+}; -+ -+extern struct notifier_block *panic_notifier_list; -+static int __init log_init(void) -+{ -+ misc_register(&logdrv_miscdev); -+ return notifier_chain_register(&panic_notifier_list, &panic_log_nb); -+} -+ -+static void __exit log_exit(void) -+{ -+ notifier_chain_unregister(&panic_notifier_list, &panic_log_nb); -+ misc_deregister(&logdrv_miscdev); -+} -+ -+module_init(log_init); -+module_exit(log_exit); -+ -+EXPORT_SYMBOL(log_register); -+EXPORT_SYMBOL(log_unregister); -+ -+MODULE_AUTHOR("zxf <w19962@motorola.com>"); -+MODULE_DESCRIPTION("Kernel panic log interface"); -+MODULE_LICENSE("GPL"); -+ -Index: linux-2.6.16.5-a/drivers/misc/ezx/log.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/drivers/misc/ezx/log.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,35 @@ -+/* -+ * Kernel panic log interface for Linux on A760(XScale PXA262). -+ * -+ * Copyright (c) 2000 Motorola -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * 0.01 2003-07-01 zxf <w19962@motorola.com> -+ * - initial release -+ */ -+ -+#ifndef _PANIC_LOG_H_ -+#define _PANIC_LOG_H_ -+ -+#include <linux/fs.h> -+ -+struct log_area { -+ char name[8]; -+ unsigned long start; -+ unsigned long size; -+ ssize_t (*write) (const char *buf, size_t count); -+ ssize_t (*read) (const char *buf, size_t count, loff_t *ppos); -+}; -+ -+struct log_cmdline { -+ char name[8]; -+}; -+ -+extern int log_register(struct log_area *log_f); -+extern int log_unregister(struct log_area *log_f); -+ -+#endif /* _PANIC_LOG_H_ */ -Index: linux-2.6.16.5-a/include/linux/keypad.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/include/linux/keypad.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,137 @@ -+#ifndef __LINUX_KEYPAD_H -+#define __LINUX_KEYPAD_H -+ -+/* -+ * include/linux/keypad.h -+ * -+ * (c) Copyright Motorola 2003, All rights reserved. -+ */ -+ -+#include <linux/ioctl.h> -+ -+#define KEYDOWN 0x8000 -+#define KEYUP 0x0000 -+ -+#define EVENTSIZE sizeof(short) -+#define KEY_IS_DOWN(x) ((x) & KEYDOWN) -+#define KEYCODE(x) ((x) & 0x7fff) -+ -+struct autorepeatinfo { -+ int r_repeat; /* 1 to do autorepeat, 0 to not do it */ -+ int r_time_to_first_repeat; /* time to first repeat in milliseconds */ -+ int r_time_between_repeats; /* time between repeats in milliseconds */ -+}; -+ -+#define KEYPAD_IOCTL_BASE 'k' -+ -+/* -+ * return the bitmap of keys currently down. -+ * The bitmap is an array of NUM_WORDS_IN_BITMAP unsigned long words. -+ * We count the bits starting with 1 in the rightmost position in -+ * the rightmost (highest-indexed) word. If NUM_WORDS_IN_BITMAP is two, -+ * the bitmap looks like this: -+ * 0 1 -+ * ---------------------------------------------------- -+ * | 64 63 ........... 34 33 | 32 31 ............. 2 1 | -+ * ---------------------------------------------------- -+ * Bit n corresponds to key code n. -+ */ -+ -+#define KEYPAD_IOC_GETBITMAP _IOR(KEYPAD_IOCTL_BASE,1,unsigned long *) -+#define NUM_WORDS_IN_BITMAP 2 -+ -+/** -+ * put the specified event on the keypad's input queue and update the bitmap. -+ * The exact event as specified will be returned by read() when it -+ * reaches the front of the queue. A key press event consists of -+ * the key code or'd with KEYDOWN. A key release event consists of -+ * just the key code. -+ */ -+#define KEYPAD_IOC_INSERT_EVENT _IOW(KEYPAD_IOCTL_BASE,2,unsigned short) -+ -+/** -+ * have the driver interpret the specified scan register values as -+ * if it had gotten an interrupt. The passed-in argument is a pointer -+ * to three consecutive 32-bit words in this order: KPAS, KPASMKP0, KPASMKP1. -+ */ -+#define KEYPAD_IOC_INSERTKEYSCAN _IOW(KEYPAD_IOCTL_BASE,3,unsigned long *) -+ -+/* get the hardware debounce interval (in milliseconds) */ -+#define KEYPAD_IOC_GET_DEBOUNCE_INTERVAL \ -+ _IOR(KEYPAD_IOCTL_BASE,4,unsigned short *) -+ -+/* set the hardware debounce interval (in milliseconds) */ -+#define KEYPAD_IOC_SET_DEBOUNCE_INTERVAL \ -+ _IOW(KEYPAD_IOCTL_BASE,4,unsigned short) -+ -+/* get "Ignore Multiple Key Press" bit; 1 means they are ignored */ -+#define KEYPAD_IOC_GET_IMKP_SETTING _IOR(KEYPAD_IOCTL_BASE,5,unsigned char *) -+ -+/* set "Ignore Multiple Key Press" bit; 1 means they will be ignored */ -+#define KEYPAD_IOC_SET_IMKP_SETTING _IOW(KEYPAD_IOCTL_BASE,5,unsigned char) -+ -+/* -+ * specify what to do about autorepeat on held keys -+ * the 3rd argument is a pointer to a struct autorepeat -+ */ -+#define KEYPAD_IOC_SET_AUTOREPEAT _IOW(KEYPAD_IOCTL_BASE,6,unsigned long *) -+ -+#define KEYPADI_TURN_ON_LED 1 -+#define KEYPADI_TURN_OFF_LED 0 -+/* -+ * the constant KEY_k is both the code for key k in an event returned by -+ * read() and the bit position for key k in the bitmap returned by -+ * ioctl(KEYPAD_IOC_GETBITMAP). -+ */ -+#define KEYPAD_NONE 0 -+ -+#define KEYPAD_0 1 -+#define KEYPAD_1 2 -+#define KEYPAD_2 3 -+#define KEYPAD_3 4 -+#define KEYPAD_4 5 -+#define KEYPAD_5 6 -+#define KEYPAD_6 7 -+#define KEYPAD_7 8 -+#define KEYPAD_8 9 -+#define KEYPAD_9 10 -+ -+#define KEYPAD_UP 11 -+#define KEYPAD_DOWN 12 -+#define KEYPAD_LEFT 13 -+#define KEYPAD_RIGHT 14 -+#define KEYPAD_POUND 15 -+#define KEYPAD_STAR 16 -+#define KEYPAD_MENU 17 -+#define KEYPAD_SLEFT 18 -+#define KEYPAD_SRIGHT 19 -+#define KEYPAD_VOLUP 20 -+#define KEYPAD_VOLDOWN 21 -+#define KEYPAD_CAMERA 22 -+#define KEYPAD_CLEAR 23 -+#define KEYPAD_CARRIER 24 -+#define KEYPAD_ACTIVATE 25 -+#define KEYPAD_SEND 26 -+#define KEYPAD_SMART 27 -+#define KEYPAD_VAVR 28 -+ -+#define KEYPAD_CENTER 29 -+#define KEYPAD_HOME 30 -+#define KEYPAD_A 31 -+#define KEYPAD_B 32 -+#define KEYPAD_GAME_R 33 -+#define KEYPAD_GAME_L 34 -+#define KEYPAD_CAMERA_VOICE 35 -+//#define KEYPAD_SCREEN_LOCK 36 -+#define KEYPAD_POWER 37 -+ -+#define KEYPAD_OK 38 -+#define KEYPAD_CANCEL 39 -+#define KEYPAD_PTT 40 -+#define KEYPAD_JOG_UP 41 -+#define KEYPAD_JOG_MIDDLE 42 -+#define KEYPAD_JOG_DOWN 43 -+ -+#define KEYPAD_MAXCODE 43 -+ -+#endif /* __LINUX_KEYPAD_H */ -Index: linux-2.6.16.5-a/include/linux/wrapper.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.16.5-a/include/linux/wrapper.h 2006-05-04 17:07:04.000000000 +0200 -@@ -0,0 +1,7 @@ -+#ifndef _WRAPPER_H_ -+#define _WRAPPER_H_ -+ -+#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags)) -+#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags)) -+ -+#endif /* _WRAPPER_H_ */ -Index: linux-2.6.16.5-a/include/linux/apm_bios.h -=================================================================== ---- linux-2.6.16.5-a.orig/include/linux/apm_bios.h 2006-05-04 17:06:50.000000000 +0200 -+++ linux-2.6.16.5-a/include/linux/apm_bios.h 2006-05-04 17:07:04.000000000 +0200 -@@ -208,6 +208,31 @@ - #define APM_CAP_RESUME_SUSPEND_PCMCIA 0x0080 /* Resume on PCMCIA Ring */ - - /* -+ * kernel event definitions for our ezx platform -+ */ -+enum -+{ -+ KRNL_ACCS_ATTACH, -+ KRNL_ACCS_DETACH, -+ KRNL_BLUETOOTH, -+ KRNL_TOUCHSCREEN, -+ KRNL_KEYPAD, -+ KRNL_RTC, -+ KRNL_FLIP_ON, -+ KRNL_FLIP_OFF, -+ KRNL_VOICE_REC, -+ KRNL_ICL, -+ KRNL_BP, -+ KRNL_BP_WDI, -+ KRNL_PROC_INACT, -+ KRNL_IDLE_TIMEOUT, -+ KRNL_SCREEN_LOCK, -+ KRNL_SCREEN_UNLOCK -+}; -+ -+ -+ -+/* - * ioctl operations - */ - #include <linux/ioctl.h> |