diff options
| -rw-r--r-- | drivers/input/keyboard/Kconfig | 19 | ||||
| -rw-r--r-- | drivers/input/keyboard/Makefile | 5 | ||||
| -rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 147 | ||||
| -rw-r--r-- | include/asm-arm/hardware/gpio_keys.h | 17 |
4 files changed, 183 insertions, 5 deletions
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 049f2f544e75..1b81a72e19d9 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -135,12 +135,12 @@ config KEYBOARD_STOWAWAY | |||
| 135 | config KEYBOARD_CORGI | 135 | config KEYBOARD_CORGI |
| 136 | tristate "Corgi keyboard" | 136 | tristate "Corgi keyboard" |
| 137 | depends on PXA_SHARPSL | 137 | depends on PXA_SHARPSL |
| 138 | default y | 138 | default y |
| 139 | help | 139 | help |
| 140 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx | 140 | Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx |
| 141 | series of PDAs. | 141 | series of PDAs. |
| 142 | 142 | ||
| 143 | To compile this driver as a module, choose M here: the | 143 | To compile this driver as a module, choose M here: the |
| 144 | module will be called corgikbd. | 144 | module will be called corgikbd. |
| 145 | 145 | ||
| 146 | config KEYBOARD_SPITZ | 146 | config KEYBOARD_SPITZ |
| @@ -214,4 +214,17 @@ config KEYBOARD_AAED2000 | |||
| 214 | To compile this driver as a module, choose M here: the | 214 | To compile this driver as a module, choose M here: the |
| 215 | module will be called aaed2000_kbd. | 215 | module will be called aaed2000_kbd. |
| 216 | 216 | ||
| 217 | config KEYBOARD_GPIO | ||
| 218 | tristate "Buttons on CPU GPIOs (PXA)" | ||
| 219 | depends on ARCH_PXA | ||
| 220 | help | ||
| 221 | This driver implements support for buttons connected | ||
| 222 | directly to GPIO pins of PXA CPUs. | ||
| 223 | |||
| 224 | Say Y here if your device has buttons connected | ||
| 225 | directly to GPIO pins of the CPU. | ||
| 226 | |||
| 227 | To compile this driver as a module, choose M here: the | ||
| 228 | module will be called gpio-keys. | ||
| 229 | |||
| 217 | endif | 230 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 568797907347..586a0fe53be6 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
| @@ -16,6 +16,7 @@ obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o | |||
| 16 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | 16 | obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o |
| 17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 17 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
| 18 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 18 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
| 19 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 19 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
| 20 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o | 20 | obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o |
| 21 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | ||
| 21 | 22 | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c new file mode 100644 index 000000000000..3a8f1b427a7f --- /dev/null +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | /* | ||
| 2 | * Driver for keys on GPIO lines capable of generating interrupts. | ||
| 3 | * | ||
| 4 | * Copyright 2005 Phil Blundell | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/version.h> | ||
| 13 | |||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/fs.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | #include <linux/sched.h> | ||
| 19 | #include <linux/pm.h> | ||
| 20 | #include <linux/sysctl.h> | ||
| 21 | #include <linux/proc_fs.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/platform_device.h> | ||
| 24 | #include <linux/input.h> | ||
| 25 | #include <linux/irq.h> | ||
| 26 | |||
| 27 | #include <asm/arch/pxa-regs.h> | ||
| 28 | #include <asm/arch/hardware.h> | ||
| 29 | |||
| 30 | #include <asm/hardware/gpio_keys.h> | ||
| 31 | |||
| 32 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | ||
| 33 | { | ||
| 34 | int i; | ||
| 35 | struct platform_device *pdev = dev_id; | ||
| 36 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 37 | struct input_dev *input = platform_get_drvdata(pdev); | ||
| 38 | |||
| 39 | for (i = 0; i < pdata->nbuttons; i++) { | ||
| 40 | int gpio = pdata->buttons[i].gpio; | ||
| 41 | if (irq == IRQ_GPIO(gpio)) { | ||
| 42 | int state = ((GPLR(gpio) & GPIO_bit(gpio)) ? 1 : 0) ^ (pdata->buttons[i].active_low); | ||
| 43 | |||
| 44 | input_report_key(input, pdata->buttons[i].keycode, state); | ||
| 45 | input_sync(input); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | return IRQ_HANDLED; | ||
| 50 | } | ||
| 51 | |||
| 52 | static int __devinit gpio_keys_probe(struct platform_device *pdev) | ||
| 53 | { | ||
| 54 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 55 | struct input_dev *input; | ||
| 56 | int i, error; | ||
| 57 | |||
| 58 | input = input_allocate_device(); | ||
| 59 | if (!input) | ||
| 60 | return -ENOMEM; | ||
| 61 | |||
| 62 | platform_set_drvdata(pdev, input); | ||
| 63 | |||
| 64 | input->evbit[0] = BIT(EV_KEY); | ||
| 65 | |||
| 66 | input->name = pdev->name; | ||
| 67 | input->phys = "gpio-keys/input0"; | ||
| 68 | input->cdev.dev = &pdev->dev; | ||
| 69 | input->private = pdata; | ||
| 70 | |||
| 71 | input->id.bustype = BUS_HOST; | ||
| 72 | input->id.vendor = 0x0001; | ||
| 73 | input->id.product = 0x0001; | ||
| 74 | input->id.version = 0x0100; | ||
| 75 | |||
| 76 | for (i = 0; i < pdata->nbuttons; i++) { | ||
| 77 | int code = pdata->buttons[i].keycode; | ||
| 78 | int irq = IRQ_GPIO(pdata->buttons[i].gpio); | ||
| 79 | |||
| 80 | set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); | ||
| 81 | error = request_irq(irq, gpio_keys_isr, SA_SAMPLE_RANDOM, | ||
| 82 | pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys", | ||
| 83 | pdev); | ||
| 84 | if (error) { | ||
| 85 | printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, ret); | ||
| 86 | goto fail; | ||
| 87 | } | ||
| 88 | set_bit(code, input->keybit); | ||
| 89 | } | ||
| 90 | |||
| 91 | error = input_register_device(input); | ||
| 92 | if (error) { | ||
| 93 | printk(KERN_ERR "Unable to register gpio-keys input device\n"); | ||
| 94 | goto fail; | ||
| 95 | } | ||
| 96 | |||
| 97 | return 0; | ||
| 98 | |||
| 99 | fail: | ||
| 100 | for (i = i - 1; i >= 0; i--) | ||
| 101 | free_irq(IRQ_GPIO(pdata->buttons[i].gpio), pdev); | ||
| 102 | |||
| 103 | input_free_device(input); | ||
| 104 | |||
| 105 | return error; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int __devexit gpio_keys_remove(struct platform_device *pdev) | ||
| 109 | { | ||
| 110 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
| 111 | struct input_dev *input = platform_get_drvdata(pdev); | ||
| 112 | int i; | ||
| 113 | |||
| 114 | for (i = 0; i < pdata->nbuttons; i++) { | ||
| 115 | int irq = IRQ_GPIO(pdata->buttons[i].gpio); | ||
| 116 | free_irq(irq, pdev); | ||
| 117 | } | ||
| 118 | |||
| 119 | input_unregister_device(input); | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | struct platform_driver gpio_keys_device_driver = { | ||
| 125 | .probe = gpio_keys_probe, | ||
| 126 | .remove = __devexit_p(gpio_keys_remove), | ||
| 127 | .driver = { | ||
| 128 | .name = "gpio-keys", | ||
| 129 | } | ||
| 130 | }; | ||
| 131 | |||
| 132 | static int __init gpio_keys_init(void) | ||
| 133 | { | ||
| 134 | return platform_driver_register(&gpio_keys_device_driver); | ||
| 135 | } | ||
| 136 | |||
| 137 | static void __exit gpio_keys_exit(void) | ||
| 138 | { | ||
| 139 | platform_driver_unregister(&gpio_keys_device_driver); | ||
| 140 | } | ||
| 141 | |||
| 142 | module_init(gpio_keys_init); | ||
| 143 | module_exit(gpio_keys_exit); | ||
| 144 | |||
| 145 | MODULE_LICENSE("GPL"); | ||
| 146 | MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>"); | ||
| 147 | MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs"); | ||
diff --git a/include/asm-arm/hardware/gpio_keys.h b/include/asm-arm/hardware/gpio_keys.h new file mode 100644 index 000000000000..2b217c7b9312 --- /dev/null +++ b/include/asm-arm/hardware/gpio_keys.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #ifndef _GPIO_KEYS_H | ||
| 2 | #define _GPIO_KEYS_H | ||
| 3 | |||
| 4 | struct gpio_keys_button { | ||
| 5 | /* Configuration parameters */ | ||
| 6 | int keycode; | ||
| 7 | int gpio; | ||
| 8 | int active_low; | ||
| 9 | char *desc; | ||
| 10 | }; | ||
| 11 | |||
| 12 | struct gpio_keys_platform_data { | ||
| 13 | struct gpio_keys_button *buttons; | ||
| 14 | int nbuttons; | ||
| 15 | }; | ||
| 16 | |||
| 17 | #endif | ||
