diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 14:50:24 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-11 14:50:24 -0500 |
| commit | d68798374bcf5cd4a19105b86d96121651b3c8cb (patch) | |
| tree | 5e7432adf2b61f1497a4c3138c969e8664c54b6e | |
| parent | 412ecd7751a2653ab17df39a1dc3565a548633fd (diff) | |
| parent | 2a598df595d33be0f12e37ef5df75eff13511d07 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: remove scan_keyb driver
Input: i8042 - fix AUX IRQ delivery check
Input: wistron - add support for Fujitsu-Siemens Amilo D88x0
Input: inport - use correct config option for ATIXL
Input: HIL - handle erros from input_register_device()
Input: tsdev - schedule removal
Input: add Atlas button driver
Input: ads7846 - be more compatible with the hwmon framework
Input: ads7846 - detect pen up from GPIO state
Input: ads7846 - select correct SPI mode
Input: ads7846 - switch to using hrtimer
Input: ads7846 - optionally leave Vref on during differential measurements
Input: ads7846 - pluggable filtering logic
Input: gpio-keys - keyboard driver for GPIO buttons
Input: hid-ff - add support for Logitech Momo racing wheel
Input: i8042 - really suppress ACK/NAK during panic blink
Input: pc110pad - return proper error
| -rw-r--r-- | Documentation/feature-removal-schedule.txt | 15 | ||||
| -rw-r--r-- | drivers/char/scan_keyb.c | 149 | ||||
| -rw-r--r-- | drivers/char/scan_keyb.h | 15 | ||||
| -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-- | drivers/input/keyboard/hilkbd.c | 114 | ||||
| -rw-r--r-- | drivers/input/misc/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/input/misc/atlas_btns.c | 170 | ||||
| -rw-r--r-- | drivers/input/misc/wistron_btns.c | 20 | ||||
| -rw-r--r-- | drivers/input/mouse/inport.c | 2 | ||||
| -rw-r--r-- | drivers/input/mouse/pc110pad.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/i8042.c | 12 | ||||
| -rw-r--r-- | drivers/input/touchscreen/Kconfig | 9 | ||||
| -rw-r--r-- | drivers/input/touchscreen/ads7846.c | 581 | ||||
| -rw-r--r-- | drivers/input/tsdev.c | 4 | ||||
| -rw-r--r-- | drivers/usb/input/hid-ff.c | 1 | ||||
| -rw-r--r-- | drivers/usb/input/hid-lgff.c | 1 | ||||
| -rw-r--r-- | include/asm-arm/hardware/gpio_keys.h | 17 | ||||
| -rw-r--r-- | include/linux/spi/ads7846.h | 12 |
21 files changed, 889 insertions, 417 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 8247a4b79d09..c585aa8d62b4 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -319,3 +319,18 @@ Why: In kernel tree version of driver is unmaintained. Sk98lin driver | |||
| 319 | replaced by the skge driver. | 319 | replaced by the skge driver. |
| 320 | Who: Stephen Hemminger <shemminger@osdl.org> | 320 | Who: Stephen Hemminger <shemminger@osdl.org> |
| 321 | 321 | ||
| 322 | --------------------------- | ||
| 323 | |||
| 324 | What: Compaq touchscreen device emulation | ||
| 325 | When: Oct 2007 | ||
| 326 | Files: drivers/input/tsdev.c | ||
| 327 | Why: The code says it was obsolete when it was written in 2001. | ||
| 328 | tslib is a userspace library which does anything tsdev can do and | ||
| 329 | much more besides in userspace where this code belongs. There is no | ||
| 330 | longer any need for tsdev and applications should have converted to | ||
| 331 | use tslib by now. | ||
| 332 | The name "tsdev" is also extremely confusing and lots of people have | ||
| 333 | it loaded when they don't need/use it. | ||
| 334 | Who: Richard Purdie <rpurdie@rpsys.net> | ||
| 335 | |||
| 336 | --------------------------- | ||
diff --git a/drivers/char/scan_keyb.c b/drivers/char/scan_keyb.c deleted file mode 100644 index 2b5bb4f5754d..000000000000 --- a/drivers/char/scan_keyb.c +++ /dev/null | |||
| @@ -1,149 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * $Id: scan_keyb.c,v 1.2 2000/07/04 06:24:42 yaegashi Exp $ | ||
| 3 | * Copyright (C) 2000 YAEGASHI Takeshi | ||
| 4 | * Generic scan keyboard driver | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/spinlock.h> | ||
| 8 | #include <linux/sched.h> | ||
| 9 | #include <linux/interrupt.h> | ||
| 10 | #include <linux/tty.h> | ||
| 11 | #include <linux/mm.h> | ||
| 12 | #include <linux/signal.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/kbd_ll.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/random.h> | ||
| 17 | #include <linux/poll.h> | ||
| 18 | #include <linux/miscdevice.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/kbd_kern.h> | ||
| 21 | #include <linux/timer.h> | ||
| 22 | |||
| 23 | #define SCANHZ (HZ/20) | ||
| 24 | |||
| 25 | struct scan_keyboard { | ||
| 26 | struct scan_keyboard *next; | ||
| 27 | int (*scan)(unsigned char *buffer); | ||
| 28 | const unsigned char *table; | ||
| 29 | unsigned char *s0, *s1; | ||
| 30 | int length; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static int scan_jiffies=0; | ||
| 34 | static struct scan_keyboard *keyboards=NULL; | ||
| 35 | struct timer_list scan_timer; | ||
| 36 | |||
| 37 | static void check_kbd(const unsigned char *table, | ||
| 38 | unsigned char *new, unsigned char *old, int length) | ||
| 39 | { | ||
| 40 | int need_tasklet_schedule=0; | ||
| 41 | unsigned int xor, bit; | ||
| 42 | |||
| 43 | while(length-->0) { | ||
| 44 | if((xor=*new^*old)==0) { | ||
| 45 | table+=8; | ||
| 46 | } | ||
| 47 | else { | ||
| 48 | for(bit=0x01; bit<0x100; bit<<=1) { | ||
| 49 | if(xor&bit) { | ||
| 50 | handle_scancode(*table, !(*new&bit)); | ||
| 51 | need_tasklet_schedule=1; | ||
| 52 | #if 0 | ||
| 53 | printk("0x%x %s\n", *table, (*new&bit)?"released":"pressed"); | ||
| 54 | #endif | ||
| 55 | } | ||
| 56 | table++; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | new++; old++; | ||
| 60 | } | ||
| 61 | |||
| 62 | if(need_tasklet_schedule) | ||
| 63 | tasklet_schedule(&keyboard_tasklet); | ||
| 64 | } | ||
| 65 | |||
| 66 | |||
| 67 | static void scan_kbd(unsigned long dummy) | ||
| 68 | { | ||
| 69 | struct scan_keyboard *kbd; | ||
| 70 | |||
| 71 | scan_jiffies++; | ||
| 72 | |||
| 73 | for(kbd=keyboards; kbd!=NULL; kbd=kbd->next) { | ||
| 74 | if(scan_jiffies&1) { | ||
| 75 | if(!kbd->scan(kbd->s0)) | ||
| 76 | check_kbd(kbd->table, | ||
| 77 | kbd->s0, kbd->s1, kbd->length); | ||
| 78 | else | ||
| 79 | memcpy(kbd->s0, kbd->s1, kbd->length); | ||
| 80 | } | ||
| 81 | else { | ||
| 82 | if(!kbd->scan(kbd->s1)) | ||
| 83 | check_kbd(kbd->table, | ||
| 84 | kbd->s1, kbd->s0, kbd->length); | ||
| 85 | else | ||
| 86 | memcpy(kbd->s1, kbd->s0, kbd->length); | ||
| 87 | } | ||
| 88 | |||
| 89 | } | ||
| 90 | |||
| 91 | init_timer(&scan_timer); | ||
| 92 | scan_timer.expires = jiffies + SCANHZ; | ||
| 93 | scan_timer.data = 0; | ||
| 94 | scan_timer.function = scan_kbd; | ||
| 95 | add_timer(&scan_timer); | ||
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | int register_scan_keyboard(int (*scan)(unsigned char *buffer), | ||
| 100 | const unsigned char *table, | ||
| 101 | int length) | ||
| 102 | { | ||
| 103 | struct scan_keyboard *kbd; | ||
| 104 | |||
| 105 | kbd = kmalloc(sizeof(struct scan_keyboard), GFP_KERNEL); | ||
| 106 | if (kbd == NULL) | ||
| 107 | goto error_out; | ||
| 108 | |||
| 109 | kbd->scan=scan; | ||
| 110 | kbd->table=table; | ||
| 111 | kbd->length=length; | ||
| 112 | |||
| 113 | kbd->s0 = kmalloc(length, GFP_KERNEL); | ||
| 114 | if (kbd->s0 == NULL) | ||
| 115 | goto error_free_kbd; | ||
| 116 | |||
| 117 | kbd->s1 = kmalloc(length, GFP_KERNEL); | ||
| 118 | if (kbd->s1 == NULL) | ||
| 119 | goto error_free_s0; | ||
| 120 | |||
| 121 | memset(kbd->s0, -1, kbd->length); | ||
| 122 | memset(kbd->s1, -1, kbd->length); | ||
| 123 | |||
| 124 | kbd->next=keyboards; | ||
| 125 | keyboards=kbd; | ||
| 126 | |||
| 127 | return 0; | ||
| 128 | |||
| 129 | error_free_s0: | ||
| 130 | kfree(kbd->s0); | ||
| 131 | |||
| 132 | error_free_kbd: | ||
| 133 | kfree(kbd); | ||
| 134 | |||
| 135 | error_out: | ||
| 136 | return -ENOMEM; | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
| 140 | void __init scan_kbd_init(void) | ||
| 141 | { | ||
| 142 | init_timer(&scan_timer); | ||
| 143 | scan_timer.expires = jiffies + SCANHZ; | ||
| 144 | scan_timer.data = 0; | ||
| 145 | scan_timer.function = scan_kbd; | ||
| 146 | add_timer(&scan_timer); | ||
| 147 | |||
| 148 | printk(KERN_INFO "Generic scan keyboard driver initialized\n"); | ||
| 149 | } | ||
diff --git a/drivers/char/scan_keyb.h b/drivers/char/scan_keyb.h deleted file mode 100644 index b4b611290a00..000000000000 --- a/drivers/char/scan_keyb.h +++ /dev/null | |||
| @@ -1,15 +0,0 @@ | |||
| 1 | #ifndef __DRIVER_CHAR_SCAN_KEYB_H | ||
| 2 | #define __DRIVER_CHAR_SCAN_KEYB_H | ||
| 3 | /* | ||
| 4 | * $Id: scan_keyb.h,v 1.1 2000/06/10 21:45:30 yaegashi Exp $ | ||
| 5 | * Copyright (C) 2000 YAEGASHI Takeshi | ||
| 6 | * Generic scan keyboard driver | ||
| 7 | */ | ||
| 8 | |||
| 9 | int register_scan_keyboard(int (*scan)(unsigned char *buffer), | ||
| 10 | const unsigned char *table, | ||
| 11 | int length); | ||
| 12 | |||
| 13 | void __init scan_kbd_init(void); | ||
| 14 | |||
| 15 | #endif | ||
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/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 35461eab2faf..255a6ec75a48 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
| @@ -6,10 +6,10 @@ | |||
| 6 | * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> | 6 | * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> |
| 7 | * | 7 | * |
| 8 | * Very basic HP Human Interface Loop (HIL) driver. | 8 | * Very basic HP Human Interface Loop (HIL) driver. |
| 9 | * This driver handles the keyboard on HP300 (m68k) and on some | 9 | * This driver handles the keyboard on HP300 (m68k) and on some |
| 10 | * HP700 (parisc) series machines. | 10 | * HP700 (parisc) series machines. |
| 11 | * | 11 | * |
| 12 | * | 12 | * |
| 13 | * This file is subject to the terms and conditions of the GNU General Public | 13 | * This file is subject to the terms and conditions of the GNU General Public |
| 14 | * License version 2. See the file COPYING in the main directory of this | 14 | * License version 2. See the file COPYING in the main directory of this |
| 15 | * archive for more details. | 15 | * archive for more details. |
| @@ -64,9 +64,9 @@ MODULE_LICENSE("GPL v2"); | |||
| 64 | #endif | 64 | #endif |
| 65 | 65 | ||
| 66 | 66 | ||
| 67 | 67 | ||
| 68 | /* HIL helper functions */ | 68 | /* HIL helper functions */ |
| 69 | 69 | ||
| 70 | #define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY) | 70 | #define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY) |
| 71 | #define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY) | 71 | #define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY) |
| 72 | #define hil_status() (hil_readb(HILBASE + HIL_CMD)) | 72 | #define hil_status() (hil_readb(HILBASE + HIL_CMD)) |
| @@ -75,7 +75,7 @@ MODULE_LICENSE("GPL v2"); | |||
| 75 | #define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0) | 75 | #define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0) |
| 76 | 76 | ||
| 77 | /* HIL constants */ | 77 | /* HIL constants */ |
| 78 | 78 | ||
| 79 | #define HIL_BUSY 0x02 | 79 | #define HIL_BUSY 0x02 |
| 80 | #define HIL_DATA_RDY 0x01 | 80 | #define HIL_DATA_RDY 0x01 |
| 81 | 81 | ||
| @@ -86,10 +86,10 @@ MODULE_LICENSE("GPL v2"); | |||
| 86 | #define HIL_INTON 0x5C /* Turn on interrupts. */ | 86 | #define HIL_INTON 0x5C /* Turn on interrupts. */ |
| 87 | #define HIL_INTOFF 0x5D /* Turn off interrupts. */ | 87 | #define HIL_INTOFF 0x5D /* Turn off interrupts. */ |
| 88 | 88 | ||
| 89 | #define HIL_READKBDSADR 0xF9 | 89 | #define HIL_READKBDSADR 0xF9 |
| 90 | #define HIL_WRITEKBDSADR 0xE9 | 90 | #define HIL_WRITEKBDSADR 0xE9 |
| 91 | 91 | ||
| 92 | static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = | 92 | static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = |
| 93 | { HIL_KEYCODES_SET1 }; | 93 | { HIL_KEYCODES_SET1 }; |
| 94 | 94 | ||
| 95 | /* HIL structure */ | 95 | /* HIL structure */ |
| @@ -97,11 +97,11 @@ static struct { | |||
| 97 | struct input_dev *dev; | 97 | struct input_dev *dev; |
| 98 | 98 | ||
| 99 | unsigned int curdev; | 99 | unsigned int curdev; |
| 100 | 100 | ||
| 101 | unsigned char s; | 101 | unsigned char s; |
| 102 | unsigned char c; | 102 | unsigned char c; |
| 103 | int valid; | 103 | int valid; |
| 104 | 104 | ||
| 105 | unsigned char data[16]; | 105 | unsigned char data[16]; |
| 106 | unsigned int ptr; | 106 | unsigned int ptr; |
| 107 | spinlock_t lock; | 107 | spinlock_t lock; |
| @@ -115,7 +115,7 @@ static void poll_finished(void) | |||
| 115 | int down; | 115 | int down; |
| 116 | int key; | 116 | int key; |
| 117 | unsigned char scode; | 117 | unsigned char scode; |
| 118 | 118 | ||
| 119 | switch (hil_dev.data[0]) { | 119 | switch (hil_dev.data[0]) { |
| 120 | case 0x40: | 120 | case 0x40: |
| 121 | down = (hil_dev.data[1] & 1) == 0; | 121 | down = (hil_dev.data[1] & 1) == 0; |
| @@ -127,6 +127,7 @@ static void poll_finished(void) | |||
| 127 | hil_dev.curdev = 0; | 127 | hil_dev.curdev = 0; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | |||
| 130 | static inline void handle_status(unsigned char s, unsigned char c) | 131 | static inline void handle_status(unsigned char s, unsigned char c) |
| 131 | { | 132 | { |
| 132 | if (c & 0x8) { | 133 | if (c & 0x8) { |
| @@ -143,6 +144,7 @@ static inline void handle_status(unsigned char s, unsigned char c) | |||
| 143 | } | 144 | } |
| 144 | } | 145 | } |
| 145 | 146 | ||
| 147 | |||
| 146 | static inline void handle_data(unsigned char s, unsigned char c) | 148 | static inline void handle_data(unsigned char s, unsigned char c) |
| 147 | { | 149 | { |
| 148 | if (hil_dev.curdev) { | 150 | if (hil_dev.curdev) { |
| @@ -152,13 +154,11 @@ static inline void handle_data(unsigned char s, unsigned char c) | |||
| 152 | } | 154 | } |
| 153 | 155 | ||
| 154 | 156 | ||
| 155 | /* | 157 | /* handle HIL interrupts */ |
| 156 | * Handle HIL interrupts. | ||
| 157 | */ | ||
| 158 | static irqreturn_t hil_interrupt(int irq, void *handle) | 158 | static irqreturn_t hil_interrupt(int irq, void *handle) |
| 159 | { | 159 | { |
| 160 | unsigned char s, c; | 160 | unsigned char s, c; |
| 161 | 161 | ||
| 162 | s = hil_status(); | 162 | s = hil_status(); |
| 163 | c = hil_read_data(); | 163 | c = hil_read_data(); |
| 164 | 164 | ||
| @@ -179,10 +179,8 @@ static irqreturn_t hil_interrupt(int irq, void *handle) | |||
| 179 | return IRQ_HANDLED; | 179 | return IRQ_HANDLED; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | /* | ||
| 183 | * Send a command to the HIL | ||
| 184 | */ | ||
| 185 | 182 | ||
| 183 | /* send a command to the HIL */ | ||
| 186 | static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | 184 | static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) |
| 187 | { | 185 | { |
| 188 | unsigned long flags; | 186 | unsigned long flags; |
| @@ -200,16 +198,14 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | |||
| 200 | } | 198 | } |
| 201 | 199 | ||
| 202 | 200 | ||
| 203 | /* | 201 | /* initialise HIL */ |
| 204 | * Initialise HIL. | ||
| 205 | */ | ||
| 206 | |||
| 207 | static int __init | 202 | static int __init |
| 208 | hil_keyb_init(void) | 203 | hil_keyb_init(void) |
| 209 | { | 204 | { |
| 210 | unsigned char c; | 205 | unsigned char c; |
| 211 | unsigned int i, kbid; | 206 | unsigned int i, kbid; |
| 212 | wait_queue_head_t hil_wait; | 207 | wait_queue_head_t hil_wait; |
| 208 | int err; | ||
| 213 | 209 | ||
| 214 | if (hil_dev.dev) { | 210 | if (hil_dev.dev) { |
| 215 | return -ENODEV; /* already initialized */ | 211 | return -ENODEV; /* already initialized */ |
| @@ -219,15 +215,25 @@ hil_keyb_init(void) | |||
| 219 | if (!hil_dev.dev) | 215 | if (!hil_dev.dev) |
| 220 | return -ENOMEM; | 216 | return -ENOMEM; |
| 221 | hil_dev.dev->private = &hil_dev; | 217 | hil_dev.dev->private = &hil_dev; |
| 222 | 218 | ||
| 223 | #if defined(CONFIG_HP300) | 219 | #if defined(CONFIG_HP300) |
| 224 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) | 220 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { |
| 225 | return -ENODEV; | 221 | printk(KERN_ERR "HIL: hardware register was not found\n"); |
| 226 | 222 | err = -ENODEV; | |
| 227 | request_region(HILBASE+HIL_DATA, 2, "hil"); | 223 | goto err1; |
| 224 | } | ||
| 225 | if (!request_region(HILBASE + HIL_DATA, 2, "hil")) { | ||
| 226 | printk(KERN_ERR "HIL: IOPORT region already used\n"); | ||
| 227 | err = -EIO; | ||
| 228 | goto err1; | ||
| 229 | } | ||
| 228 | #endif | 230 | #endif |
| 229 | 231 | ||
| 230 | request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); | 232 | err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); |
| 233 | if (err) { | ||
| 234 | printk(KERN_ERR "HIL: Can't get IRQ\n"); | ||
| 235 | goto err2; | ||
| 236 | } | ||
| 231 | 237 | ||
| 232 | /* Turn on interrupts */ | 238 | /* Turn on interrupts */ |
| 233 | hil_do(HIL_INTON, NULL, 0); | 239 | hil_do(HIL_INTON, NULL, 0); |
| @@ -239,47 +245,63 @@ hil_keyb_init(void) | |||
| 239 | init_waitqueue_head(&hil_wait); | 245 | init_waitqueue_head(&hil_wait); |
| 240 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); | 246 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); |
| 241 | if (!hil_dev.valid) { | 247 | if (!hil_dev.valid) { |
| 242 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present.\n"); | 248 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n"); |
| 243 | } | 249 | } |
| 244 | 250 | ||
| 245 | c = hil_dev.c; | 251 | c = hil_dev.c; |
| 246 | hil_dev.valid = 0; | 252 | hil_dev.valid = 0; |
| 247 | if (c == 0) { | 253 | if (c == 0) { |
| 248 | kbid = -1; | 254 | kbid = -1; |
| 249 | printk(KERN_WARNING "HIL: no keyboard present.\n"); | 255 | printk(KERN_WARNING "HIL: no keyboard present\n"); |
| 250 | } else { | 256 | } else { |
| 251 | kbid = ffz(~c); | 257 | kbid = ffz(~c); |
| 252 | /* printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); */ | 258 | printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); |
| 253 | } | 259 | } |
| 254 | 260 | ||
| 255 | /* set it to raw mode */ | 261 | /* set it to raw mode */ |
| 256 | c = 0; | 262 | c = 0; |
| 257 | hil_do(HIL_WRITEKBDSADR, &c, 1); | 263 | hil_do(HIL_WRITEKBDSADR, &c, 1); |
| 258 | 264 | ||
| 259 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) | 265 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) |
| 260 | if (hphilkeyb_keycode[i] != KEY_RESERVED) | 266 | if (hphilkeyb_keycode[i] != KEY_RESERVED) |
| 261 | set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); | 267 | set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); |
| 262 | 268 | ||
| 263 | hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 269 | hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
| 264 | hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); | 270 | hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); |
| 265 | hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | 271 | hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; |
| 266 | hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]); | 272 | hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]); |
| 267 | hil_dev.dev->keycode = hphilkeyb_keycode; | 273 | hil_dev.dev->keycode = hphilkeyb_keycode; |
| 268 | hil_dev.dev->name = "HIL keyboard"; | 274 | hil_dev.dev->name = "HIL keyboard"; |
| 269 | hil_dev.dev->phys = "hpkbd/input0"; | 275 | hil_dev.dev->phys = "hpkbd/input0"; |
| 270 | 276 | ||
| 271 | hil_dev.dev->id.bustype = BUS_HIL; | 277 | hil_dev.dev->id.bustype = BUS_HIL; |
| 272 | hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; | 278 | hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; |
| 273 | hil_dev.dev->id.product = 0x0001; | 279 | hil_dev.dev->id.product = 0x0001; |
| 274 | hil_dev.dev->id.version = 0x0010; | 280 | hil_dev.dev->id.version = 0x0010; |
| 275 | 281 | ||
| 276 | input_register_device(hil_dev.dev); | 282 | err = input_register_device(hil_dev.dev); |
| 283 | if (err) { | ||
| 284 | printk(KERN_ERR "HIL: Can't register device\n"); | ||
| 285 | goto err3; | ||
| 286 | } | ||
| 277 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", | 287 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", |
| 278 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); | 288 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); |
| 279 | 289 | ||
| 280 | return 0; | 290 | return 0; |
| 291 | |||
| 292 | err3: | ||
| 293 | hil_do(HIL_INTOFF, NULL, 0); | ||
| 294 | disable_irq(HIL_IRQ); | ||
| 295 | free_irq(HIL_IRQ, hil_dev.dev_id); | ||
| 296 | err2: | ||
| 297 | release_region(HILBASE + HIL_DATA, 2); | ||
| 298 | err1: | ||
| 299 | input_free_device(hil_dev.dev); | ||
| 300 | hil_dev.dev = NULL; | ||
| 301 | return err; | ||
| 281 | } | 302 | } |
| 282 | 303 | ||
| 304 | |||
| 283 | #if defined(CONFIG_PARISC) | 305 | #if defined(CONFIG_PARISC) |
| 284 | static int __init | 306 | static int __init |
| 285 | hil_init_chip(struct parisc_device *dev) | 307 | hil_init_chip(struct parisc_device *dev) |
| @@ -292,7 +314,7 @@ hil_init_chip(struct parisc_device *dev) | |||
| 292 | hil_base = dev->hpa.start; | 314 | hil_base = dev->hpa.start; |
| 293 | hil_irq = dev->irq; | 315 | hil_irq = dev->irq; |
| 294 | hil_dev.dev_id = dev; | 316 | hil_dev.dev_id = dev; |
| 295 | 317 | ||
| 296 | printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq); | 318 | printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq); |
| 297 | 319 | ||
| 298 | return hil_keyb_init(); | 320 | return hil_keyb_init(); |
| @@ -313,9 +335,6 @@ static struct parisc_driver hil_driver = { | |||
| 313 | #endif /* CONFIG_PARISC */ | 335 | #endif /* CONFIG_PARISC */ |
| 314 | 336 | ||
| 315 | 337 | ||
| 316 | |||
| 317 | |||
| 318 | |||
| 319 | static int __init hil_init(void) | 338 | static int __init hil_init(void) |
| 320 | { | 339 | { |
| 321 | #if defined(CONFIG_PARISC) | 340 | #if defined(CONFIG_PARISC) |
| @@ -349,4 +368,3 @@ static void __exit hil_exit(void) | |||
| 349 | 368 | ||
| 350 | module_init(hil_init); | 369 | module_init(hil_init); |
| 351 | module_exit(hil_exit); | 370 | module_exit(hil_exit); |
| 352 | |||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index ba0e88c64e1e..41b42587f5e9 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
| @@ -50,6 +50,16 @@ config INPUT_WISTRON_BTNS | |||
| 50 | To compile this driver as a module, choose M here: the module will | 50 | To compile this driver as a module, choose M here: the module will |
| 51 | be called wistron_btns. | 51 | be called wistron_btns. |
| 52 | 52 | ||
| 53 | config INPUT_ATLAS_BTNS | ||
| 54 | tristate "x86 Atlas button interface" | ||
| 55 | depends on X86 && ACPI | ||
| 56 | help | ||
| 57 | Say Y here for support of Atlas wallmount touchscreen buttons. | ||
| 58 | The events will show up as scancodes F1 through F9 via evdev. | ||
| 59 | |||
| 60 | To compile this driver as a module, choose M here: the module will | ||
| 61 | be called atlas_btns. | ||
| 62 | |||
| 53 | config INPUT_IXP4XX_BEEPER | 63 | config INPUT_IXP4XX_BEEPER |
| 54 | tristate "IXP4XX Beeper support" | 64 | tristate "IXP4XX Beeper support" |
| 55 | depends on ARCH_IXP4XX | 65 | depends on ARCH_IXP4XX |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 415c49178985..e0a8d58c9e9b 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
| @@ -9,5 +9,6 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o | |||
| 9 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 9 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
| 10 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 10 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
| 11 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 11 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
| 12 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | ||
| 12 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 13 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
| 13 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | 14 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c new file mode 100644 index 000000000000..0acc3a123604 --- /dev/null +++ b/drivers/input/misc/atlas_btns.c | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* | ||
| 2 | * atlas_btns.c - Atlas Wallmount Touchscreen ACPI Extras | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Jaya Kumar | ||
| 5 | * Based on Toshiba ACPI by John Belmonte and ASUS ACPI | ||
| 6 | * This work was sponsored by CIS(M) Sdn Bhd. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/input.h> | ||
| 28 | #include <linux/types.h> | ||
| 29 | #include <asm/uaccess.h> | ||
| 30 | #include <acpi/acpi_drivers.h> | ||
| 31 | |||
| 32 | #define ACPI_ATLAS_NAME "Atlas ACPI" | ||
| 33 | #define ACPI_ATLAS_CLASS "Atlas" | ||
| 34 | #define ACPI_ATLAS_BUTTON_HID "ASIM0000" | ||
| 35 | |||
| 36 | static struct input_dev *input_dev; | ||
| 37 | |||
| 38 | /* button handling code */ | ||
| 39 | static acpi_status acpi_atlas_button_setup(acpi_handle region_handle, | ||
| 40 | u32 function, void *handler_context, void **return_context) | ||
| 41 | { | ||
| 42 | *return_context = | ||
| 43 | (function != ACPI_REGION_DEACTIVATE) ? handler_context : NULL; | ||
| 44 | |||
| 45 | return AE_OK; | ||
| 46 | } | ||
| 47 | |||
| 48 | static acpi_status acpi_atlas_button_handler(u32 function, | ||
| 49 | acpi_physical_address address, | ||
| 50 | u32 bit_width, acpi_integer *value, | ||
| 51 | void *handler_context, void *region_context) | ||
| 52 | { | ||
| 53 | acpi_status status; | ||
| 54 | int keycode; | ||
| 55 | |||
| 56 | if (function == ACPI_WRITE) { | ||
| 57 | keycode = KEY_F1 + (address & 0x0F); | ||
| 58 | input_report_key(input_dev, keycode, !(address & 0x10)); | ||
| 59 | input_sync(input_dev); | ||
| 60 | status = 0; | ||
| 61 | } else { | ||
| 62 | printk(KERN_WARNING "atlas: shrugged on unexpected function" | ||
| 63 | ":function=%x,address=%lx,value=%x\n", | ||
| 64 | function, (unsigned long)address, (u32)*value); | ||
| 65 | status = -EINVAL; | ||
| 66 | } | ||
| 67 | |||
| 68 | return status; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int atlas_acpi_button_add(struct acpi_device *device) | ||
| 72 | { | ||
| 73 | acpi_status status; | ||
| 74 | int err; | ||
| 75 | |||
| 76 | input_dev = input_allocate_device(); | ||
| 77 | if (!input_dev) { | ||
| 78 | printk(KERN_ERR "atlas: unable to allocate input device\n"); | ||
| 79 | return -ENOMEM; | ||
| 80 | } | ||
| 81 | |||
| 82 | input_dev->name = "Atlas ACPI button driver"; | ||
| 83 | input_dev->phys = "ASIM0000/atlas/input0"; | ||
| 84 | input_dev->id.bustype = BUS_HOST; | ||
| 85 | input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); | ||
| 86 | |||
| 87 | set_bit(KEY_F1, input_dev->keybit); | ||
| 88 | set_bit(KEY_F2, input_dev->keybit); | ||
| 89 | set_bit(KEY_F3, input_dev->keybit); | ||
| 90 | set_bit(KEY_F4, input_dev->keybit); | ||
| 91 | set_bit(KEY_F5, input_dev->keybit); | ||
| 92 | set_bit(KEY_F6, input_dev->keybit); | ||
| 93 | set_bit(KEY_F7, input_dev->keybit); | ||
| 94 | set_bit(KEY_F8, input_dev->keybit); | ||
| 95 | set_bit(KEY_F9, input_dev->keybit); | ||
| 96 | |||
| 97 | err = input_register_device(input_dev); | ||
| 98 | if (err) { | ||
| 99 | printk(KERN_ERR "atlas: couldn't register input device\n"); | ||
| 100 | input_free_device(input_dev); | ||
| 101 | return err; | ||
| 102 | } | ||
| 103 | |||
| 104 | /* hookup button handler */ | ||
| 105 | status = acpi_install_address_space_handler(device->handle, | ||
| 106 | 0x81, &acpi_atlas_button_handler, | ||
| 107 | &acpi_atlas_button_setup, device); | ||
| 108 | if (ACPI_FAILURE(status)) { | ||
| 109 | printk(KERN_ERR "Atlas: Error installing addr spc handler\n"); | ||
| 110 | input_unregister_device(input_dev); | ||
| 111 | status = -EINVAL; | ||
| 112 | } | ||
| 113 | |||
| 114 | return status; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int atlas_acpi_button_remove(struct acpi_device *device, int type) | ||
| 118 | { | ||
| 119 | acpi_status status; | ||
| 120 | |||
| 121 | status = acpi_remove_address_space_handler(device->handle, | ||
| 122 | 0x81, &acpi_atlas_button_handler); | ||
| 123 | if (ACPI_FAILURE(status)) { | ||
| 124 | printk(KERN_ERR "Atlas: Error removing addr spc handler\n"); | ||
| 125 | status = -EINVAL; | ||
| 126 | } | ||
| 127 | |||
| 128 | input_unregister_device(input_dev); | ||
| 129 | |||
| 130 | return status; | ||
| 131 | } | ||
| 132 | |||
| 133 | static struct acpi_driver atlas_acpi_driver = { | ||
| 134 | .name = ACPI_ATLAS_NAME, | ||
| 135 | .class = ACPI_ATLAS_CLASS, | ||
| 136 | .ids = ACPI_ATLAS_BUTTON_HID, | ||
| 137 | .ops = { | ||
| 138 | .add = atlas_acpi_button_add, | ||
| 139 | .remove = atlas_acpi_button_remove, | ||
| 140 | }, | ||
| 141 | }; | ||
| 142 | |||
| 143 | static int __init atlas_acpi_init(void) | ||
| 144 | { | ||
| 145 | int result; | ||
| 146 | |||
| 147 | if (acpi_disabled) | ||
| 148 | return -ENODEV; | ||
| 149 | |||
| 150 | result = acpi_bus_register_driver(&atlas_acpi_driver); | ||
| 151 | if (result < 0) { | ||
| 152 | printk(KERN_ERR "Atlas ACPI: Unable to register driver\n"); | ||
| 153 | return -ENODEV; | ||
| 154 | } | ||
| 155 | |||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | static void __exit atlas_acpi_exit(void) | ||
| 160 | { | ||
| 161 | acpi_bus_unregister_driver(&atlas_acpi_driver); | ||
| 162 | } | ||
| 163 | |||
| 164 | module_init(atlas_acpi_init); | ||
| 165 | module_exit(atlas_acpi_exit); | ||
| 166 | |||
| 167 | MODULE_AUTHOR("Jaya Kumar"); | ||
| 168 | MODULE_LICENSE("GPL"); | ||
| 169 | MODULE_DESCRIPTION("Atlas button driver"); | ||
| 170 | |||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 7b9d1c1da41a..e1183aeb8ed5 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
| @@ -335,6 +335,17 @@ static struct key_entry keymap_aopen_1559as[] = { | |||
| 335 | { KE_END, 0 }, | 335 | { KE_END, 0 }, |
| 336 | }; | 336 | }; |
| 337 | 337 | ||
| 338 | static struct key_entry keymap_fs_amilo_d88x0[] = { | ||
| 339 | { KE_KEY, 0x01, KEY_HELP }, | ||
| 340 | { KE_KEY, 0x08, KEY_MUTE }, | ||
| 341 | { KE_KEY, 0x31, KEY_MAIL }, | ||
| 342 | { KE_KEY, 0x36, KEY_WWW }, | ||
| 343 | { KE_KEY, 0x11, KEY_PROG1 }, | ||
| 344 | { KE_KEY, 0x12, KEY_PROG2 }, | ||
| 345 | { KE_KEY, 0x13, KEY_PROG3 }, | ||
| 346 | { KE_END, 0 } | ||
| 347 | }; | ||
| 348 | |||
| 338 | /* | 349 | /* |
| 339 | * If your machine is not here (which is currently rather likely), please send | 350 | * If your machine is not here (which is currently rather likely), please send |
| 340 | * a list of buttons and their key codes (reported when loading this module | 351 | * a list of buttons and their key codes (reported when loading this module |
| @@ -413,6 +424,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
| 413 | }, | 424 | }, |
| 414 | .driver_data = keymap_wistron_ms2111 | 425 | .driver_data = keymap_wistron_ms2111 |
| 415 | }, | 426 | }, |
| 427 | { | ||
| 428 | .callback = dmi_matched, | ||
| 429 | .ident = "Fujitsu Siemens Amilo D88x0", | ||
| 430 | .matches = { | ||
| 431 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
| 432 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"), | ||
| 433 | }, | ||
| 434 | .driver_data = keymap_fs_amilo_d88x0 | ||
| 435 | }, | ||
| 416 | { NULL, } | 436 | { NULL, } |
| 417 | }; | 437 | }; |
| 418 | 438 | ||
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index 13dd96785e39..701ebd5473cf 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c | |||
| @@ -61,7 +61,7 @@ MODULE_LICENSE("GPL"); | |||
| 61 | #define INPORT_REG_MODE 0x07 | 61 | #define INPORT_REG_MODE 0x07 |
| 62 | #define INPORT_RESET 0x80 | 62 | #define INPORT_RESET 0x80 |
| 63 | 63 | ||
| 64 | #ifdef CONFIG_INPUT_ATIXL | 64 | #ifdef CONFIG_MOUSE_ATIXL |
| 65 | #define INPORT_NAME "ATI XL Mouse" | 65 | #define INPORT_NAME "ATI XL Mouse" |
| 66 | #define INPORT_VENDOR 0x0002 | 66 | #define INPORT_VENDOR 0x0002 |
| 67 | #define INPORT_SPEED_30HZ 0x01 | 67 | #define INPORT_SPEED_30HZ 0x01 |
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index f155c1fea04e..05d992e514f0 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
| @@ -113,7 +113,7 @@ static int __init pc110pad_init(void) | |||
| 113 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); | 113 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); |
| 114 | if (dev) { | 114 | if (dev) { |
| 115 | pci_dev_put(dev); | 115 | pci_dev_put(dev); |
| 116 | return -ENOENT; | 116 | return -ENODEV; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | if (!request_region(pc110pad_io, 4, "pc110pad")) { | 119 | if (!request_region(pc110pad_io, 4, "pc110pad")) { |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index debe9445488c..c3fdfc1f342a 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
| @@ -371,7 +371,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
| 371 | if (unlikely(i8042_suppress_kbd_ack)) | 371 | if (unlikely(i8042_suppress_kbd_ack)) |
| 372 | if (port_no == I8042_KBD_PORT_NO && | 372 | if (port_no == I8042_KBD_PORT_NO && |
| 373 | (data == 0xfa || data == 0xfe)) { | 373 | (data == 0xfa || data == 0xfe)) { |
| 374 | i8042_suppress_kbd_ack = 0; | 374 | i8042_suppress_kbd_ack--; |
| 375 | goto out; | 375 | goto out; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| @@ -543,6 +543,7 @@ static int __devinit i8042_check_aux(void) | |||
| 543 | { | 543 | { |
| 544 | int retval = -1; | 544 | int retval = -1; |
| 545 | int irq_registered = 0; | 545 | int irq_registered = 0; |
| 546 | int aux_loop_broken = 0; | ||
| 546 | unsigned long flags; | 547 | unsigned long flags; |
| 547 | unsigned char param; | 548 | unsigned char param; |
| 548 | 549 | ||
| @@ -572,6 +573,8 @@ static int __devinit i8042_check_aux(void) | |||
| 572 | if (i8042_command(¶m, I8042_CMD_AUX_TEST) || | 573 | if (i8042_command(¶m, I8042_CMD_AUX_TEST) || |
| 573 | (param && param != 0xfa && param != 0xff)) | 574 | (param && param != 0xfa && param != 0xff)) |
| 574 | return -1; | 575 | return -1; |
| 576 | |||
| 577 | aux_loop_broken = 1; | ||
| 575 | } | 578 | } |
| 576 | 579 | ||
| 577 | /* | 580 | /* |
| @@ -595,7 +598,7 @@ static int __devinit i8042_check_aux(void) | |||
| 595 | * used it for a PCI card or somethig else. | 598 | * used it for a PCI card or somethig else. |
| 596 | */ | 599 | */ |
| 597 | 600 | ||
| 598 | if (i8042_noloop) { | 601 | if (i8042_noloop || aux_loop_broken) { |
| 599 | /* | 602 | /* |
| 600 | * Without LOOP command we can't test AUX IRQ delivery. Assume the port | 603 | * Without LOOP command we can't test AUX IRQ delivery. Assume the port |
| 601 | * is working and hope we are right. | 604 | * is working and hope we are right. |
| @@ -838,13 +841,14 @@ static long i8042_panic_blink(long count) | |||
| 838 | led ^= 0x01 | 0x04; | 841 | led ^= 0x01 | 0x04; |
| 839 | while (i8042_read_status() & I8042_STR_IBF) | 842 | while (i8042_read_status() & I8042_STR_IBF) |
| 840 | DELAY; | 843 | DELAY; |
| 841 | i8042_suppress_kbd_ack = 1; | 844 | dbg("%02x -> i8042 (panic blink)", 0xed); |
| 845 | i8042_suppress_kbd_ack = 2; | ||
| 842 | i8042_write_data(0xed); /* set leds */ | 846 | i8042_write_data(0xed); /* set leds */ |
| 843 | DELAY; | 847 | DELAY; |
| 844 | while (i8042_read_status() & I8042_STR_IBF) | 848 | while (i8042_read_status() & I8042_STR_IBF) |
| 845 | DELAY; | 849 | DELAY; |
| 846 | DELAY; | 850 | DELAY; |
| 847 | i8042_suppress_kbd_ack = 1; | 851 | dbg("%02x -> i8042 (panic blink)", led); |
| 848 | i8042_write_data(led); | 852 | i8042_write_data(led); |
| 849 | DELAY; | 853 | DELAY; |
| 850 | last_blink = count; | 854 | last_blink = count; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6b46c9bf1d20..971618059a6f 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -12,13 +12,18 @@ menuconfig INPUT_TOUCHSCREEN | |||
| 12 | if INPUT_TOUCHSCREEN | 12 | if INPUT_TOUCHSCREEN |
| 13 | 13 | ||
| 14 | config TOUCHSCREEN_ADS7846 | 14 | config TOUCHSCREEN_ADS7846 |
| 15 | tristate "ADS 7846 based touchscreens" | 15 | tristate "ADS 7846/7843 based touchscreens" |
| 16 | depends on SPI_MASTER | 16 | depends on SPI_MASTER |
| 17 | depends on HWMON = n || HWMON | ||
| 17 | help | 18 | help |
| 18 | Say Y here if you have a touchscreen interface using the | 19 | Say Y here if you have a touchscreen interface using the |
| 19 | ADS7846 controller, and your board-specific initialization | 20 | ADS7846 or ADS7843 controller, and your board-specific setup |
| 20 | code includes that in its table of SPI devices. | 21 | code includes that in its table of SPI devices. |
| 21 | 22 | ||
| 23 | If HWMON is selected, and the driver is told the reference voltage | ||
| 24 | on your board, you will also get hwmon interfaces for the voltage | ||
| 25 | (and on ads7846, temperature) sensors of this chip. | ||
| 26 | |||
| 22 | If unsure, say N (but it's safe to say "Y"). | 27 | If unsure, say N (but it's safe to say "Y"). |
| 23 | 28 | ||
| 24 | To compile this driver as a module, choose M here: the | 29 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index c6164b6f476a..cd251efda410 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -17,8 +17,9 @@ | |||
| 17 | * it under the terms of the GNU General Public License version 2 as | 17 | * it under the terms of the GNU General Public License version 2 as |
| 18 | * published by the Free Software Foundation. | 18 | * published by the Free Software Foundation. |
| 19 | */ | 19 | */ |
| 20 | #include <linux/device.h> | 20 | #include <linux/hwmon.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/err.h> | ||
| 22 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
| 23 | #include <linux/input.h> | 24 | #include <linux/input.h> |
| 24 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| @@ -54,7 +55,8 @@ | |||
| 54 | * files. | 55 | * files. |
| 55 | */ | 56 | */ |
| 56 | 57 | ||
| 57 | #define TS_POLL_PERIOD msecs_to_jiffies(10) | 58 | #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */ |
| 59 | #define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */ | ||
| 58 | 60 | ||
| 59 | /* this driver doesn't aim at the peak continuous sample rate */ | 61 | /* this driver doesn't aim at the peak continuous sample rate */ |
| 60 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) | 62 | #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */) |
| @@ -63,12 +65,12 @@ struct ts_event { | |||
| 63 | /* For portability, we can't read 12 bit values using SPI (which | 65 | /* For portability, we can't read 12 bit values using SPI (which |
| 64 | * would make the controller deliver them as native byteorder u16 | 66 | * would make the controller deliver them as native byteorder u16 |
| 65 | * with msbs zeroed). Instead, we read them as two 8-bit values, | 67 | * with msbs zeroed). Instead, we read them as two 8-bit values, |
| 66 | * which need byteswapping then range adjustment. | 68 | * *** WHICH NEED BYTESWAPPING *** and range adjustment. |
| 67 | */ | 69 | */ |
| 68 | __be16 x; | 70 | u16 x; |
| 69 | __be16 y; | 71 | u16 y; |
| 70 | __be16 z1, z2; | 72 | u16 z1, z2; |
| 71 | int ignore; | 73 | int ignore; |
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | struct ads7846 { | 76 | struct ads7846 { |
| @@ -76,7 +78,12 @@ struct ads7846 { | |||
| 76 | char phys[32]; | 78 | char phys[32]; |
| 77 | 79 | ||
| 78 | struct spi_device *spi; | 80 | struct spi_device *spi; |
| 81 | |||
| 82 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) | ||
| 79 | struct attribute_group *attr_group; | 83 | struct attribute_group *attr_group; |
| 84 | struct class_device *hwmon; | ||
| 85 | #endif | ||
| 86 | |||
| 80 | u16 model; | 87 | u16 model; |
| 81 | u16 vref_delay_usecs; | 88 | u16 vref_delay_usecs; |
| 82 | u16 x_plate_ohms; | 89 | u16 x_plate_ohms; |
| @@ -99,13 +106,16 @@ struct ads7846 { | |||
| 99 | u16 debounce_rep; | 106 | u16 debounce_rep; |
| 100 | 107 | ||
| 101 | spinlock_t lock; | 108 | spinlock_t lock; |
| 102 | struct timer_list timer; /* P: lock */ | 109 | struct hrtimer timer; |
| 103 | unsigned pendown:1; /* P: lock */ | 110 | unsigned pendown:1; /* P: lock */ |
| 104 | unsigned pending:1; /* P: lock */ | 111 | unsigned pending:1; /* P: lock */ |
| 105 | // FIXME remove "irq_disabled" | 112 | // FIXME remove "irq_disabled" |
| 106 | unsigned irq_disabled:1; /* P: lock */ | 113 | unsigned irq_disabled:1; /* P: lock */ |
| 107 | unsigned disabled:1; | 114 | unsigned disabled:1; |
| 108 | 115 | ||
| 116 | int (*filter)(void *data, int data_idx, int *val); | ||
| 117 | void *filter_data; | ||
| 118 | void (*filter_cleanup)(void *data); | ||
| 109 | int (*get_pendown_state)(void); | 119 | int (*get_pendown_state)(void); |
| 110 | }; | 120 | }; |
| 111 | 121 | ||
| @@ -142,15 +152,16 @@ struct ads7846 { | |||
| 142 | #define MAX_12BIT ((1<<12)-1) | 152 | #define MAX_12BIT ((1<<12)-1) |
| 143 | 153 | ||
| 144 | /* leave ADC powered up (disables penirq) between differential samples */ | 154 | /* leave ADC powered up (disables penirq) between differential samples */ |
| 145 | #define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ | 155 | #define READ_12BIT_DFR(x, adc, vref) (ADS_START | ADS_A2A1A0_d_ ## x \ |
| 146 | | ADS_12_BIT | ADS_DFR) | 156 | | ADS_12_BIT | ADS_DFR | \ |
| 157 | (adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0)) | ||
| 147 | 158 | ||
| 148 | #define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON) | 159 | #define READ_Y(vref) (READ_12BIT_DFR(y, 1, vref)) |
| 149 | #define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON) | 160 | #define READ_Z1(vref) (READ_12BIT_DFR(z1, 1, vref)) |
| 150 | #define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON) | 161 | #define READ_Z2(vref) (READ_12BIT_DFR(z2, 1, vref)) |
| 151 | 162 | ||
| 152 | #define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON) | 163 | #define READ_X(vref) (READ_12BIT_DFR(x, 1, vref)) |
| 153 | #define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */ | 164 | #define PWRDOWN (READ_12BIT_DFR(y, 0, 0)) /* LAST */ |
| 154 | 165 | ||
| 155 | /* single-ended samples need to first power up reference voltage; | 166 | /* single-ended samples need to first power up reference voltage; |
| 156 | * we leave both ADC and VREF powered | 167 | * we leave both ADC and VREF powered |
| @@ -158,14 +169,19 @@ struct ads7846 { | |||
| 158 | #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ | 169 | #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ |
| 159 | | ADS_12_BIT | ADS_SER) | 170 | | ADS_12_BIT | ADS_SER) |
| 160 | 171 | ||
| 161 | #define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON) | 172 | #define REF_ON (READ_12BIT_DFR(x, 1, 1)) |
| 162 | #define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) | 173 | #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) |
| 163 | 174 | ||
| 164 | /*--------------------------------------------------------------------------*/ | 175 | /*--------------------------------------------------------------------------*/ |
| 165 | 176 | ||
| 166 | /* | 177 | /* |
| 167 | * Non-touchscreen sensors only use single-ended conversions. | 178 | * Non-touchscreen sensors only use single-ended conversions. |
| 179 | * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; | ||
| 180 | * ads7846 lets that pin be unconnected, to use internal vREF. | ||
| 168 | */ | 181 | */ |
| 182 | static unsigned vREF_mV; | ||
| 183 | module_param(vREF_mV, uint, 0); | ||
| 184 | MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts"); | ||
| 169 | 185 | ||
| 170 | struct ser_req { | 186 | struct ser_req { |
| 171 | u8 ref_on; | 187 | u8 ref_on; |
| @@ -193,50 +209,55 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
| 193 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); | 209 | struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL); |
| 194 | int status; | 210 | int status; |
| 195 | int sample; | 211 | int sample; |
| 196 | int i; | 212 | int use_internal; |
| 197 | 213 | ||
| 198 | if (!req) | 214 | if (!req) |
| 199 | return -ENOMEM; | 215 | return -ENOMEM; |
| 200 | 216 | ||
| 201 | spi_message_init(&req->msg); | 217 | spi_message_init(&req->msg); |
| 202 | 218 | ||
| 203 | /* activate reference, so it has time to settle; */ | 219 | /* FIXME boards with ads7846 might use external vref instead ... */ |
| 204 | req->ref_on = REF_ON; | 220 | use_internal = (ts->model == 7846); |
| 205 | req->xfer[0].tx_buf = &req->ref_on; | 221 | |
| 206 | req->xfer[0].len = 1; | 222 | /* maybe turn on internal vREF, and let it settle */ |
| 207 | req->xfer[1].rx_buf = &req->scratch; | 223 | if (use_internal) { |
| 208 | req->xfer[1].len = 2; | 224 | req->ref_on = REF_ON; |
| 209 | 225 | req->xfer[0].tx_buf = &req->ref_on; | |
| 210 | /* | 226 | req->xfer[0].len = 1; |
| 211 | * for external VREF, 0 usec (and assume it's always on); | 227 | spi_message_add_tail(&req->xfer[0], &req->msg); |
| 212 | * for 1uF, use 800 usec; | 228 | |
| 213 | * no cap, 100 usec. | 229 | req->xfer[1].rx_buf = &req->scratch; |
| 214 | */ | 230 | req->xfer[1].len = 2; |
| 215 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | 231 | |
| 232 | /* for 1uF, settle for 800 usec; no cap, 100 usec. */ | ||
| 233 | req->xfer[1].delay_usecs = ts->vref_delay_usecs; | ||
| 234 | spi_message_add_tail(&req->xfer[1], &req->msg); | ||
| 235 | } | ||
| 216 | 236 | ||
| 217 | /* take sample */ | 237 | /* take sample */ |
| 218 | req->command = (u8) command; | 238 | req->command = (u8) command; |
| 219 | req->xfer[2].tx_buf = &req->command; | 239 | req->xfer[2].tx_buf = &req->command; |
| 220 | req->xfer[2].len = 1; | 240 | req->xfer[2].len = 1; |
| 241 | spi_message_add_tail(&req->xfer[2], &req->msg); | ||
| 242 | |||
| 221 | req->xfer[3].rx_buf = &req->sample; | 243 | req->xfer[3].rx_buf = &req->sample; |
| 222 | req->xfer[3].len = 2; | 244 | req->xfer[3].len = 2; |
| 245 | spi_message_add_tail(&req->xfer[3], &req->msg); | ||
| 223 | 246 | ||
| 224 | /* REVISIT: take a few more samples, and compare ... */ | 247 | /* REVISIT: take a few more samples, and compare ... */ |
| 225 | 248 | ||
| 226 | /* turn off reference */ | 249 | /* maybe off internal vREF */ |
| 227 | req->ref_off = REF_OFF; | 250 | if (use_internal) { |
| 228 | req->xfer[4].tx_buf = &req->ref_off; | 251 | req->ref_off = REF_OFF; |
| 229 | req->xfer[4].len = 1; | 252 | req->xfer[4].tx_buf = &req->ref_off; |
| 230 | req->xfer[5].rx_buf = &req->scratch; | 253 | req->xfer[4].len = 1; |
| 231 | req->xfer[5].len = 2; | 254 | spi_message_add_tail(&req->xfer[4], &req->msg); |
| 232 | 255 | ||
| 233 | CS_CHANGE(req->xfer[5]); | 256 | req->xfer[5].rx_buf = &req->scratch; |
| 234 | 257 | req->xfer[5].len = 2; | |
| 235 | /* group all the transfers together, so we can't interfere with | 258 | CS_CHANGE(req->xfer[5]); |
| 236 | * reading touchscreen state; disable penirq while sampling | 259 | spi_message_add_tail(&req->xfer[5], &req->msg); |
| 237 | */ | 260 | } |
| 238 | for (i = 0; i < 6; i++) | ||
| 239 | spi_message_add_tail(&req->xfer[i], &req->msg); | ||
| 240 | 261 | ||
| 241 | ts->irq_disabled = 1; | 262 | ts->irq_disabled = 1; |
| 242 | disable_irq(spi->irq); | 263 | disable_irq(spi->irq); |
| @@ -256,25 +277,173 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) | |||
| 256 | return status ? status : sample; | 277 | return status ? status : sample; |
| 257 | } | 278 | } |
| 258 | 279 | ||
| 259 | #define SHOW(name) static ssize_t \ | 280 | #if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE) |
| 281 | |||
| 282 | #define SHOW(name, var, adjust) static ssize_t \ | ||
| 260 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | 283 | name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ |
| 261 | { \ | 284 | { \ |
| 285 | struct ads7846 *ts = dev_get_drvdata(dev); \ | ||
| 262 | ssize_t v = ads7846_read12_ser(dev, \ | 286 | ssize_t v = ads7846_read12_ser(dev, \ |
| 263 | READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \ | 287 | READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \ |
| 264 | if (v < 0) \ | 288 | if (v < 0) \ |
| 265 | return v; \ | 289 | return v; \ |
| 266 | return sprintf(buf, "%u\n", (unsigned) v); \ | 290 | return sprintf(buf, "%u\n", adjust(ts, v)); \ |
| 267 | } \ | 291 | } \ |
| 268 | static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); | 292 | static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); |
| 269 | 293 | ||
| 270 | SHOW(temp0) | 294 | |
| 271 | SHOW(temp1) | 295 | /* Sysfs conventions report temperatures in millidegrees Celcius. |
| 272 | SHOW(vaux) | 296 | * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high |
| 273 | SHOW(vbatt) | 297 | * accuracy scheme without calibration data. For now we won't try either; |
| 298 | * userspace sees raw sensor values, and must scale/calibrate appropriately. | ||
| 299 | */ | ||
| 300 | static inline unsigned null_adjust(struct ads7846 *ts, ssize_t v) | ||
| 301 | { | ||
| 302 | return v; | ||
| 303 | } | ||
| 304 | |||
| 305 | SHOW(temp0, temp0, null_adjust) /* temp1_input */ | ||
| 306 | SHOW(temp1, temp1, null_adjust) /* temp2_input */ | ||
| 307 | |||
| 308 | |||
| 309 | /* sysfs conventions report voltages in millivolts. We can convert voltages | ||
| 310 | * if we know vREF. userspace may need to scale vAUX to match the board's | ||
| 311 | * external resistors; we assume that vBATT only uses the internal ones. | ||
| 312 | */ | ||
| 313 | static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v) | ||
| 314 | { | ||
| 315 | unsigned retval = v; | ||
| 316 | |||
| 317 | /* external resistors may scale vAUX into 0..vREF */ | ||
| 318 | retval *= vREF_mV; | ||
| 319 | retval = retval >> 12; | ||
| 320 | return retval; | ||
| 321 | } | ||
| 322 | |||
| 323 | static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v) | ||
| 324 | { | ||
| 325 | unsigned retval = vaux_adjust(ts, v); | ||
| 326 | |||
| 327 | /* ads7846 has a resistor ladder to scale this signal down */ | ||
| 328 | if (ts->model == 7846) | ||
| 329 | retval *= 4; | ||
| 330 | return retval; | ||
| 331 | } | ||
| 332 | |||
| 333 | SHOW(in0_input, vaux, vaux_adjust) | ||
| 334 | SHOW(in1_input, vbatt, vbatt_adjust) | ||
| 335 | |||
| 336 | |||
| 337 | static struct attribute *ads7846_attributes[] = { | ||
| 338 | &dev_attr_temp0.attr, | ||
| 339 | &dev_attr_temp1.attr, | ||
| 340 | &dev_attr_in0_input.attr, | ||
| 341 | &dev_attr_in1_input.attr, | ||
| 342 | NULL, | ||
| 343 | }; | ||
| 344 | |||
| 345 | static struct attribute_group ads7846_attr_group = { | ||
| 346 | .attrs = ads7846_attributes, | ||
| 347 | }; | ||
| 348 | |||
| 349 | static struct attribute *ads7843_attributes[] = { | ||
| 350 | &dev_attr_in0_input.attr, | ||
| 351 | &dev_attr_in1_input.attr, | ||
| 352 | NULL, | ||
| 353 | }; | ||
| 354 | |||
| 355 | static struct attribute_group ads7843_attr_group = { | ||
| 356 | .attrs = ads7843_attributes, | ||
| 357 | }; | ||
| 358 | |||
| 359 | static struct attribute *ads7845_attributes[] = { | ||
| 360 | &dev_attr_in0_input.attr, | ||
| 361 | NULL, | ||
| 362 | }; | ||
| 363 | |||
| 364 | static struct attribute_group ads7845_attr_group = { | ||
| 365 | .attrs = ads7845_attributes, | ||
| 366 | }; | ||
| 367 | |||
| 368 | static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts) | ||
| 369 | { | ||
| 370 | struct class_device *hwmon; | ||
| 371 | int err; | ||
| 372 | |||
| 373 | /* hwmon sensors need a reference voltage */ | ||
| 374 | switch (ts->model) { | ||
| 375 | case 7846: | ||
| 376 | if (!vREF_mV) { | ||
| 377 | dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n"); | ||
| 378 | vREF_mV = 2500; | ||
| 379 | } | ||
| 380 | break; | ||
| 381 | case 7845: | ||
| 382 | case 7843: | ||
| 383 | if (!vREF_mV) { | ||
| 384 | dev_warn(&spi->dev, | ||
| 385 | "external vREF for ADS%d not specified\n", | ||
| 386 | ts->model); | ||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | |||
| 392 | /* different chips have different sensor groups */ | ||
| 393 | switch (ts->model) { | ||
| 394 | case 7846: | ||
| 395 | ts->attr_group = &ads7846_attr_group; | ||
| 396 | break; | ||
| 397 | case 7845: | ||
| 398 | ts->attr_group = &ads7845_attr_group; | ||
| 399 | break; | ||
| 400 | case 7843: | ||
| 401 | ts->attr_group = &ads7843_attr_group; | ||
| 402 | break; | ||
| 403 | default: | ||
| 404 | dev_dbg(&spi->dev, "ADS%d not recognized\n", ts->model); | ||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | |||
| 408 | err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); | ||
| 409 | if (err) | ||
| 410 | return err; | ||
| 411 | |||
| 412 | hwmon = hwmon_device_register(&spi->dev); | ||
| 413 | if (IS_ERR(hwmon)) { | ||
| 414 | sysfs_remove_group(&spi->dev.kobj, ts->attr_group); | ||
| 415 | return PTR_ERR(hwmon); | ||
| 416 | } | ||
| 417 | |||
| 418 | ts->hwmon = hwmon; | ||
| 419 | return 0; | ||
| 420 | } | ||
| 421 | |||
| 422 | static void ads784x_hwmon_unregister(struct spi_device *spi, | ||
| 423 | struct ads7846 *ts) | ||
| 424 | { | ||
| 425 | if (ts->hwmon) { | ||
| 426 | sysfs_remove_group(&spi->dev.kobj, ts->attr_group); | ||
| 427 | hwmon_device_unregister(ts->hwmon); | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | #else | ||
| 432 | static inline int ads784x_hwmon_register(struct spi_device *spi, | ||
| 433 | struct ads7846 *ts) | ||
| 434 | { | ||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | |||
| 438 | static inline void ads784x_hwmon_unregister(struct spi_device *spi, | ||
| 439 | struct ads7846 *ts) | ||
| 440 | { | ||
| 441 | } | ||
| 442 | #endif | ||
| 274 | 443 | ||
| 275 | static int is_pen_down(struct device *dev) | 444 | static int is_pen_down(struct device *dev) |
| 276 | { | 445 | { |
| 277 | struct ads7846 *ts = dev_get_drvdata(dev); | 446 | struct ads7846 *ts = dev_get_drvdata(dev); |
| 278 | 447 | ||
| 279 | return ts->pendown; | 448 | return ts->pendown; |
| 280 | } | 449 | } |
| @@ -318,46 +487,14 @@ static ssize_t ads7846_disable_store(struct device *dev, | |||
| 318 | 487 | ||
| 319 | static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); | 488 | static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store); |
| 320 | 489 | ||
| 321 | static struct attribute *ads7846_attributes[] = { | 490 | static struct attribute *ads784x_attributes[] = { |
| 322 | &dev_attr_temp0.attr, | ||
| 323 | &dev_attr_temp1.attr, | ||
| 324 | &dev_attr_vbatt.attr, | ||
| 325 | &dev_attr_vaux.attr, | ||
| 326 | &dev_attr_pen_down.attr, | ||
| 327 | &dev_attr_disable.attr, | ||
| 328 | NULL, | ||
| 329 | }; | ||
| 330 | |||
| 331 | static struct attribute_group ads7846_attr_group = { | ||
| 332 | .attrs = ads7846_attributes, | ||
| 333 | }; | ||
| 334 | |||
| 335 | /* | ||
| 336 | * ads7843/7845 don't have temperature sensors, and | ||
| 337 | * use the other sensors a bit differently too | ||
| 338 | */ | ||
| 339 | |||
| 340 | static struct attribute *ads7843_attributes[] = { | ||
| 341 | &dev_attr_vbatt.attr, | ||
| 342 | &dev_attr_vaux.attr, | ||
| 343 | &dev_attr_pen_down.attr, | 491 | &dev_attr_pen_down.attr, |
| 344 | &dev_attr_disable.attr, | 492 | &dev_attr_disable.attr, |
| 345 | NULL, | 493 | NULL, |
| 346 | }; | 494 | }; |
| 347 | 495 | ||
| 348 | static struct attribute_group ads7843_attr_group = { | 496 | static struct attribute_group ads784x_attr_group = { |
| 349 | .attrs = ads7843_attributes, | 497 | .attrs = ads784x_attributes, |
| 350 | }; | ||
| 351 | |||
| 352 | static struct attribute *ads7845_attributes[] = { | ||
| 353 | &dev_attr_vaux.attr, | ||
| 354 | &dev_attr_pen_down.attr, | ||
| 355 | &dev_attr_disable.attr, | ||
| 356 | NULL, | ||
| 357 | }; | ||
| 358 | |||
| 359 | static struct attribute_group ads7845_attr_group = { | ||
| 360 | .attrs = ads7845_attributes, | ||
| 361 | }; | 498 | }; |
| 362 | 499 | ||
| 363 | /*--------------------------------------------------------------------------*/ | 500 | /*--------------------------------------------------------------------------*/ |
| @@ -373,25 +510,22 @@ static struct attribute_group ads7845_attr_group = { | |||
| 373 | static void ads7846_rx(void *ads) | 510 | static void ads7846_rx(void *ads) |
| 374 | { | 511 | { |
| 375 | struct ads7846 *ts = ads; | 512 | struct ads7846 *ts = ads; |
| 376 | struct input_dev *input_dev = ts->input; | ||
| 377 | unsigned Rt; | 513 | unsigned Rt; |
| 378 | unsigned sync = 0; | ||
| 379 | u16 x, y, z1, z2; | 514 | u16 x, y, z1, z2; |
| 380 | unsigned long flags; | ||
| 381 | 515 | ||
| 382 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; | 516 | /* ads7846_rx_val() did in-place conversion (including byteswap) from |
| 383 | * built from two 8 bit values written msb-first. | 517 | * on-the-wire format as part of debouncing to get stable readings. |
| 384 | */ | 518 | */ |
| 385 | x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff; | 519 | x = ts->tc.x; |
| 386 | y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff; | 520 | y = ts->tc.y; |
| 387 | z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff; | 521 | z1 = ts->tc.z1; |
| 388 | z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff; | 522 | z2 = ts->tc.z2; |
| 389 | 523 | ||
| 390 | /* range filtering */ | 524 | /* range filtering */ |
| 391 | if (x == MAX_12BIT) | 525 | if (x == MAX_12BIT) |
| 392 | x = 0; | 526 | x = 0; |
| 393 | 527 | ||
| 394 | if (likely(x && z1 && !device_suspended(&ts->spi->dev))) { | 528 | if (likely(x && z1)) { |
| 395 | /* compute touch pressure resistance using equation #2 */ | 529 | /* compute touch pressure resistance using equation #2 */ |
| 396 | Rt = z2; | 530 | Rt = z2; |
| 397 | Rt -= z1; | 531 | Rt -= z1; |
| @@ -403,100 +537,129 @@ static void ads7846_rx(void *ads) | |||
| 403 | Rt = 0; | 537 | Rt = 0; |
| 404 | 538 | ||
| 405 | /* Sample found inconsistent by debouncing or pressure is beyond | 539 | /* Sample found inconsistent by debouncing or pressure is beyond |
| 406 | * the maximum. Don't report it to user space, repeat at least | 540 | * the maximum. Don't report it to user space, repeat at least |
| 407 | * once more the measurement */ | 541 | * once more the measurement |
| 542 | */ | ||
| 408 | if (ts->tc.ignore || Rt > ts->pressure_max) { | 543 | if (ts->tc.ignore || Rt > ts->pressure_max) { |
| 409 | mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); | 544 | #ifdef VERBOSE |
| 545 | pr_debug("%s: ignored %d pressure %d\n", | ||
| 546 | ts->spi->dev.bus_id, ts->tc.ignore, Rt); | ||
| 547 | #endif | ||
| 548 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), | ||
| 549 | HRTIMER_REL); | ||
| 410 | return; | 550 | return; |
| 411 | } | 551 | } |
| 412 | 552 | ||
| 413 | /* NOTE: "pendown" is inferred from pressure; we don't rely on | 553 | /* NOTE: We can't rely on the pressure to determine the pen down |
| 414 | * being able to check nPENIRQ status, or "friendly" trigger modes | 554 | * state, even this controller has a pressure sensor. The pressure |
| 415 | * (both-edges is much better than just-falling or low-level). | 555 | * value can fluctuate for quite a while after lifting the pen and |
| 556 | * in some cases may not even settle at the expected value. | ||
| 416 | * | 557 | * |
| 417 | * REVISIT: some boards may require reading nPENIRQ; it's | 558 | * The only safe way to check for the pen up condition is in the |
| 418 | * needed on 7843. and 7845 reads pressure differently... | 559 | * timer by reading the pen signal state (it's a GPIO _and_ IRQ). |
| 419 | * | ||
| 420 | * REVISIT: the touchscreen might not be connected; this code | ||
| 421 | * won't notice that, even if nPENIRQ never fires ... | ||
| 422 | */ | 560 | */ |
| 423 | if (!ts->pendown && Rt != 0) { | ||
| 424 | input_report_key(input_dev, BTN_TOUCH, 1); | ||
| 425 | sync = 1; | ||
| 426 | } else if (ts->pendown && Rt == 0) { | ||
| 427 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
| 428 | sync = 1; | ||
| 429 | } | ||
| 430 | |||
| 431 | if (Rt) { | 561 | if (Rt) { |
| 432 | input_report_abs(input_dev, ABS_X, x); | 562 | struct input_dev *input = ts->input; |
| 433 | input_report_abs(input_dev, ABS_Y, y); | ||
| 434 | sync = 1; | ||
| 435 | } | ||
| 436 | |||
| 437 | if (sync) { | ||
| 438 | input_report_abs(input_dev, ABS_PRESSURE, Rt); | ||
| 439 | input_sync(input_dev); | ||
| 440 | } | ||
| 441 | 563 | ||
| 442 | #ifdef VERBOSE | 564 | if (!ts->pendown) { |
| 443 | if (Rt || ts->pendown) | 565 | input_report_key(input, BTN_TOUCH, 1); |
| 444 | pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id, | 566 | ts->pendown = 1; |
| 445 | x, y, Rt, Rt ? "" : " UP"); | 567 | #ifdef VERBOSE |
| 568 | dev_dbg(&ts->spi->dev, "DOWN\n"); | ||
| 446 | #endif | 569 | #endif |
| 570 | } | ||
| 571 | input_report_abs(input, ABS_X, x); | ||
| 572 | input_report_abs(input, ABS_Y, y); | ||
| 573 | input_report_abs(input, ABS_PRESSURE, Rt); | ||
| 447 | 574 | ||
| 448 | spin_lock_irqsave(&ts->lock, flags); | 575 | input_sync(input); |
| 449 | 576 | #ifdef VERBOSE | |
| 450 | ts->pendown = (Rt != 0); | 577 | dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); |
| 451 | mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); | 578 | #endif |
| 579 | } | ||
| 452 | 580 | ||
| 453 | spin_unlock_irqrestore(&ts->lock, flags); | 581 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL); |
| 454 | } | 582 | } |
| 455 | 583 | ||
| 456 | static void ads7846_debounce(void *ads) | 584 | static int ads7846_debounce(void *ads, int data_idx, int *val) |
| 457 | { | 585 | { |
| 458 | struct ads7846 *ts = ads; | 586 | struct ads7846 *ts = ads; |
| 459 | struct spi_message *m; | ||
| 460 | struct spi_transfer *t; | ||
| 461 | int val; | ||
| 462 | int status; | ||
| 463 | 587 | ||
| 464 | m = &ts->msg[ts->msg_idx]; | 588 | if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { |
| 465 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | 589 | /* Start over collecting consistent readings. */ |
| 466 | val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff; | 590 | ts->read_rep = 0; |
| 467 | if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) { | ||
| 468 | /* Repeat it, if this was the first read or the read | 591 | /* Repeat it, if this was the first read or the read |
| 469 | * wasn't consistent enough. */ | 592 | * wasn't consistent enough. */ |
| 470 | if (ts->read_cnt < ts->debounce_max) { | 593 | if (ts->read_cnt < ts->debounce_max) { |
| 471 | ts->last_read = val; | 594 | ts->last_read = *val; |
| 472 | ts->read_cnt++; | 595 | ts->read_cnt++; |
| 596 | return ADS7846_FILTER_REPEAT; | ||
| 473 | } else { | 597 | } else { |
| 474 | /* Maximum number of debouncing reached and still | 598 | /* Maximum number of debouncing reached and still |
| 475 | * not enough number of consistent readings. Abort | 599 | * not enough number of consistent readings. Abort |
| 476 | * the whole sample, repeat it in the next sampling | 600 | * the whole sample, repeat it in the next sampling |
| 477 | * period. | 601 | * period. |
| 478 | */ | 602 | */ |
| 479 | ts->tc.ignore = 1; | ||
| 480 | ts->read_cnt = 0; | 603 | ts->read_cnt = 0; |
| 481 | /* Last message will contain ads7846_rx() as the | 604 | return ADS7846_FILTER_IGNORE; |
| 482 | * completion function. | ||
| 483 | */ | ||
| 484 | m = ts->last_msg; | ||
| 485 | } | 605 | } |
| 486 | /* Start over collecting consistent readings. */ | ||
| 487 | ts->read_rep = 0; | ||
| 488 | } else { | 606 | } else { |
| 489 | if (++ts->read_rep > ts->debounce_rep) { | 607 | if (++ts->read_rep > ts->debounce_rep) { |
| 490 | /* Got a good reading for this coordinate, | 608 | /* Got a good reading for this coordinate, |
| 491 | * go for the next one. */ | 609 | * go for the next one. */ |
| 492 | ts->tc.ignore = 0; | ||
| 493 | ts->msg_idx++; | ||
| 494 | ts->read_cnt = 0; | 610 | ts->read_cnt = 0; |
| 495 | ts->read_rep = 0; | 611 | ts->read_rep = 0; |
| 496 | m++; | 612 | return ADS7846_FILTER_OK; |
| 497 | } else | 613 | } else { |
| 498 | /* Read more values that are consistent. */ | 614 | /* Read more values that are consistent. */ |
| 499 | ts->read_cnt++; | 615 | ts->read_cnt++; |
| 616 | return ADS7846_FILTER_REPEAT; | ||
| 617 | } | ||
| 618 | } | ||
| 619 | } | ||
| 620 | |||
| 621 | static int ads7846_no_filter(void *ads, int data_idx, int *val) | ||
| 622 | { | ||
| 623 | return ADS7846_FILTER_OK; | ||
| 624 | } | ||
| 625 | |||
| 626 | static void ads7846_rx_val(void *ads) | ||
| 627 | { | ||
| 628 | struct ads7846 *ts = ads; | ||
| 629 | struct spi_message *m; | ||
| 630 | struct spi_transfer *t; | ||
| 631 | u16 *rx_val; | ||
| 632 | int val; | ||
| 633 | int action; | ||
| 634 | int status; | ||
| 635 | |||
| 636 | m = &ts->msg[ts->msg_idx]; | ||
| 637 | t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list); | ||
| 638 | rx_val = t->rx_buf; | ||
| 639 | |||
| 640 | /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding; | ||
| 641 | * built from two 8 bit values written msb-first. | ||
| 642 | */ | ||
| 643 | val = be16_to_cpu(*rx_val) >> 3; | ||
| 644 | |||
| 645 | action = ts->filter(ts->filter_data, ts->msg_idx, &val); | ||
| 646 | switch (action) { | ||
| 647 | case ADS7846_FILTER_REPEAT: | ||
| 648 | break; | ||
| 649 | case ADS7846_FILTER_IGNORE: | ||
| 650 | ts->tc.ignore = 1; | ||
| 651 | /* Last message will contain ads7846_rx() as the | ||
| 652 | * completion function. | ||
| 653 | */ | ||
| 654 | m = ts->last_msg; | ||
| 655 | break; | ||
| 656 | case ADS7846_FILTER_OK: | ||
| 657 | *rx_val = val; | ||
| 658 | ts->tc.ignore = 0; | ||
| 659 | m = &ts->msg[++ts->msg_idx]; | ||
| 660 | break; | ||
| 661 | default: | ||
| 662 | BUG(); | ||
| 500 | } | 663 | } |
| 501 | status = spi_async(ts->spi, m); | 664 | status = spi_async(ts->spi, m); |
| 502 | if (status) | 665 | if (status) |
| @@ -504,21 +667,34 @@ static void ads7846_debounce(void *ads) | |||
| 504 | status); | 667 | status); |
| 505 | } | 668 | } |
| 506 | 669 | ||
| 507 | static void ads7846_timer(unsigned long handle) | 670 | static int ads7846_timer(struct hrtimer *handle) |
| 508 | { | 671 | { |
| 509 | struct ads7846 *ts = (void *)handle; | 672 | struct ads7846 *ts = container_of(handle, struct ads7846, timer); |
| 510 | int status = 0; | 673 | int status = 0; |
| 511 | 674 | ||
| 512 | spin_lock_irq(&ts->lock); | 675 | spin_lock_irq(&ts->lock); |
| 513 | 676 | ||
| 514 | if (unlikely(ts->msg_idx && !ts->pendown)) { | 677 | if (unlikely(!ts->get_pendown_state() || |
| 678 | device_suspended(&ts->spi->dev))) { | ||
| 679 | if (ts->pendown) { | ||
| 680 | struct input_dev *input = ts->input; | ||
| 681 | |||
| 682 | input_report_key(input, BTN_TOUCH, 0); | ||
| 683 | input_report_abs(input, ABS_PRESSURE, 0); | ||
| 684 | input_sync(input); | ||
| 685 | |||
| 686 | ts->pendown = 0; | ||
| 687 | #ifdef VERBOSE | ||
| 688 | dev_dbg(&ts->spi->dev, "UP\n"); | ||
| 689 | #endif | ||
| 690 | } | ||
| 691 | |||
| 515 | /* measurement cycle ended */ | 692 | /* measurement cycle ended */ |
| 516 | if (!device_suspended(&ts->spi->dev)) { | 693 | if (!device_suspended(&ts->spi->dev)) { |
| 517 | ts->irq_disabled = 0; | 694 | ts->irq_disabled = 0; |
| 518 | enable_irq(ts->spi->irq); | 695 | enable_irq(ts->spi->irq); |
| 519 | } | 696 | } |
| 520 | ts->pending = 0; | 697 | ts->pending = 0; |
| 521 | ts->msg_idx = 0; | ||
| 522 | } else { | 698 | } else { |
| 523 | /* pen is still down, continue with the measurement */ | 699 | /* pen is still down, continue with the measurement */ |
| 524 | ts->msg_idx = 0; | 700 | ts->msg_idx = 0; |
| @@ -528,6 +704,7 @@ static void ads7846_timer(unsigned long handle) | |||
| 528 | } | 704 | } |
| 529 | 705 | ||
| 530 | spin_unlock_irq(&ts->lock); | 706 | spin_unlock_irq(&ts->lock); |
| 707 | return HRTIMER_NORESTART; | ||
| 531 | } | 708 | } |
| 532 | 709 | ||
| 533 | static irqreturn_t ads7846_irq(int irq, void *handle) | 710 | static irqreturn_t ads7846_irq(int irq, void *handle) |
| @@ -546,7 +723,8 @@ static irqreturn_t ads7846_irq(int irq, void *handle) | |||
| 546 | ts->irq_disabled = 1; | 723 | ts->irq_disabled = 1; |
| 547 | disable_irq(ts->spi->irq); | 724 | disable_irq(ts->spi->irq); |
| 548 | ts->pending = 1; | 725 | ts->pending = 1; |
| 549 | mod_timer(&ts->timer, jiffies); | 726 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), |
| 727 | HRTIMER_REL); | ||
| 550 | } | 728 | } |
| 551 | } | 729 | } |
| 552 | spin_unlock_irqrestore(&ts->lock, flags); | 730 | spin_unlock_irqrestore(&ts->lock, flags); |
| @@ -632,6 +810,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 632 | struct ads7846_platform_data *pdata = spi->dev.platform_data; | 810 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
| 633 | struct spi_message *m; | 811 | struct spi_message *m; |
| 634 | struct spi_transfer *x; | 812 | struct spi_transfer *x; |
| 813 | int vref; | ||
| 635 | int err; | 814 | int err; |
| 636 | 815 | ||
| 637 | if (!spi->irq) { | 816 | if (!spi->irq) { |
| @@ -665,6 +844,10 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 665 | * may not. So we stick to very-portable 8 bit words, both RX and TX. | 844 | * may not. So we stick to very-portable 8 bit words, both RX and TX. |
| 666 | */ | 845 | */ |
| 667 | spi->bits_per_word = 8; | 846 | spi->bits_per_word = 8; |
| 847 | spi->mode = SPI_MODE_1; | ||
| 848 | err = spi_setup(spi); | ||
| 849 | if (err < 0) | ||
| 850 | return err; | ||
| 668 | 851 | ||
| 669 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); | 852 | ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL); |
| 670 | input_dev = input_allocate_device(); | 853 | input_dev = input_allocate_device(); |
| @@ -679,8 +862,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 679 | ts->spi = spi; | 862 | ts->spi = spi; |
| 680 | ts->input = input_dev; | 863 | ts->input = input_dev; |
| 681 | 864 | ||
| 682 | init_timer(&ts->timer); | 865 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_REL); |
| 683 | ts->timer.data = (unsigned long) ts; | ||
| 684 | ts->timer.function = ads7846_timer; | 866 | ts->timer.function = ads7846_timer; |
| 685 | 867 | ||
| 686 | spin_lock_init(&ts->lock); | 868 | spin_lock_init(&ts->lock); |
| @@ -689,14 +871,25 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 689 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; | 871 | ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; |
| 690 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; | 872 | ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; |
| 691 | ts->pressure_max = pdata->pressure_max ? : ~0; | 873 | ts->pressure_max = pdata->pressure_max ? : ~0; |
| 692 | if (pdata->debounce_max) { | 874 | |
| 875 | if (pdata->filter != NULL) { | ||
| 876 | if (pdata->filter_init != NULL) { | ||
| 877 | err = pdata->filter_init(pdata, &ts->filter_data); | ||
| 878 | if (err < 0) | ||
| 879 | goto err_free_mem; | ||
| 880 | } | ||
| 881 | ts->filter = pdata->filter; | ||
| 882 | ts->filter_cleanup = pdata->filter_cleanup; | ||
| 883 | } else if (pdata->debounce_max) { | ||
| 693 | ts->debounce_max = pdata->debounce_max; | 884 | ts->debounce_max = pdata->debounce_max; |
| 885 | if (ts->debounce_max < 2) | ||
| 886 | ts->debounce_max = 2; | ||
| 694 | ts->debounce_tol = pdata->debounce_tol; | 887 | ts->debounce_tol = pdata->debounce_tol; |
| 695 | ts->debounce_rep = pdata->debounce_rep; | 888 | ts->debounce_rep = pdata->debounce_rep; |
| 696 | if (ts->debounce_rep > ts->debounce_max + 1) | 889 | ts->filter = ads7846_debounce; |
| 697 | ts->debounce_rep = ts->debounce_max - 1; | 890 | ts->filter_data = ts; |
| 698 | } else | 891 | } else |
| 699 | ts->debounce_tol = ~0; | 892 | ts->filter = ads7846_no_filter; |
| 700 | ts->get_pendown_state = pdata->get_pendown_state; | 893 | ts->get_pendown_state = pdata->get_pendown_state; |
| 701 | 894 | ||
| 702 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); | 895 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id); |
| @@ -718,6 +911,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 718 | input_set_abs_params(input_dev, ABS_PRESSURE, | 911 | input_set_abs_params(input_dev, ABS_PRESSURE, |
| 719 | pdata->pressure_min, pdata->pressure_max, 0, 0); | 912 | pdata->pressure_min, pdata->pressure_max, 0, 0); |
| 720 | 913 | ||
| 914 | vref = pdata->keep_vref_on; | ||
| 915 | |||
| 721 | /* set up the transfers to read touchscreen state; this assumes we | 916 | /* set up the transfers to read touchscreen state; this assumes we |
| 722 | * use formula #2 for pressure, not #3. | 917 | * use formula #2 for pressure, not #3. |
| 723 | */ | 918 | */ |
| @@ -727,7 +922,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 727 | spi_message_init(m); | 922 | spi_message_init(m); |
| 728 | 923 | ||
| 729 | /* y- still on; turn on only y+ (and ADC) */ | 924 | /* y- still on; turn on only y+ (and ADC) */ |
| 730 | ts->read_y = READ_Y; | 925 | ts->read_y = READ_Y(vref); |
| 731 | x->tx_buf = &ts->read_y; | 926 | x->tx_buf = &ts->read_y; |
| 732 | x->len = 1; | 927 | x->len = 1; |
| 733 | spi_message_add_tail(x, m); | 928 | spi_message_add_tail(x, m); |
| @@ -737,7 +932,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 737 | x->len = 2; | 932 | x->len = 2; |
| 738 | spi_message_add_tail(x, m); | 933 | spi_message_add_tail(x, m); |
| 739 | 934 | ||
| 740 | m->complete = ads7846_debounce; | 935 | m->complete = ads7846_rx_val; |
| 741 | m->context = ts; | 936 | m->context = ts; |
| 742 | 937 | ||
| 743 | m++; | 938 | m++; |
| @@ -745,7 +940,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 745 | 940 | ||
| 746 | /* turn y- off, x+ on, then leave in lowpower */ | 941 | /* turn y- off, x+ on, then leave in lowpower */ |
| 747 | x++; | 942 | x++; |
| 748 | ts->read_x = READ_X; | 943 | ts->read_x = READ_X(vref); |
| 749 | x->tx_buf = &ts->read_x; | 944 | x->tx_buf = &ts->read_x; |
| 750 | x->len = 1; | 945 | x->len = 1; |
| 751 | spi_message_add_tail(x, m); | 946 | spi_message_add_tail(x, m); |
| @@ -755,7 +950,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 755 | x->len = 2; | 950 | x->len = 2; |
| 756 | spi_message_add_tail(x, m); | 951 | spi_message_add_tail(x, m); |
| 757 | 952 | ||
| 758 | m->complete = ads7846_debounce; | 953 | m->complete = ads7846_rx_val; |
| 759 | m->context = ts; | 954 | m->context = ts; |
| 760 | 955 | ||
| 761 | /* turn y+ off, x- on; we'll use formula #2 */ | 956 | /* turn y+ off, x- on; we'll use formula #2 */ |
| @@ -764,7 +959,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 764 | spi_message_init(m); | 959 | spi_message_init(m); |
| 765 | 960 | ||
| 766 | x++; | 961 | x++; |
| 767 | ts->read_z1 = READ_Z1; | 962 | ts->read_z1 = READ_Z1(vref); |
| 768 | x->tx_buf = &ts->read_z1; | 963 | x->tx_buf = &ts->read_z1; |
| 769 | x->len = 1; | 964 | x->len = 1; |
| 770 | spi_message_add_tail(x, m); | 965 | spi_message_add_tail(x, m); |
| @@ -774,14 +969,14 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 774 | x->len = 2; | 969 | x->len = 2; |
| 775 | spi_message_add_tail(x, m); | 970 | spi_message_add_tail(x, m); |
| 776 | 971 | ||
| 777 | m->complete = ads7846_debounce; | 972 | m->complete = ads7846_rx_val; |
| 778 | m->context = ts; | 973 | m->context = ts; |
| 779 | 974 | ||
| 780 | m++; | 975 | m++; |
| 781 | spi_message_init(m); | 976 | spi_message_init(m); |
| 782 | 977 | ||
| 783 | x++; | 978 | x++; |
| 784 | ts->read_z2 = READ_Z2; | 979 | ts->read_z2 = READ_Z2(vref); |
| 785 | x->tx_buf = &ts->read_z2; | 980 | x->tx_buf = &ts->read_z2; |
| 786 | x->len = 1; | 981 | x->len = 1; |
| 787 | spi_message_add_tail(x, m); | 982 | spi_message_add_tail(x, m); |
| @@ -791,7 +986,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 791 | x->len = 2; | 986 | x->len = 2; |
| 792 | spi_message_add_tail(x, m); | 987 | spi_message_add_tail(x, m); |
| 793 | 988 | ||
| 794 | m->complete = ads7846_debounce; | 989 | m->complete = ads7846_rx_val; |
| 795 | m->context = ts; | 990 | m->context = ts; |
| 796 | } | 991 | } |
| 797 | 992 | ||
| @@ -820,31 +1015,24 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 820 | spi->dev.driver->name, ts)) { | 1015 | spi->dev.driver->name, ts)) { |
| 821 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 1016 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); |
| 822 | err = -EBUSY; | 1017 | err = -EBUSY; |
| 823 | goto err_free_mem; | 1018 | goto err_cleanup_filter; |
| 824 | } | 1019 | } |
| 825 | 1020 | ||
| 1021 | err = ads784x_hwmon_register(spi, ts); | ||
| 1022 | if (err) | ||
| 1023 | goto err_free_irq; | ||
| 1024 | |||
| 826 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); | 1025 | dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); |
| 827 | 1026 | ||
| 828 | /* take a first sample, leaving nPENIRQ active; avoid | 1027 | /* take a first sample, leaving nPENIRQ active and vREF off; avoid |
| 829 | * the touchscreen, in case it's not connected. | 1028 | * the touchscreen, in case it's not connected. |
| 830 | */ | 1029 | */ |
| 831 | (void) ads7846_read12_ser(&spi->dev, | 1030 | (void) ads7846_read12_ser(&spi->dev, |
| 832 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); | 1031 | READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); |
| 833 | 1032 | ||
| 834 | switch (ts->model) { | 1033 | err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); |
| 835 | case 7846: | ||
| 836 | ts->attr_group = &ads7846_attr_group; | ||
| 837 | break; | ||
| 838 | case 7845: | ||
| 839 | ts->attr_group = &ads7845_attr_group; | ||
| 840 | break; | ||
| 841 | default: | ||
| 842 | ts->attr_group = &ads7843_attr_group; | ||
| 843 | break; | ||
| 844 | } | ||
| 845 | err = sysfs_create_group(&spi->dev.kobj, ts->attr_group); | ||
| 846 | if (err) | 1034 | if (err) |
| 847 | goto err_free_irq; | 1035 | goto err_remove_hwmon; |
| 848 | 1036 | ||
| 849 | err = input_register_device(input_dev); | 1037 | err = input_register_device(input_dev); |
| 850 | if (err) | 1038 | if (err) |
| @@ -853,9 +1041,14 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 853 | return 0; | 1041 | return 0; |
| 854 | 1042 | ||
| 855 | err_remove_attr_group: | 1043 | err_remove_attr_group: |
| 856 | sysfs_remove_group(&spi->dev.kobj, ts->attr_group); | 1044 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); |
| 1045 | err_remove_hwmon: | ||
| 1046 | ads784x_hwmon_unregister(spi, ts); | ||
| 857 | err_free_irq: | 1047 | err_free_irq: |
| 858 | free_irq(spi->irq, ts); | 1048 | free_irq(spi->irq, ts); |
| 1049 | err_cleanup_filter: | ||
| 1050 | if (ts->filter_cleanup) | ||
| 1051 | ts->filter_cleanup(ts->filter_data); | ||
| 859 | err_free_mem: | 1052 | err_free_mem: |
| 860 | input_free_device(input_dev); | 1053 | input_free_device(input_dev); |
| 861 | kfree(ts); | 1054 | kfree(ts); |
| @@ -866,16 +1059,20 @@ static int __devexit ads7846_remove(struct spi_device *spi) | |||
| 866 | { | 1059 | { |
| 867 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); | 1060 | struct ads7846 *ts = dev_get_drvdata(&spi->dev); |
| 868 | 1061 | ||
| 1062 | ads784x_hwmon_unregister(spi, ts); | ||
| 869 | input_unregister_device(ts->input); | 1063 | input_unregister_device(ts->input); |
| 870 | 1064 | ||
| 871 | ads7846_suspend(spi, PMSG_SUSPEND); | 1065 | ads7846_suspend(spi, PMSG_SUSPEND); |
| 872 | 1066 | ||
| 873 | sysfs_remove_group(&spi->dev.kobj, ts->attr_group); | 1067 | sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); |
| 874 | 1068 | ||
| 875 | free_irq(ts->spi->irq, ts); | 1069 | free_irq(ts->spi->irq, ts); |
| 876 | /* suspend left the IRQ disabled */ | 1070 | /* suspend left the IRQ disabled */ |
| 877 | enable_irq(ts->spi->irq); | 1071 | enable_irq(ts->spi->irq); |
| 878 | 1072 | ||
| 1073 | if (ts->filter_cleanup) | ||
| 1074 | ts->filter_cleanup(ts->filter_data); | ||
| 1075 | |||
| 879 | kfree(ts); | 1076 | kfree(ts); |
| 880 | 1077 | ||
| 881 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 1078 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index a730c461227f..0300dca8591d 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c | |||
| @@ -151,6 +151,10 @@ static int tsdev_open(struct inode *inode, struct file *file) | |||
| 151 | int i = iminor(inode) - TSDEV_MINOR_BASE; | 151 | int i = iminor(inode) - TSDEV_MINOR_BASE; |
| 152 | struct tsdev_list *list; | 152 | struct tsdev_list *list; |
| 153 | 153 | ||
| 154 | printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " | ||
| 155 | "for removal.\nSee Documentation/feature-removal-schedule.txt " | ||
| 156 | "for details.\n"); | ||
| 157 | |||
| 154 | if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) | 158 | if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) |
| 155 | return -ENODEV; | 159 | return -ENODEV; |
| 156 | 160 | ||
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index 5d145058a5cb..bc7f8e6f8c97 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c | |||
| @@ -57,6 +57,7 @@ static struct hid_ff_initializer inits[] = { | |||
| 57 | { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */ | 57 | { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */ |
| 58 | { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ | 58 | { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ |
| 59 | { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ | 59 | { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ |
| 60 | { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */ | ||
| 60 | #endif | 61 | #endif |
| 61 | #ifdef CONFIG_PANTHERLORD_FF | 62 | #ifdef CONFIG_PANTHERLORD_FF |
| 62 | { 0x810, 0x0001, hid_plff_init }, | 63 | { 0x810, 0x0001, hid_plff_init }, |
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c index 4f4fc3be192e..4df0968f852e 100644 --- a/drivers/usb/input/hid-lgff.c +++ b/drivers/usb/input/hid-lgff.c | |||
| @@ -52,6 +52,7 @@ static const struct dev_type devices[] = { | |||
| 52 | { 0x046d, 0xc211, ff_rumble }, | 52 | { 0x046d, 0xc211, ff_rumble }, |
| 53 | { 0x046d, 0xc219, ff_rumble }, | 53 | { 0x046d, 0xc219, ff_rumble }, |
| 54 | { 0x046d, 0xc283, ff_joystick }, | 54 | { 0x046d, 0xc283, ff_joystick }, |
| 55 | { 0x046d, 0xca03, ff_joystick }, | ||
| 55 | { 0x0000, 0x0000, ff_joystick } | 56 | { 0x0000, 0x0000, ff_joystick } |
| 56 | }; | 57 | }; |
| 57 | 58 | ||
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 | ||
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index adb3dafd33e9..3387e44dfd13 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h | |||
| @@ -5,9 +5,17 @@ | |||
| 5 | * | 5 | * |
| 6 | * It's OK if the min/max values are zero. | 6 | * It's OK if the min/max values are zero. |
| 7 | */ | 7 | */ |
| 8 | enum ads7846_filter { | ||
| 9 | ADS7846_FILTER_OK, | ||
| 10 | ADS7846_FILTER_REPEAT, | ||
| 11 | ADS7846_FILTER_IGNORE, | ||
| 12 | }; | ||
| 13 | |||
| 8 | struct ads7846_platform_data { | 14 | struct ads7846_platform_data { |
| 9 | u16 model; /* 7843, 7845, 7846. */ | 15 | u16 model; /* 7843, 7845, 7846. */ |
| 10 | u16 vref_delay_usecs; /* 0 for external vref; etc */ | 16 | u16 vref_delay_usecs; /* 0 for external vref; etc */ |
| 17 | int keep_vref_on:1; /* set to keep vref on for differential | ||
| 18 | * measurements as well */ | ||
| 11 | u16 x_plate_ohms; | 19 | u16 x_plate_ohms; |
| 12 | u16 y_plate_ohms; | 20 | u16 y_plate_ohms; |
| 13 | 21 | ||
| @@ -21,5 +29,9 @@ struct ads7846_platform_data { | |||
| 21 | u16 debounce_rep; /* additional consecutive good readings | 29 | u16 debounce_rep; /* additional consecutive good readings |
| 22 | * required after the first two */ | 30 | * required after the first two */ |
| 23 | int (*get_pendown_state)(void); | 31 | int (*get_pendown_state)(void); |
| 32 | int (*filter_init) (struct ads7846_platform_data *pdata, | ||
| 33 | void **filter_data); | ||
| 34 | int (*filter) (void *filter_data, int data_idx, int *val); | ||
| 35 | void (*filter_cleanup)(void *filter_data); | ||
| 24 | }; | 36 | }; |
| 25 | 37 | ||
