diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/Kconfig hh-head-clean-work/arch/arm/mach-pxa/Kconfig --- hh-head/arch/arm/mach-pxa/Kconfig 2006-06-15 21:17:18.000000000 -0400 +++ hh-head-clean-work/arch/arm/mach-pxa/Kconfig 2006-06-17 00:48:03.000000000 -0400 @@ -140,6 +140,11 @@ help Enable common support for Sharp Cxx00 models +config PXA27X_KEYBOARD + tristate + help + Enable support for PXA27x matrix keyboard controller + config PXA_SSP tristate help diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/Makefile hh-head-clean-work/arch/arm/mach-pxa/Makefile --- hh-head/arch/arm/mach-pxa/Makefile 2006-06-15 21:17:18.000000000 -0400 +++ hh-head-clean-work/arch/arm/mach-pxa/Makefile 2006-06-17 00:30:31.000000000 -0400 @@ -54,6 +54,7 @@ # Misc features obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PXA_SSP) += ssp.o +obj-$(CONFIG_PXA27X_KEYBOARD) += pxa27x_keyboard.o ifeq ($(CONFIG_PXA27x),y) obj-$(CONFIG_PM) += standby.o diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/htcapache/Kconfig hh-head-clean-work/arch/arm/mach-pxa/htcapache/Kconfig --- hh-head/arch/arm/mach-pxa/htcapache/Kconfig 2006-06-14 16:16:31.000000000 -0400 +++ hh-head-clean-work/arch/arm/mach-pxa/htcapache/Kconfig 2006-06-17 00:48:28.000000000 -0400 @@ -1,8 +1,9 @@ menuconfig MACH_HTCAPACHE bool "HTC Apache" select PXA27x + select GPIO_KEYS + select PXA27X_KEYBOARD help Say Y here if you intend to run this kernel on a HTC Apache. Currently there is only basic support for this PDA. - diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/htcapache/Makefile hh-head-clean-work/arch/arm/mach-pxa/htcapache/Makefile --- hh-head/arch/arm/mach-pxa/htcapache/Makefile 2006-06-14 16:16:31.000000000 -0400 +++ hh-head-clean-work/arch/arm/mach-pxa/htcapache/Makefile 2006-06-17 01:47:36.000000000 -0400 @@ -3,4 +3,3 @@ # obj-$(CONFIG_MACH_HTCAPACHE) += htcapache.o -obj-y += htcapache-buttons.o diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/htcapache/htcapache-buttons.c hh-head-clean-work/arch/arm/mach-pxa/htcapache/htcapache-buttons.c --- hh-head/arch/arm/mach-pxa/htcapache/htcapache-buttons.c 2006-06-16 21:26:12.000000000 -0400 +++ hh-head-clean-work/arch/arm/mach-pxa/htcapache/htcapache-buttons.c 1969-12-31 19:00:00.000000000 -0500 @@ -1,251 +0,0 @@ -/* - * linux/arch/arm/mach-pxa/htcapache/htcapache-buttons.c - * - * Button driver for Palm Treo 650 - * - * Author: Alex Osborne - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define KPASMKP(col) (col/2==0 ? KPASMKP0 : col/2==1 ? KPASMKP1 : col/2==2 ? KPASMKP2 : KPASMKP3) -#define KPASMKPx_MKC(row, col) (1 << (row + 16*(col%2))) - -/* - * LifeDrive keypad layout: - * Pin MKOUT0 MKOUT1 MKOUT2 - * MKIN0 unused Folder Nav-Up - * MKIN1 Picture Star Nav-Right - * MKIN2 Home VMemo Nav-Down - * MKIN3 RotDisp Center Nav-Left - */ - -#define HTCAPACHE_KM_ROWS 7 -#define HTCAPACHE_KM_COLS 7 - -static struct { - int keycode; - char *desc; -} button_matrix[HTCAPACHE_KM_ROWS][HTCAPACHE_KM_COLS] = { - { /* row 0 */ - { -1, "Unused" }, // Unused - { KEY_LEFTSHIFT,"Left Shift" }, - { -1, "Unused" }, // Unused - { KEY_Q, "Q" }, - { KEY_W, "W" }, - { KEY_E, "E" }, - { KEY_R, "R" }, - }, { /* row 1 */ - { -1, "Unused" }, // Unused - { -1, "Unused" }, // Unused - { KEY_LEFTALT, "Red Dot" }, // Red Dot - { KEY_T, "T" }, - { KEY_Y, "Y" }, - { KEY_U, "U" }, - { KEY_I, "I" }, - }, { /* row 2 */ - { -1, "Unused" }, // Unused - { KEY_LEFTMETA, "WinKey" }, // Windows Key - { -1, "Unused" }, // Unused - { KEY_ENTER, "Return" }, - { KEY_SPACE, "Space" }, - { KEY_BACKSPACE,"Backspace" }, - { KEY_A, "A" }, - }, { /* row 3 */ - { -1, "Unused" }, //unused - { KEY_S, "S" }, - { KEY_D, "D" }, - { KEY_F, "F" }, - { KEY_G, "G" }, - { KEY_H, "H" }, - { KEY_J, "J" }, - }, { /* row 4 */ - { KEY_LEFTCTRL, "Left Menu" }, // Left Menu - { KEY_K, "K" }, - { KEY_Z, "Z" }, - { KEY_X, "X" }, - { KEY_C, "C" }, - { KEY_V, "V" }, - { KEY_B, "B" }, - }, { /* row 5 */ - { KEY_RIGHTCTRL,"Right Menu" }, // Right Menu - { KEY_N, "N" }, - { KEY_M, "M" }, - { KEY_O, "O" }, - { KEY_L, "L" }, - { KEY_P, "P" }, - { KEY_DOT, "." }, - }, { /* row 6 */ - { -1, "Unused" }, // Unused - { KEY_LEFT, "Left Arrow" }, - { KEY_DOWN, "Down Arrow" }, - { KEY_UP, "Up Arrow" }, - { KEY_ESC, "OK" }, // OK Button - { KEY_TAB, "Tab" }, - { KEY_RIGHT, "Right Arrow" }, - }, -}; - -struct input_dev* button_dev; - -static void htcapache_buttons_report_event(int row, int col, int pressed) -{ - if(row >= HTCAPACHE_KM_ROWS || col >= HTCAPACHE_KM_COLS) { - printk(KERN_ERR "htcapache_buttons_report_event: out of bounds " - "key event row=%d col=%d pressed=%d\n", row, col, - pressed); - return; - } - - if( button_matrix[row][col].keycode >= 0 ) { - input_report_key(button_dev, button_matrix[row][col].keycode, pressed); - } -} - -static irqreturn_t htcapache_keypad_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - int mi; - int row=-1, col=-1; - - - /* - * notify controller that interrupt was handled, otherwise it'll - * constantly send interrupts and lock up the device. - */ - mi = KPC & KPC_MI; - - /* report the status of every button */ - for(row=0; row < HTCAPACHE_KM_ROWS; row++) { - for(col=0; col < HTCAPACHE_KM_COLS; col++) { - htcapache_buttons_report_event(row, col, KPASMKP(col) & KPASMKPx_MKC(row, col)); - } - } - - return IRQ_HANDLED; -} - -static int __init htcapache_buttons_probe(struct device *dev) -{ - int err; - - pxa_set_cken(CKEN19_KEYPAD, 1); - - /* - * setup GPIOs for the LifeDrive keypad matrix - */ - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN0_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN1_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN2_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN3_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN4_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN5_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN6_MD); -// pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKIN7_MD); - - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT0_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT1_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT2_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT3_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT4_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT5_MD); - pxa_gpio_mode(GPIO_NR_HTCAPACHE_KP_MKOUT6_MD); - - /* - * setup the PXA270 keypad controller for automatic on-activity scanning - */ - KPC |= HTCAPACHE_KM_ROWS << 26; /* lifedrive keypad matrix has 4 rows */ - KPC |= HTCAPACHE_KM_COLS << 23; /* and 3 columns */ - - KPC |= KPC_ASACT; /* enable automatic scan on activity */ - KPC &= ~KPC_AS; /* disable automatic scan */ - KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */ - - KPC &= ~KPC_DE; /* disable direct keypad */ - KPC &= ~KPC_DIE; /* disable direct keypad interrupt */ - - err = request_irq(IRQ_KEYPAD, htcapache_keypad_irq_handler, SA_INTERRUPT, - "keypad", NULL); - if (err) { - printk(KERN_ERR "htcapache_buttons_probe: cannot request keypad IRQ\n"); - pxa_set_cken(CKEN19_KEYPAD, 0); - return -1; - } - - KPC |= KPC_ME; /* matrix keypad enabled */ - KPC |= KPC_ME; /* matrix keypad interrupt enabled */ - - return 0; -} - -static int __exit htcapache_buttons_remove (struct device *dev) -{ - free_irq(IRQ_KEYPAD, NULL); - pxa_set_cken(CKEN19_KEYPAD, 0); - return 0; -} - -static struct device_driver htcapache_buttons_driver = { - .name = "htcapache-buttons", - .bus = &platform_bus_type, - .probe = htcapache_buttons_probe, - .remove = htcapache_buttons_remove, -#ifdef CONFIG_PM - .suspend = NULL, - .resume = NULL, -#endif -}; - -static int __init htcapache_buttons_init(void) -{ - int row, col; - - if(!machine_is_htcapache()) - return -ENODEV; - - button_dev = input_allocate_device(); - - button_dev->evbit[0] = BIT(EV_KEY); - for(row=0; row < HTCAPACHE_KM_ROWS; row++) { - for(col=0; col < HTCAPACHE_KM_COLS; col++) { - if( button_matrix[row][col].keycode >= 0 ) { - button_dev->keybit[ LONG - (button_matrix[row][col].keycode)] |= - BIT(button_matrix[row][col].keycode); - } - } - } - - button_dev->name = "Palm LifeDrive buttons"; - button_dev->id.bustype = BUS_HOST; - input_register_device(button_dev); - - return driver_register(&htcapache_buttons_driver); -} - -static void __exit htcapache_buttons_exit(void) -{ - input_unregister_device(button_dev); - driver_unregister(&htcapache_buttons_driver); -} - -module_init(htcapache_buttons_init); -module_exit(htcapache_buttons_exit); - -MODULE_AUTHOR ("Alex Osborne "); -MODULE_DESCRIPTION ("Button support for Palm LifeDrive"); -MODULE_LICENSE ("GPL"); diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/htcapache/htcapache.c hh-head-clean-work/arch/arm/mach-pxa/htcapache/htcapache.c --- hh-head/arch/arm/mach-pxa/htcapache/htcapache.c 2006-06-16 21:26:12.000000000 -0400 +++ hh-head-clean-work/arch/arm/mach-pxa/htcapache/htcapache.c 2006-06-17 01:21:03.000000000 -0400 @@ -1,12 +1,9 @@ /* * linux/arch/arm/mach-pxa/htcapache/htcapache.c * - * Support for the Intel XScale based Palm PDAs. Only the LifeDrive is - * supported at the moment. + * Support for HTC Apache phones. * - * Author: Alex Osborne - * - * USB stubs based on aximx30.c (Michael Opdenacker) + * Based on code from: Alex Osborne * */ @@ -15,6 +12,7 @@ #include #include #include +#include #include #include @@ -24,9 +22,20 @@ #include #include #include +#include +#include +#include #include "../generic.h" +#define GPSR_BIT(n) (GPSR((n)) = GPIO_bit((n))) +#define GPCR_BIT(n) (GPCR((n)) = GPIO_bit((n))) + + +/**************************************************************** + * Backlight + ****************************************************************/ + static void htcapache_backlight_power(int on) { /** @@ -37,29 +46,9 @@ } -/* USB Device Controller */ - -#define GPSR_BIT(n) (GPSR((n)) = GPIO_bit((n))) -#define GPCR_BIT(n) (GPCR((n)) = GPIO_bit((n))) - -static void udc_command(int cmd) -{ - switch (cmd) - { - case PXA2XX_UDC_CMD_DISCONNECT: - printk (KERN_NOTICE "USB cmd disconnect\n"); - GPSR_BIT(99); - break; - case PXA2XX_UDC_CMD_CONNECT: - printk (KERN_NOTICE "USB cmd connect\n"); - GPCR_BIT(99); - break; - } -} - -static struct pxa2xx_udc_mach_info htcapache_udc_mach_info = { - .udc_command = udc_command, -}; +/**************************************************************** + * Frame buffer + ****************************************************************/ static struct pxafb_mach_info htcapache_lcd __initdata = { .pixclock = 192307, @@ -79,20 +68,216 @@ .pxafb_backlight_power = htcapache_backlight_power, }; -struct platform_device htcapache_buttons = { - .name = "htcapache-buttons", + +/**************************************************************** + * Pull out keyboard + ****************************************************************/ + +static struct pxa27x_keyboard_platform_data htcapache_kbd = { + .nr_rows = 7, + .nr_cols = 7, + .keycodes = { + { + /* row 0 */ + -1, // Unused + KEY_LEFTSHIFT, // Left Shift + -1, // Unused + KEY_Q, // Q + KEY_W, // W + KEY_E, // E + KEY_R, // R + }, { /* row 1 */ + -1, // Unused + -1, // Unused + KEY_LEFTALT, // Red Dot + KEY_T, // T + KEY_Y, // Y + KEY_U, // U + KEY_I, // I + }, { /* row 2 */ + -1, // Unused + KEY_LEFTMETA, // Windows Key + -1, // Unused + KEY_ENTER, // Return + KEY_SPACE, // Space + KEY_BACKSPACE, // Backspace + KEY_A, // A + }, { /* row 3 */ + -1, // Unused + KEY_S, // S + KEY_D, // D + KEY_F, // F + KEY_G, // G + KEY_H, // H + KEY_J, // J + }, { /* row 4 */ + KEY_LEFTCTRL, // Left Menu + KEY_K, // K + KEY_Z, // Z + KEY_X, // X + KEY_C, // C + KEY_V, // V + KEY_B, // B + }, { /* row 5 */ + KEY_RIGHTCTRL, // Right Menu + KEY_N, // N + KEY_M, // M + KEY_O, // O + KEY_L, // L + KEY_P, // P + KEY_DOT, // . + }, { /* row 6 */ + -1, // Unused + KEY_LEFT, // Left Arrow + KEY_DOWN, // Down Arrow + KEY_UP, // Up Arrow + KEY_ESC, // OK button + KEY_TAB, // Tab + KEY_RIGHT, // Right Arrow + }, + }, + .gpio_modes = { + GPIO_NR_HTCAPACHE_KP_MKIN0_MD, + GPIO_NR_HTCAPACHE_KP_MKIN1_MD, + GPIO_NR_HTCAPACHE_KP_MKIN2_MD, + GPIO_NR_HTCAPACHE_KP_MKIN3_MD, + GPIO_NR_HTCAPACHE_KP_MKIN4_MD, + GPIO_NR_HTCAPACHE_KP_MKIN5_MD, + GPIO_NR_HTCAPACHE_KP_MKIN6_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT0_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT1_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT2_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT3_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT4_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT5_MD, + GPIO_NR_HTCAPACHE_KP_MKOUT6_MD, + }, +}; + +static struct platform_device htcapache_keyboard = { + .name = "pxa27x-keyboard", + .id = -1, + .dev = { + .platform_data = &htcapache_kbd, + }, +}; + + +/**************************************************************** + * Buttons on side + ****************************************************************/ + +static struct gpio_keys_button htcapache_button_list[] = { + { .gpio = GPIO_NR_HTCAPACHE_BUTTON_POWER, .keycode = KEY_POWER}, + { .gpio = GPIO_NR_HTCAPACHE_BUTTON_RECORD, .keycode = KEY_RECORD}, + { .gpio = GPIO_NR_HTCAPACHE_BUTTON_VOLUP, .keycode = KEY_VOLUMEUP}, + { .gpio = GPIO_NR_HTCAPACHE_BUTTON_VOLDOWN, .keycode = KEY_VOLUMEDOWN}, + { .gpio = GPIO_NR_HTCAPACHE_BUTTON_BROWSER, .keycode = KEY_WWW}, + { .gpio = GPIO_NR_HTCAPACHE_BUTTON_CAMERA, .keycode = KEY_CAMERA}, +}; + +static struct gpio_keys_platform_data htcapache_buttons_data = { + .buttons = htcapache_button_list, + .nbuttons = ARRAY_SIZE(htcapache_button_list), +}; + +static struct platform_device htcapache_buttons = { + .name = "gpio-keys", .id = -1, + .dev = { + .platform_data = &htcapache_buttons_data, + }, }; + +/**************************************************************** + * USB client controller + ****************************************************************/ + +static void udc_command(int cmd) +{ + switch (cmd) + { + case PXA2XX_UDC_CMD_DISCONNECT: + printk(KERN_NOTICE "USB cmd disconnect\n"); + GPSR_BIT(GPIO_NR_HTCAPACHE_USB); + break; + case PXA2XX_UDC_CMD_CONNECT: + printk(KERN_NOTICE "USB cmd connect\n"); + GPCR_BIT(GPIO_NR_HTCAPACHE_USB); + break; + } +} + +static struct pxa2xx_udc_mach_info htcapache_udc_mach_info = { + .udc_command = udc_command, +}; + + +/**************************************************************** + * Mini-SD card + ****************************************************************/ + +static int +htcapache_mci_init(struct device *dev + , irqreturn_t (*ih)(int, void *, struct pt_regs *) + , void *data) +{ + int err = request_irq(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N) + , ih, SA_INTERRUPT + , "MMC/SD card detect", data); + set_irq_type(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N) + , IRQT_BOTHEDGE); + if (err) { + printk(KERN_ERR "htcapache_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); + return -1; + } + + return 0; +} + +static void htcapache_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data* p_d = dev->platform_data; + + // XXX - No idea if this is correct for apache.. + if ((1 << vdd) & p_d->ocr_mask) { + printk(KERN_NOTICE "MMC power up\n"); + GPSR_BIT(GPIO_NR_HTCAPACHE_SD_POWER_N); + } else { + printk(KERN_NOTICE "MMC power down\n"); + GPCR_BIT(GPIO_NR_HTCAPACHE_SD_POWER_N); + } +} + +static void htcapache_mci_exit(struct device *dev, void *data) +{ + free_irq(IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N), data); +} + +static struct pxamci_platform_data htcapache_mci_platform_data = { + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, + .init = htcapache_mci_init, + .setpower = htcapache_mci_setpower, + .exit = htcapache_mci_exit, +}; + + +/**************************************************************** + * Init + ****************************************************************/ + static struct platform_device *devices[] __initdata = { - &htcapache_buttons + &htcapache_keyboard, + &htcapache_buttons, }; static void __init htcapache_init(void) { - set_pxa_fb_info( &htcapache_lcd ); - platform_add_devices( devices, ARRAY_SIZE(devices) ); - pxa_set_udc_info( &htcapache_udc_mach_info ); + set_pxa_fb_info(&htcapache_lcd); + pxa_set_udc_info(&htcapache_udc_mach_info); + pxa_set_mci_info(&htcapache_mci_platform_data); + platform_add_devices(devices, ARRAY_SIZE(devices)); } MACHINE_START(HTCAPACHE, "HTC Apache") diff -x CVS -x '.#*' -urN hh-head/arch/arm/mach-pxa/pxa27x_keyboard.c hh-head-clean-work/arch/arm/mach-pxa/pxa27x_keyboard.c --- hh-head/arch/arm/mach-pxa/pxa27x_keyboard.c 1969-12-31 19:00:00.000000000 -0500 +++ hh-head-clean-work/arch/arm/mach-pxa/pxa27x_keyboard.c 2006-06-17 00:59:35.000000000 -0400 @@ -0,0 +1,147 @@ +/* + * linux/arch/arm/mach-pxa/pxa27x_keyboard.c + * + * Driver for the pxa27x matrix keyboard controller. + * + * Based on code by: Alex Osborne + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#define DRIVER_NAME "pxa27x-keyboard" + +#define KPASMKP(col) (col/2==0 ? KPASMKP0 : col/2==1 ? KPASMKP1 : col/2==2 ? KPASMKP2 : KPASMKP3) +#define KPASMKPx_MKC(row, col) (1 << (row + 16*(col%2))) + +static irqreturn_t +pxakbd_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + struct device *dev = dev_id; + struct pxa27x_keyboard_platform_data *pdev = dev->platform_data; + struct input_dev *button_dev = dev->driver_data; + int mi; + int row, col; + + /* + * notify controller that interrupt was handled, otherwise it'll + * constantly send interrupts and lock up the device. + */ + mi = KPC & KPC_MI; + + /* report the status of every button */ + for (row=0; row < pdev->nr_rows; row++) { + for (col=0; col < pdev->nr_cols; col++) { + int pressed = KPASMKP(col) & KPASMKPx_MKC(row, col); + input_report_key(button_dev + , pdev->keycodes[row][col] + , pressed); + } + } + + return IRQ_HANDLED; +} + +static int pxakbd_probe(struct device *dev) +{ + struct input_dev *button_dev; + struct pxa27x_keyboard_platform_data *pdev = dev->platform_data; + int row, col, i, err; + + // Create and register the input driver. + dev->driver_data = button_dev = input_allocate_device(); + init_input_dev(button_dev); + button_dev->evbit[0] = BIT(EV_KEY); + for (row=0; row < pdev->nr_rows; row++) { + for (col=0; col < pdev->nr_cols; col++) { + int code = pdev->keycodes[row][col]; + if (code <= 0) + continue; + set_bit(code, button_dev->keybit); + } + } + button_dev->name = DRIVER_NAME; + button_dev->id.bustype = BUS_HOST; + input_register_device(button_dev); + + // + // Enable keyboard. + // + + pxa_set_cken(CKEN19_KEYPAD, 1); + + // Setup GPIOs. + for (i=0; i < pdev->nr_rows + pdev->nr_cols; i++) + pxa_gpio_mode(pdev->gpio_modes[i]); + + KPC |= pdev->nr_rows << 26; + KPC |= pdev->nr_cols << 23; + + KPC |= KPC_ASACT; /* enable automatic scan on activity */ + KPC &= ~KPC_AS; /* disable automatic scan */ + KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */ + + KPC &= ~KPC_DE; /* disable direct keypad */ + KPC &= ~KPC_DIE; /* disable direct keypad interrupt */ + + err = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, SA_INTERRUPT, + DRIVER_NAME, dev); + if (err) { + printk(KERN_ERR "Cannot request keypad IRQ\n"); + input_unregister_device(button_dev); + pxa_set_cken(CKEN19_KEYPAD, 0); + return -1; + } + + KPC |= KPC_ME; /* matrix keypad enabled */ + KPC |= KPC_ME; /* matrix keypad interrupt enabled */ + + return 0; +} + +static int pxakbd_remove(struct device *dev) +{ + struct input_dev *button_dev = dev->driver_data; + input_unregister_device(button_dev); + free_irq(IRQ_KEYPAD, NULL); + pxa_set_cken(CKEN19_KEYPAD, 0); + return 0; +} + +static struct device_driver pxakbd_driver = { + .name = DRIVER_NAME, + .bus = &platform_bus_type, + .probe = pxakbd_probe, + .remove = pxakbd_remove, +}; + +static int __init pxakbd_init(void) +{ + return driver_register(&pxakbd_driver); +} + +static void __exit pxakbd_exit(void) +{ + driver_unregister(&pxakbd_driver); +} + +module_init(pxakbd_init); +module_exit(pxakbd_exit); + +MODULE_DESCRIPTION("PXA27x Matrix Keyboard Driver"); +MODULE_LICENSE("GPL"); diff -x CVS -x '.#*' -urN hh-head/include/asm-arm/arch-pxa/htcapache-gpio.h hh-head-clean-work/include/asm-arm/arch-pxa/htcapache-gpio.h --- hh-head/include/asm-arm/arch-pxa/htcapache-gpio.h 2006-06-14 15:48:11.000000000 -0400 +++ hh-head-clean-work/include/asm-arm/arch-pxa/htcapache-gpio.h 2006-06-16 23:39:48.000000000 -0400 @@ -1,28 +1,46 @@ -/* Palm LifeDrive GPIOs */ +/* HTC Apache GPIOs */ #ifndef _HTCAPACHE_GPIO_H_ #define _HTCAPACHE_GPIO_H_ - /* Palm LifeDrive GPIOs */ -#define GPIO_NR_HTCAPACHE_WM9712_IRQ 90 -#define IRQ_GPIO_HTCAPACHE_WM9712_IRQ IRQ_GPIO(GPIO_NR_HTCAPACHE_WM9712_IRQ) -#define GPIO_HTCAPACHE_POWER_DETECT 4 -#define GPIO_HTCAPACHE_USB_DETECT 0 -#define GPIO_NR_HTCAPACHE_USB_DETECT 3 -#define GPIO_NR_HTCAPACHE_POWER_DETECT 4 -#define GPIO_NR_HTCAPACHE_HOTSYNC_BUTTON_N 10 -#define GPIO_NR_HTCAPACHE_POWER_SWITCH 11 -#define GPIO_NR_HTCAPACHE_EARPHONE_DETECT 13 -#define GPIO_NR_HTCAPACHE_SD_DETECT_N 113 /* SD card inserted; RE FE; Input */ -#define GPIO_NR_HTCAPACHE_LOCK_SWITCH 15 /* keypad lock */ - -#define GPIO_NR_HTCAPACHE_KP_MKIN0 100 -#define GPIO_NR_HTCAPACHE_KP_MKIN1 101 -#define GPIO_NR_HTCAPACHE_KP_MKIN2 102 -#define GPIO_NR_HTCAPACHE_KP_MKIN3 37 -#define GPIO_NR_HTCAPACHE_KP_MKIN4 38 -#define GPIO_NR_HTCAPACHE_KP_MKIN5 90 -#define GPIO_NR_HTCAPACHE_KP_MKIN6 91 -//#define GPIO_NR_HTCAPACHE_KP_MKIN7 13 + +/**************************************************************** + * Mini-SD card + ****************************************************************/ + +#define GPIO_NR_HTCAPACHE_SD_CARD_DETECT_N 13 +#define GPIO_NR_HTCAPACHE_SD_POWER_N 89 + + +/**************************************************************** + * USB + ****************************************************************/ + +#define GPIO_NR_HTCAPACHE_USB 99 + + +/**************************************************************** + * Buttons on side + ****************************************************************/ + +#define GPIO_NR_HTCAPACHE_BUTTON_POWER 0 +#define GPIO_NR_HTCAPACHE_BUTTON_RECORD 95 +#define GPIO_NR_HTCAPACHE_BUTTON_VOLUP 9 +#define GPIO_NR_HTCAPACHE_BUTTON_VOLDOWN 10 +#define GPIO_NR_HTCAPACHE_BUTTON_BROWSER 94 +#define GPIO_NR_HTCAPACHE_BUTTON_CAMERA 93 + + +/**************************************************************** + * Pull out keyboard + ****************************************************************/ + +#define GPIO_NR_HTCAPACHE_KP_MKIN0 100 +#define GPIO_NR_HTCAPACHE_KP_MKIN1 101 +#define GPIO_NR_HTCAPACHE_KP_MKIN2 102 +#define GPIO_NR_HTCAPACHE_KP_MKIN3 37 +#define GPIO_NR_HTCAPACHE_KP_MKIN4 38 +#define GPIO_NR_HTCAPACHE_KP_MKIN5 90 +#define GPIO_NR_HTCAPACHE_KP_MKIN6 91 #define GPIO_NR_HTCAPACHE_KP_MKOUT0 103 #define GPIO_NR_HTCAPACHE_KP_MKOUT1 104 @@ -30,7 +48,7 @@ #define GPIO_NR_HTCAPACHE_KP_MKOUT3 106 #define GPIO_NR_HTCAPACHE_KP_MKOUT4 107 #define GPIO_NR_HTCAPACHE_KP_MKOUT5 108 -#define GPIO_NR_HTCAPACHE_KP_MKOUT6 40 +#define GPIO_NR_HTCAPACHE_KP_MKOUT6 40 #define GPIO_NR_HTCAPACHE_KP_MKIN0_MD (GPIO_NR_HTCAPACHE_KP_MKIN0 | GPIO_ALT_FN_1_IN) #define GPIO_NR_HTCAPACHE_KP_MKIN1_MD (GPIO_NR_HTCAPACHE_KP_MKIN1 | GPIO_ALT_FN_1_IN) @@ -39,8 +57,7 @@ #define GPIO_NR_HTCAPACHE_KP_MKIN4_MD (GPIO_NR_HTCAPACHE_KP_MKIN4 | GPIO_ALT_FN_2_IN) #define GPIO_NR_HTCAPACHE_KP_MKIN5_MD (GPIO_NR_HTCAPACHE_KP_MKIN5 | GPIO_ALT_FN_1_IN) #define GPIO_NR_HTCAPACHE_KP_MKIN6_MD (GPIO_NR_HTCAPACHE_KP_MKIN6 | GPIO_ALT_FN_1_IN) -//#define GPIO_NR_HTCAPACHE_KP_MKIN7_MD (GPIO_NR_HTCAPACHE_KP_MKIN7 | GPIO_ALT_FN_3_IN) - + #define GPIO_NR_HTCAPACHE_KP_MKOUT0_MD (GPIO_NR_HTCAPACHE_KP_MKOUT0 | GPIO_ALT_FN_2_OUT) #define GPIO_NR_HTCAPACHE_KP_MKOUT1_MD (GPIO_NR_HTCAPACHE_KP_MKOUT1 | GPIO_ALT_FN_2_OUT) #define GPIO_NR_HTCAPACHE_KP_MKOUT2_MD (GPIO_NR_HTCAPACHE_KP_MKOUT2 | GPIO_ALT_FN_2_OUT) @@ -48,7 +65,5 @@ #define GPIO_NR_HTCAPACHE_KP_MKOUT4_MD (GPIO_NR_HTCAPACHE_KP_MKOUT4 | GPIO_ALT_FN_2_OUT) #define GPIO_NR_HTCAPACHE_KP_MKOUT5_MD (GPIO_NR_HTCAPACHE_KP_MKOUT5 | GPIO_ALT_FN_2_OUT) #define GPIO_NR_HTCAPACHE_KP_MKOUT6_MD (GPIO_NR_HTCAPACHE_KP_MKOUT6 | GPIO_ALT_FN_1_OUT) - -#define IRQ_GPIO_HTCAPACHE_SD_DETECT_N IRQ_GPIO(GPIO_NR_HTCAPACHE_SD_DETECT_N) - + #endif diff -x CVS -x '.#*' -urN hh-head/include/asm-arm/hardware/pxa27x_keyboard.h hh-head-clean-work/include/asm-arm/hardware/pxa27x_keyboard.h --- hh-head/include/asm-arm/hardware/pxa27x_keyboard.h 1969-12-31 19:00:00.000000000 -0500 +++ hh-head-clean-work/include/asm-arm/hardware/pxa27x_keyboard.h 2006-06-16 23:22:12.000000000 -0400 @@ -0,0 +1,10 @@ +enum { + PXAKBD_MAXROW = 8, + PXAKBD_MAXCOL = 8, +}; + +struct pxa27x_keyboard_platform_data { + int nr_rows, nr_cols; + int keycodes[PXAKBD_MAXROW][PXAKBD_MAXCOL]; + int gpio_modes[PXAKBD_MAXROW + PXAKBD_MAXCOL]; +};