diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-05-08 21:29:27 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-05-08 21:29:27 -0400 |
commit | d585a021c0b10b0477d6b608c53e1feb8cde0507 (patch) | |
tree | 5ca059da1db7f15d4b29427644ad9c08270c885c /drivers/input | |
parent | 84e5b0d00f8f84c4ae226be131d4bebbcee88bd3 (diff) | |
parent | 091bf7624d1c90cec9e578a18529f615213ff847 (diff) |
Merge commit 'v2.6.30-rc5' into next
Diffstat (limited to 'drivers/input')
34 files changed, 360 insertions, 124 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 5f9d860925a1..cd50c00ab20f 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -143,7 +143,7 @@ config INPUT_APMPOWER | |||
143 | ---help--- | 143 | ---help--- |
144 | Say Y here if you want suspend key events to trigger a user | 144 | Say Y here if you want suspend key events to trigger a user |
145 | requested suspend through APM. This is useful on embedded | 145 | requested suspend through APM. This is useful on embedded |
146 | systems where such behviour is desired without userspace | 146 | systems where such behaviour is desired without userspace |
147 | interaction. If unsure, say N. | 147 | interaction. If unsure, say N. |
148 | 148 | ||
149 | To compile this driver as a module, choose M here: the | 149 | To compile this driver as a module, choose M here: the |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index ed8baa0aec3c..7a7a026ba712 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -94,11 +94,8 @@ static void evdev_event(struct input_handle *handle, | |||
94 | static int evdev_fasync(int fd, struct file *file, int on) | 94 | static int evdev_fasync(int fd, struct file *file, int on) |
95 | { | 95 | { |
96 | struct evdev_client *client = file->private_data; | 96 | struct evdev_client *client = file->private_data; |
97 | int retval; | ||
98 | |||
99 | retval = fasync_helper(fd, file, on, &client->fasync); | ||
100 | 97 | ||
101 | return retval < 0 ? retval : 0; | 98 | return fasync_helper(fd, file, on, &client->fasync); |
102 | } | 99 | } |
103 | 100 | ||
104 | static int evdev_flush(struct file *file, fl_owner_t id) | 101 | static int evdev_flush(struct file *file, fl_owner_t id) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index a79c83397a9c..e54e002665b0 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -29,6 +29,23 @@ MODULE_LICENSE("GPL"); | |||
29 | 29 | ||
30 | #define INPUT_DEVICES 256 | 30 | #define INPUT_DEVICES 256 |
31 | 31 | ||
32 | /* | ||
33 | * EV_ABS events which should not be cached are listed here. | ||
34 | */ | ||
35 | static unsigned int input_abs_bypass_init_data[] __initdata = { | ||
36 | ABS_MT_TOUCH_MAJOR, | ||
37 | ABS_MT_TOUCH_MINOR, | ||
38 | ABS_MT_WIDTH_MAJOR, | ||
39 | ABS_MT_WIDTH_MINOR, | ||
40 | ABS_MT_ORIENTATION, | ||
41 | ABS_MT_POSITION_X, | ||
42 | ABS_MT_POSITION_Y, | ||
43 | ABS_MT_TOOL_TYPE, | ||
44 | ABS_MT_BLOB_ID, | ||
45 | 0 | ||
46 | }; | ||
47 | static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; | ||
48 | |||
32 | static LIST_HEAD(input_dev_list); | 49 | static LIST_HEAD(input_dev_list); |
33 | static LIST_HEAD(input_handler_list); | 50 | static LIST_HEAD(input_handler_list); |
34 | 51 | ||
@@ -161,6 +178,10 @@ static void input_handle_event(struct input_dev *dev, | |||
161 | disposition = INPUT_PASS_TO_HANDLERS; | 178 | disposition = INPUT_PASS_TO_HANDLERS; |
162 | } | 179 | } |
163 | break; | 180 | break; |
181 | case SYN_MT_REPORT: | ||
182 | dev->sync = 0; | ||
183 | disposition = INPUT_PASS_TO_HANDLERS; | ||
184 | break; | ||
164 | } | 185 | } |
165 | break; | 186 | break; |
166 | 187 | ||
@@ -192,6 +213,11 @@ static void input_handle_event(struct input_dev *dev, | |||
192 | case EV_ABS: | 213 | case EV_ABS: |
193 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { | 214 | if (is_event_supported(code, dev->absbit, ABS_MAX)) { |
194 | 215 | ||
216 | if (test_bit(code, input_abs_bypass)) { | ||
217 | disposition = INPUT_PASS_TO_HANDLERS; | ||
218 | break; | ||
219 | } | ||
220 | |||
195 | value = input_defuzz_abs_event(value, | 221 | value = input_defuzz_abs_event(value, |
196 | dev->abs[code], dev->absfuzz[code]); | 222 | dev->abs[code], dev->absfuzz[code]); |
197 | 223 | ||
@@ -910,8 +936,6 @@ static int __init input_proc_init(void) | |||
910 | if (!proc_bus_input_dir) | 936 | if (!proc_bus_input_dir) |
911 | return -ENOMEM; | 937 | return -ENOMEM; |
912 | 938 | ||
913 | proc_bus_input_dir->owner = THIS_MODULE; | ||
914 | |||
915 | entry = proc_create("devices", 0, proc_bus_input_dir, | 939 | entry = proc_create("devices", 0, proc_bus_input_dir, |
916 | &input_devices_fileops); | 940 | &input_devices_fileops); |
917 | if (!entry) | 941 | if (!entry) |
@@ -1636,10 +1660,20 @@ static const struct file_operations input_fops = { | |||
1636 | .open = input_open_file, | 1660 | .open = input_open_file, |
1637 | }; | 1661 | }; |
1638 | 1662 | ||
1663 | static void __init input_init_abs_bypass(void) | ||
1664 | { | ||
1665 | const unsigned int *p; | ||
1666 | |||
1667 | for (p = input_abs_bypass_init_data; *p; p++) | ||
1668 | input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p); | ||
1669 | } | ||
1670 | |||
1639 | static int __init input_init(void) | 1671 | static int __init input_init(void) |
1640 | { | 1672 | { |
1641 | int err; | 1673 | int err; |
1642 | 1674 | ||
1675 | input_init_abs_bypass(); | ||
1676 | |||
1643 | err = class_register(&input_class); | 1677 | err = class_register(&input_class); |
1644 | if (err) { | 1678 | if (err) { |
1645 | printk(KERN_ERR "input: unable to register input_dev class\n"); | 1679 | printk(KERN_ERR "input: unable to register input_dev class\n"); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 6f2366220a50..4224f0112849 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -159,12 +159,9 @@ static void joydev_event(struct input_handle *handle, | |||
159 | 159 | ||
160 | static int joydev_fasync(int fd, struct file *file, int on) | 160 | static int joydev_fasync(int fd, struct file *file, int on) |
161 | { | 161 | { |
162 | int retval; | ||
163 | struct joydev_client *client = file->private_data; | 162 | struct joydev_client *client = file->private_data; |
164 | 163 | ||
165 | retval = fasync_helper(fd, file, on, &client->fasync); | 164 | return fasync_helper(fd, file, on, &client->fasync); |
166 | |||
167 | return retval < 0 ? retval : 0; | ||
168 | } | 165 | } |
169 | 166 | ||
170 | static void joydev_free(struct device *dev) | 167 | static void joydev_free(struct device *dev) |
diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c index e50047bfe938..77cfde571bd9 100644 --- a/drivers/input/joystick/maplecontrol.c +++ b/drivers/input/joystick/maplecontrol.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Based on drivers/usb/iforce.c | 3 | * Based on drivers/usb/iforce.c |
4 | * | 4 | * |
5 | * Copyright Yaegashi Takeshi, 2001 | 5 | * Copyright Yaegashi Takeshi, 2001 |
6 | * Adrian McMenamin, 2008 | 6 | * Adrian McMenamin, 2008 - 2009 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
@@ -29,7 +29,7 @@ static void dc_pad_callback(struct mapleq *mq) | |||
29 | struct maple_device *mapledev = mq->dev; | 29 | struct maple_device *mapledev = mq->dev; |
30 | struct dc_pad *pad = maple_get_drvdata(mapledev); | 30 | struct dc_pad *pad = maple_get_drvdata(mapledev); |
31 | struct input_dev *dev = pad->dev; | 31 | struct input_dev *dev = pad->dev; |
32 | unsigned char *res = mq->recvbuf; | 32 | unsigned char *res = mq->recvbuf->buf; |
33 | 33 | ||
34 | buttons = ~le16_to_cpup((__le16 *)(res + 8)); | 34 | buttons = ~le16_to_cpup((__le16 *)(res + 8)); |
35 | 35 | ||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 76407df17cd7..54775aaa7be7 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD | |||
13 | if INPUT_KEYBOARD | 13 | if INPUT_KEYBOARD |
14 | 14 | ||
15 | config KEYBOARD_ATKBD | 15 | config KEYBOARD_ATKBD |
16 | tristate "AT keyboard" if EMBEDDED || !X86_PC | 16 | tristate "AT keyboard" if EMBEDDED || !X86 |
17 | default y | 17 | default y |
18 | select SERIO | 18 | select SERIO |
19 | select SERIO_LIBPS2 | 19 | select SERIO_LIBPS2 |
20 | select SERIO_I8042 if X86_PC | 20 | select SERIO_I8042 if X86 |
21 | select SERIO_GSCPS2 if GSC | 21 | select SERIO_GSCPS2 if GSC |
22 | help | 22 | help |
23 | Say Y here if you want to use a standard AT or PS/2 keyboard. Usually | 23 | Say Y here if you want to use a standard AT or PS/2 keyboard. Usually |
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c index abb04c82c622..634af6a8e6b3 100644 --- a/drivers/input/keyboard/corgikbd.c +++ b/drivers/input/keyboard/corgikbd.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #include <mach/corgi.h> | 23 | #include <mach/corgi.h> |
24 | #include <mach/hardware.h> | ||
25 | #include <mach/pxa-regs.h> | ||
26 | #include <mach/pxa2xx-gpio.h> | 24 | #include <mach/pxa2xx-gpio.h> |
27 | #include <asm/hardware/scoop.h> | 25 | #include <asm/hardware/scoop.h> |
28 | 26 | ||
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 22f17a593be7..5aa2361aef95 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * SEGA Dreamcast keyboard driver | 2 | * SEGA Dreamcast keyboard driver |
3 | * Based on drivers/usb/usbkbd.c | 3 | * Based on drivers/usb/usbkbd.c |
4 | * Copyright YAEGASHI Takeshi, 2001 | 4 | * Copyright (c) YAEGASHI Takeshi, 2001 |
5 | * Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008 | 5 | * Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009 |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
@@ -33,7 +33,7 @@ static DEFINE_MUTEX(maple_keyb_mutex); | |||
33 | 33 | ||
34 | #define NR_SCANCODES 256 | 34 | #define NR_SCANCODES 256 |
35 | 35 | ||
36 | MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin"); | 36 | MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk"); |
37 | MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver"); | 37 | MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver"); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | 39 | ||
@@ -115,7 +115,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd) | |||
115 | input_event(dev, EV_MSC, MSC_SCAN, code); | 115 | input_event(dev, EV_MSC, MSC_SCAN, code); |
116 | input_report_key(dev, keycode, 0); | 116 | input_report_key(dev, keycode, 0); |
117 | } else | 117 | } else |
118 | printk(KERN_DEBUG "maple_keyb: " | 118 | dev_dbg(&dev->dev, |
119 | "Unknown key (scancode %#x) released.", | 119 | "Unknown key (scancode %#x) released.", |
120 | code); | 120 | code); |
121 | } | 121 | } |
@@ -127,7 +127,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd) | |||
127 | input_event(dev, EV_MSC, MSC_SCAN, code); | 127 | input_event(dev, EV_MSC, MSC_SCAN, code); |
128 | input_report_key(dev, keycode, 1); | 128 | input_report_key(dev, keycode, 1); |
129 | } else | 129 | } else |
130 | printk(KERN_DEBUG "maple_keyb: " | 130 | dev_dbg(&dev->dev, |
131 | "Unknown key (scancode %#x) pressed.", | 131 | "Unknown key (scancode %#x) pressed.", |
132 | code); | 132 | code); |
133 | } | 133 | } |
@@ -140,7 +140,7 @@ static void dc_kbd_callback(struct mapleq *mq) | |||
140 | { | 140 | { |
141 | struct maple_device *mapledev = mq->dev; | 141 | struct maple_device *mapledev = mq->dev; |
142 | struct dc_kbd *kbd = maple_get_drvdata(mapledev); | 142 | struct dc_kbd *kbd = maple_get_drvdata(mapledev); |
143 | unsigned long *buf = mq->recvbuf; | 143 | unsigned long *buf = (unsigned long *)(mq->recvbuf->buf); |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * We should always get the lock because the only | 146 | * We should always get the lock because the only |
@@ -159,22 +159,27 @@ static void dc_kbd_callback(struct mapleq *mq) | |||
159 | 159 | ||
160 | static int probe_maple_kbd(struct device *dev) | 160 | static int probe_maple_kbd(struct device *dev) |
161 | { | 161 | { |
162 | struct maple_device *mdev = to_maple_dev(dev); | 162 | struct maple_device *mdev; |
163 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | 163 | struct maple_driver *mdrv; |
164 | int i, error; | 164 | int i, error; |
165 | struct dc_kbd *kbd; | 165 | struct dc_kbd *kbd; |
166 | struct input_dev *idev; | 166 | struct input_dev *idev; |
167 | 167 | ||
168 | if (!(mdev->function & MAPLE_FUNC_KEYBOARD)) | 168 | mdev = to_maple_dev(dev); |
169 | return -EINVAL; | 169 | mdrv = to_maple_driver(dev->driver); |
170 | 170 | ||
171 | kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); | 171 | kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); |
172 | idev = input_allocate_device(); | 172 | if (!kbd) { |
173 | if (!kbd || !idev) { | ||
174 | error = -ENOMEM; | 173 | error = -ENOMEM; |
175 | goto fail; | 174 | goto fail; |
176 | } | 175 | } |
177 | 176 | ||
177 | idev = input_allocate_device(); | ||
178 | if (!idev) { | ||
179 | error = -ENOMEM; | ||
180 | goto fail_idev_alloc; | ||
181 | } | ||
182 | |||
178 | kbd->dev = idev; | 183 | kbd->dev = idev; |
179 | memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); | 184 | memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); |
180 | 185 | ||
@@ -195,7 +200,7 @@ static int probe_maple_kbd(struct device *dev) | |||
195 | 200 | ||
196 | error = input_register_device(idev); | 201 | error = input_register_device(idev); |
197 | if (error) | 202 | if (error) |
198 | goto fail; | 203 | goto fail_register; |
199 | 204 | ||
200 | /* Maple polling is locked to VBLANK - which may be just 50/s */ | 205 | /* Maple polling is locked to VBLANK - which may be just 50/s */ |
201 | maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, | 206 | maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, |
@@ -207,10 +212,12 @@ static int probe_maple_kbd(struct device *dev) | |||
207 | 212 | ||
208 | return error; | 213 | return error; |
209 | 214 | ||
210 | fail: | 215 | fail_register: |
216 | maple_set_drvdata(mdev, NULL); | ||
211 | input_free_device(idev); | 217 | input_free_device(idev); |
218 | fail_idev_alloc: | ||
212 | kfree(kbd); | 219 | kfree(kbd); |
213 | maple_set_drvdata(mdev, NULL); | 220 | fail: |
214 | return error; | 221 | return error; |
215 | } | 222 | } |
216 | 223 | ||
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 058fa8b02c21..87ec7b18ac69 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -100,8 +100,20 @@ static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) | |||
100 | /* disable keyboard interrupt and schedule for handling */ | 100 | /* disable keyboard interrupt and schedule for handling */ |
101 | if (cpu_is_omap24xx()) { | 101 | if (cpu_is_omap24xx()) { |
102 | int i; | 102 | int i; |
103 | for (i = 0; i < omap_kp->rows; i++) | 103 | |
104 | disable_irq(gpio_to_irq(row_gpios[i])); | 104 | for (i = 0; i < omap_kp->rows; i++) { |
105 | int gpio_irq = gpio_to_irq(row_gpios[i]); | ||
106 | /* | ||
107 | * The interrupt which we're currently handling should | ||
108 | * be disabled _nosync() to avoid deadlocks waiting | ||
109 | * for this handler to complete. All others should | ||
110 | * be disabled the regular way for SMP safety. | ||
111 | */ | ||
112 | if (gpio_irq == irq) | ||
113 | disable_irq_nosync(gpio_irq); | ||
114 | else | ||
115 | disable_irq(gpio_irq); | ||
116 | } | ||
105 | } else | 117 | } else |
106 | /* disable keyboard interrupt and schedule for handling */ | 118 | /* disable keyboard interrupt and schedule for handling */ |
107 | omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | 119 | omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 5c8a1bcf7ca7..cea70e6a1031 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c | |||
@@ -219,6 +219,8 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) | |||
219 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); | 219 | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); |
220 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); | 220 | iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); |
221 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); | 221 | iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); |
222 | |||
223 | device_init_wakeup(&pdev->dev, 1); | ||
222 | return 0; | 224 | return 0; |
223 | err5: | 225 | err5: |
224 | free_irq(irq, pdev); | 226 | free_irq(irq, pdev); |
@@ -253,17 +255,48 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) | |||
253 | return 0; | 255 | return 0; |
254 | } | 256 | } |
255 | 257 | ||
258 | static int sh_keysc_suspend(struct device *dev) | ||
259 | { | ||
260 | struct platform_device *pdev = to_platform_device(dev); | ||
261 | struct sh_keysc_priv *priv = platform_get_drvdata(pdev); | ||
262 | int irq = platform_get_irq(pdev, 0); | ||
263 | unsigned short value; | ||
264 | |||
265 | value = ioread16(priv->iomem_base + KYCR1_OFFS); | ||
266 | |||
267 | if (device_may_wakeup(dev)) { | ||
268 | value |= 0x80; | ||
269 | enable_irq_wake(irq); | ||
270 | } | ||
271 | else | ||
272 | value &= ~0x80; | ||
273 | |||
274 | iowrite16(value, priv->iomem_base + KYCR1_OFFS); | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int sh_keysc_resume(struct device *dev) | ||
279 | { | ||
280 | struct platform_device *pdev = to_platform_device(dev); | ||
281 | int irq = platform_get_irq(pdev, 0); | ||
282 | |||
283 | if (device_may_wakeup(dev)) | ||
284 | disable_irq_wake(irq); | ||
256 | 285 | ||
257 | #define sh_keysc_suspend NULL | 286 | return 0; |
258 | #define sh_keysc_resume NULL | 287 | } |
288 | |||
289 | static struct dev_pm_ops sh_keysc_dev_pm_ops = { | ||
290 | .suspend = sh_keysc_suspend, | ||
291 | .resume = sh_keysc_resume, | ||
292 | }; | ||
259 | 293 | ||
260 | struct platform_driver sh_keysc_device_driver = { | 294 | struct platform_driver sh_keysc_device_driver = { |
261 | .probe = sh_keysc_probe, | 295 | .probe = sh_keysc_probe, |
262 | .remove = __devexit_p(sh_keysc_remove), | 296 | .remove = __devexit_p(sh_keysc_remove), |
263 | .suspend = sh_keysc_suspend, | ||
264 | .resume = sh_keysc_resume, | ||
265 | .driver = { | 297 | .driver = { |
266 | .name = "sh_keysc", | 298 | .name = "sh_keysc", |
299 | .pm = &sh_keysc_dev_pm_ops, | ||
267 | } | 300 | } |
268 | }; | 301 | }; |
269 | 302 | ||
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c index 9d1781a618e9..13967422658c 100644 --- a/drivers/input/keyboard/spitzkbd.c +++ b/drivers/input/keyboard/spitzkbd.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | 22 | ||
23 | #include <mach/spitz.h> | 23 | #include <mach/spitz.h> |
24 | #include <mach/hardware.h> | ||
25 | #include <mach/pxa-regs.h> | ||
26 | #include <mach/pxa2xx-gpio.h> | 24 | #include <mach/pxa2xx-gpio.h> |
27 | 25 | ||
28 | #define KB_ROWS 7 | 26 | #define KB_ROWS 7 |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 2a92e19c1509..c66cc3d08c2f 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -17,7 +17,7 @@ config MOUSE_PS2 | |||
17 | default y | 17 | default y |
18 | select SERIO | 18 | select SERIO |
19 | select SERIO_LIBPS2 | 19 | select SERIO_LIBPS2 |
20 | select SERIO_I8042 if X86_PC | 20 | select SERIO_I8042 if X86 |
21 | select SERIO_GSCPS2 if GSC | 21 | select SERIO_GSCPS2 if GSC |
22 | help | 22 | help |
23 | Say Y here if you have a PS/2 mouse connected to your system. This | 23 | Say Y here if you have a PS/2 mouse connected to your system. This |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index cbedf957cc58..daecc75c72e6 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #define ALPS_FW_BK_2 0x40 | 37 | #define ALPS_FW_BK_2 0x40 |
38 | 38 | ||
39 | static const struct alps_model_info alps_model_data[] = { | 39 | static const struct alps_model_info alps_model_data[] = { |
40 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | ||
40 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ | 41 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ |
41 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 42 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
42 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 43 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 454b96112f03..e0140fdc02a5 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
@@ -255,15 +255,22 @@ MODULE_PARM_DESC(debug, "Activate debugging output"); | |||
255 | */ | 255 | */ |
256 | static int atp_geyser_init(struct usb_device *udev) | 256 | static int atp_geyser_init(struct usb_device *udev) |
257 | { | 257 | { |
258 | char data[8]; | 258 | char *data; |
259 | int size; | 259 | int size; |
260 | int i; | 260 | int i; |
261 | int ret; | ||
262 | |||
263 | data = kmalloc(8, GFP_KERNEL); | ||
264 | if (!data) { | ||
265 | err("Out of memory"); | ||
266 | return -ENOMEM; | ||
267 | } | ||
261 | 268 | ||
262 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 269 | size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
263 | ATP_GEYSER_MODE_READ_REQUEST_ID, | 270 | ATP_GEYSER_MODE_READ_REQUEST_ID, |
264 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 271 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
265 | ATP_GEYSER_MODE_REQUEST_VALUE, | 272 | ATP_GEYSER_MODE_REQUEST_VALUE, |
266 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); | 273 | ATP_GEYSER_MODE_REQUEST_INDEX, data, 8, 5000); |
267 | 274 | ||
268 | if (size != 8) { | 275 | if (size != 8) { |
269 | dprintk("atp_geyser_init: read error\n"); | 276 | dprintk("atp_geyser_init: read error\n"); |
@@ -271,7 +278,8 @@ static int atp_geyser_init(struct usb_device *udev) | |||
271 | dprintk("appletouch[%d]: %d\n", i, data[i]); | 278 | dprintk("appletouch[%d]: %d\n", i, data[i]); |
272 | 279 | ||
273 | err("Failed to read mode from device."); | 280 | err("Failed to read mode from device."); |
274 | return -EIO; | 281 | ret = -EIO; |
282 | goto out_free; | ||
275 | } | 283 | } |
276 | 284 | ||
277 | /* Apply the mode switch */ | 285 | /* Apply the mode switch */ |
@@ -281,7 +289,7 @@ static int atp_geyser_init(struct usb_device *udev) | |||
281 | ATP_GEYSER_MODE_WRITE_REQUEST_ID, | 289 | ATP_GEYSER_MODE_WRITE_REQUEST_ID, |
282 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 290 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
283 | ATP_GEYSER_MODE_REQUEST_VALUE, | 291 | ATP_GEYSER_MODE_REQUEST_VALUE, |
284 | ATP_GEYSER_MODE_REQUEST_INDEX, &data, 8, 5000); | 292 | ATP_GEYSER_MODE_REQUEST_INDEX, data, 8, 5000); |
285 | 293 | ||
286 | if (size != 8) { | 294 | if (size != 8) { |
287 | dprintk("atp_geyser_init: write error\n"); | 295 | dprintk("atp_geyser_init: write error\n"); |
@@ -289,9 +297,13 @@ static int atp_geyser_init(struct usb_device *udev) | |||
289 | dprintk("appletouch[%d]: %d\n", i, data[i]); | 297 | dprintk("appletouch[%d]: %d\n", i, data[i]); |
290 | 298 | ||
291 | err("Failed to request geyser raw mode"); | 299 | err("Failed to request geyser raw mode"); |
292 | return -EIO; | 300 | ret = -EIO; |
301 | goto out_free; | ||
293 | } | 302 | } |
294 | return 0; | 303 | ret = 0; |
304 | out_free: | ||
305 | kfree(data); | ||
306 | return ret; | ||
295 | } | 307 | } |
296 | 308 | ||
297 | /* | 309 | /* |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2998a6ac9ae4..2d8fc0bf6923 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -51,6 +51,10 @@ | |||
51 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | 51 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 |
52 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | 52 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 |
53 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | 53 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 |
54 | /* Macbook5,1 (unibody), aka wellspring3 */ | ||
55 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | ||
56 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | ||
57 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | ||
54 | 58 | ||
55 | #define BCM5974_DEVICE(prod) { \ | 59 | #define BCM5974_DEVICE(prod) { \ |
56 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 60 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
@@ -72,6 +76,10 @@ static const struct usb_device_id bcm5974_table[] = { | |||
72 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), | 76 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), |
73 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), | 77 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), |
74 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), | 78 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), |
79 | /* Macbook5,1 */ | ||
80 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), | ||
81 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), | ||
82 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | ||
75 | /* Terminating entry */ | 83 | /* Terminating entry */ |
76 | {} | 84 | {} |
77 | }; | 85 | }; |
@@ -96,14 +104,23 @@ struct bt_data { | |||
96 | u8 rel_y; /* relative y coordinate */ | 104 | u8 rel_y; /* relative y coordinate */ |
97 | }; | 105 | }; |
98 | 106 | ||
99 | /* trackpad header structure */ | 107 | /* trackpad header types */ |
100 | struct tp_header { | 108 | enum tp_type { |
101 | u8 unknown1[16]; /* constants, timers, etc */ | 109 | TYPE1, /* plain trackpad */ |
102 | u8 fingers; /* number of fingers on trackpad */ | 110 | TYPE2 /* button integrated in trackpad */ |
103 | u8 unknown2[9]; /* constants, timers, etc */ | ||
104 | }; | 111 | }; |
105 | 112 | ||
106 | /* trackpad finger structure */ | 113 | /* trackpad finger data offsets, le16-aligned */ |
114 | #define FINGER_TYPE1 (13 * sizeof(__le16)) | ||
115 | #define FINGER_TYPE2 (15 * sizeof(__le16)) | ||
116 | |||
117 | /* trackpad button data offsets */ | ||
118 | #define BUTTON_TYPE2 15 | ||
119 | |||
120 | /* list of device capability bits */ | ||
121 | #define HAS_INTEGRATED_BUTTON 1 | ||
122 | |||
123 | /* trackpad finger structure, le16-aligned */ | ||
107 | struct tp_finger { | 124 | struct tp_finger { |
108 | __le16 origin; /* zero when switching track finger */ | 125 | __le16 origin; /* zero when switching track finger */ |
109 | __le16 abs_x; /* absolute x coodinate */ | 126 | __le16 abs_x; /* absolute x coodinate */ |
@@ -117,13 +134,11 @@ struct tp_finger { | |||
117 | __le16 force_minor; /* trackpad force, minor axis? */ | 134 | __le16 force_minor; /* trackpad force, minor axis? */ |
118 | __le16 unused[3]; /* zeros */ | 135 | __le16 unused[3]; /* zeros */ |
119 | __le16 multi; /* one finger: varies, more fingers: constant */ | 136 | __le16 multi; /* one finger: varies, more fingers: constant */ |
120 | }; | 137 | } __attribute__((packed,aligned(2))); |
121 | 138 | ||
122 | /* trackpad data structure, empirically at least ten fingers */ | 139 | /* trackpad finger data size, empirically at least ten fingers */ |
123 | struct tp_data { | 140 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
124 | struct tp_header header; | 141 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) |
125 | struct tp_finger finger[16]; | ||
126 | }; | ||
127 | 142 | ||
128 | /* device-specific parameters */ | 143 | /* device-specific parameters */ |
129 | struct bcm5974_param { | 144 | struct bcm5974_param { |
@@ -136,9 +151,12 @@ struct bcm5974_param { | |||
136 | /* device-specific configuration */ | 151 | /* device-specific configuration */ |
137 | struct bcm5974_config { | 152 | struct bcm5974_config { |
138 | int ansi, iso, jis; /* the product id of this device */ | 153 | int ansi, iso, jis; /* the product id of this device */ |
154 | int caps; /* device capability bitmask */ | ||
139 | int bt_ep; /* the endpoint of the button interface */ | 155 | int bt_ep; /* the endpoint of the button interface */ |
140 | int bt_datalen; /* data length of the button interface */ | 156 | int bt_datalen; /* data length of the button interface */ |
141 | int tp_ep; /* the endpoint of the trackpad interface */ | 157 | int tp_ep; /* the endpoint of the trackpad interface */ |
158 | enum tp_type tp_type; /* type of trackpad interface */ | ||
159 | int tp_offset; /* offset to trackpad finger data */ | ||
142 | int tp_datalen; /* data length of the trackpad interface */ | 160 | int tp_datalen; /* data length of the trackpad interface */ |
143 | struct bcm5974_param p; /* finger pressure limits */ | 161 | struct bcm5974_param p; /* finger pressure limits */ |
144 | struct bcm5974_param w; /* finger width limits */ | 162 | struct bcm5974_param w; /* finger width limits */ |
@@ -158,7 +176,7 @@ struct bcm5974 { | |||
158 | struct urb *bt_urb; /* button usb request block */ | 176 | struct urb *bt_urb; /* button usb request block */ |
159 | struct bt_data *bt_data; /* button transferred data */ | 177 | struct bt_data *bt_data; /* button transferred data */ |
160 | struct urb *tp_urb; /* trackpad usb request block */ | 178 | struct urb *tp_urb; /* trackpad usb request block */ |
161 | struct tp_data *tp_data; /* trackpad transferred data */ | 179 | u8 *tp_data; /* trackpad transferred data */ |
162 | int fingers; /* number of fingers on trackpad */ | 180 | int fingers; /* number of fingers on trackpad */ |
163 | }; | 181 | }; |
164 | 182 | ||
@@ -183,8 +201,9 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
183 | USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, | 201 | USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, |
184 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, | 202 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, |
185 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, | 203 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, |
204 | 0, | ||
186 | 0x84, sizeof(struct bt_data), | 205 | 0x84, sizeof(struct bt_data), |
187 | 0x81, sizeof(struct tp_data), | 206 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
188 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 207 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
189 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 208 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
190 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, | 209 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, |
@@ -194,13 +213,26 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
194 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, | 213 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, |
195 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, | 214 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, |
196 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, | 215 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, |
216 | 0, | ||
197 | 0x84, sizeof(struct bt_data), | 217 | 0x84, sizeof(struct bt_data), |
198 | 0x81, sizeof(struct tp_data), | 218 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
199 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 219 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
200 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 220 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
201 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, | 221 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, |
202 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } | 222 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } |
203 | }, | 223 | }, |
224 | { | ||
225 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, | ||
226 | USB_DEVICE_ID_APPLE_WELLSPRING3_ISO, | ||
227 | USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, | ||
228 | HAS_INTEGRATED_BUTTON, | ||
229 | 0x84, sizeof(struct bt_data), | ||
230 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
231 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | ||
232 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
233 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, | ||
234 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } | ||
235 | }, | ||
204 | {} | 236 | {} |
205 | }; | 237 | }; |
206 | 238 | ||
@@ -257,6 +289,7 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
257 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 289 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
258 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 290 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
259 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 291 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
292 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
260 | __set_bit(BTN_LEFT, input_dev->keybit); | 293 | __set_bit(BTN_LEFT, input_dev->keybit); |
261 | } | 294 | } |
262 | 295 | ||
@@ -266,6 +299,11 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
266 | if (size != sizeof(struct bt_data)) | 299 | if (size != sizeof(struct bt_data)) |
267 | return -EIO; | 300 | return -EIO; |
268 | 301 | ||
302 | dprintk(7, | ||
303 | "bcm5974: button data: %x %x %x %x\n", | ||
304 | dev->bt_data->unknown1, dev->bt_data->button, | ||
305 | dev->bt_data->rel_x, dev->bt_data->rel_y); | ||
306 | |||
269 | input_report_key(dev->input, BTN_LEFT, dev->bt_data->button); | 307 | input_report_key(dev->input, BTN_LEFT, dev->bt_data->button); |
270 | input_sync(dev->input); | 308 | input_sync(dev->input); |
271 | 309 | ||
@@ -276,29 +314,37 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
276 | static int report_tp_state(struct bcm5974 *dev, int size) | 314 | static int report_tp_state(struct bcm5974 *dev, int size) |
277 | { | 315 | { |
278 | const struct bcm5974_config *c = &dev->cfg; | 316 | const struct bcm5974_config *c = &dev->cfg; |
279 | const struct tp_finger *f = dev->tp_data->finger; | 317 | const struct tp_finger *f; |
280 | struct input_dev *input = dev->input; | 318 | struct input_dev *input = dev->input; |
281 | const int fingers = (size - 26) / 28; | 319 | int raw_p, raw_w, raw_x, raw_y, raw_n; |
282 | int raw_p, raw_w, raw_x, raw_y; | 320 | int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0; |
283 | int ptest = 0, origin = 0, nmin = 0, nmax = 0; | ||
284 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 321 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
285 | 322 | ||
286 | if (size < 26 || (size - 26) % 28 != 0) | 323 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
287 | return -EIO; | 324 | return -EIO; |
288 | 325 | ||
326 | /* finger data, le16-aligned */ | ||
327 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); | ||
328 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; | ||
329 | |||
289 | /* always track the first finger; when detached, start over */ | 330 | /* always track the first finger; when detached, start over */ |
290 | if (fingers) { | 331 | if (raw_n) { |
291 | raw_p = raw2int(f->force_major); | 332 | raw_p = raw2int(f->force_major); |
292 | raw_w = raw2int(f->size_major); | 333 | raw_w = raw2int(f->size_major); |
293 | raw_x = raw2int(f->abs_x); | 334 | raw_x = raw2int(f->abs_x); |
294 | raw_y = raw2int(f->abs_y); | 335 | raw_y = raw2int(f->abs_y); |
295 | 336 | ||
296 | dprintk(9, | 337 | dprintk(9, |
297 | "bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n", | 338 | "bcm5974: " |
298 | raw_p, raw_w, raw_x, raw_y); | 339 | "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", |
340 | raw_p, raw_w, raw_x, raw_y, raw_n); | ||
299 | 341 | ||
300 | ptest = int2bound(&c->p, raw_p); | 342 | ptest = int2bound(&c->p, raw_p); |
301 | origin = raw2int(f->origin); | 343 | origin = raw2int(f->origin); |
344 | |||
345 | /* set the integrated button if applicable */ | ||
346 | if (c->tp_type == TYPE2) | ||
347 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
302 | } | 348 | } |
303 | 349 | ||
304 | /* while tracking finger still valid, count all fingers */ | 350 | /* while tracking finger still valid, count all fingers */ |
@@ -307,12 +353,13 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
307 | abs_w = int2bound(&c->w, raw_w); | 353 | abs_w = int2bound(&c->w, raw_w); |
308 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | 354 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); |
309 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | 355 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); |
310 | for (; f != dev->tp_data->finger + fingers; f++) { | 356 | while (raw_n--) { |
311 | ptest = int2bound(&c->p, raw2int(f->force_major)); | 357 | ptest = int2bound(&c->p, raw2int(f->force_major)); |
312 | if (ptest > PRESSURE_LOW) | 358 | if (ptest > PRESSURE_LOW) |
313 | nmax++; | 359 | nmax++; |
314 | if (ptest > PRESSURE_HIGH) | 360 | if (ptest > PRESSURE_HIGH) |
315 | nmin++; | 361 | nmin++; |
362 | f++; | ||
316 | } | 363 | } |
317 | } | 364 | } |
318 | 365 | ||
@@ -324,7 +371,8 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
324 | input_report_key(input, BTN_TOUCH, dev->fingers > 0); | 371 | input_report_key(input, BTN_TOUCH, dev->fingers > 0); |
325 | input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); | 372 | input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); |
326 | input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); | 373 | input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); |
327 | input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2); | 374 | input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); |
375 | input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); | ||
328 | 376 | ||
329 | input_report_abs(input, ABS_PRESSURE, abs_p); | 377 | input_report_abs(input, ABS_PRESSURE, abs_p); |
330 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | 378 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); |
@@ -335,11 +383,15 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
335 | 383 | ||
336 | dprintk(8, | 384 | dprintk(8, |
337 | "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " | 385 | "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " |
338 | "nmin: %d nmax: %d n: %d\n", | 386 | "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, |
339 | abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers); | 387 | abs_x, abs_y, nmin, nmax, dev->fingers, ibt); |
340 | 388 | ||
341 | } | 389 | } |
342 | 390 | ||
391 | /* type 2 reports button events via ibt only */ | ||
392 | if (c->tp_type == TYPE2) | ||
393 | input_report_key(input, BTN_LEFT, ibt); | ||
394 | |||
343 | input_sync(input); | 395 | input_sync(input); |
344 | 396 | ||
345 | return 0; | 397 | return 0; |
@@ -649,6 +701,8 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
649 | input_dev->name = "bcm5974"; | 701 | input_dev->name = "bcm5974"; |
650 | input_dev->phys = dev->phys; | 702 | input_dev->phys = dev->phys; |
651 | usb_to_input_id(dev->udev, &input_dev->id); | 703 | usb_to_input_id(dev->udev, &input_dev->id); |
704 | /* report driver capabilities via the version field */ | ||
705 | input_dev->id.version = cfg->caps; | ||
652 | input_dev->dev.parent = &iface->dev; | 706 | input_dev->dev.parent = &iface->dev; |
653 | 707 | ||
654 | input_set_drvdata(input_dev, dev); | 708 | input_set_drvdata(input_dev, dev); |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 6ab0eb1ada1c..4bc78892ba91 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Elantech Touchpad driver (v5) | 2 | * Elantech Touchpad driver (v6) |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net> | 4 | * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published | 7 | * under the terms of the GNU General Public License version 2 as published |
@@ -178,6 +178,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
178 | struct elantech_data *etd = psmouse->private; | 178 | struct elantech_data *etd = psmouse->private; |
179 | unsigned char *packet = psmouse->packet; | 179 | unsigned char *packet = psmouse->packet; |
180 | int fingers; | 180 | int fingers; |
181 | static int old_fingers; | ||
181 | 182 | ||
182 | if (etd->fw_version_maj == 0x01) { | 183 | if (etd->fw_version_maj == 0x01) { |
183 | /* byte 0: D U p1 p2 1 p3 R L | 184 | /* byte 0: D U p1 p2 1 p3 R L |
@@ -190,6 +191,14 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
190 | fingers = (packet[0] & 0xc0) >> 6; | 191 | fingers = (packet[0] & 0xc0) >> 6; |
191 | } | 192 | } |
192 | 193 | ||
194 | if (etd->jumpy_cursor) { | ||
195 | /* Discard packets that are likely to have bogus coordinates */ | ||
196 | if (fingers > old_fingers) { | ||
197 | elantech_debug("elantech.c: discarding packet\n"); | ||
198 | goto discard_packet_v1; | ||
199 | } | ||
200 | } | ||
201 | |||
193 | input_report_key(dev, BTN_TOUCH, fingers != 0); | 202 | input_report_key(dev, BTN_TOUCH, fingers != 0); |
194 | 203 | ||
195 | /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 | 204 | /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 |
@@ -216,6 +225,9 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
216 | } | 225 | } |
217 | 226 | ||
218 | input_sync(dev); | 227 | input_sync(dev); |
228 | |||
229 | discard_packet_v1: | ||
230 | old_fingers = fingers; | ||
219 | } | 231 | } |
220 | 232 | ||
221 | /* | 233 | /* |
@@ -363,9 +375,14 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
363 | rc = -1; | 375 | rc = -1; |
364 | break; | 376 | break; |
365 | } | 377 | } |
378 | } | ||
379 | |||
380 | if (rc == 0) { | ||
366 | /* | 381 | /* |
367 | * Read back reg 0x10. The touchpad is probably initalising | 382 | * Read back reg 0x10. For hardware version 1 we must make |
368 | * and not ready until we read back the value we just wrote. | 383 | * sure the absolute mode bit is set. For hardware version 2 |
384 | * the touchpad is probably initalising and not ready until | ||
385 | * we read back the value we just wrote. | ||
369 | */ | 386 | */ |
370 | do { | 387 | do { |
371 | rc = elantech_read_reg(psmouse, 0x10, &val); | 388 | rc = elantech_read_reg(psmouse, 0x10, &val); |
@@ -373,12 +390,18 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
373 | break; | 390 | break; |
374 | tries--; | 391 | tries--; |
375 | elantech_debug("elantech.c: retrying read (%d).\n", | 392 | elantech_debug("elantech.c: retrying read (%d).\n", |
376 | tries); | 393 | tries); |
377 | msleep(ETP_READ_BACK_DELAY); | 394 | msleep(ETP_READ_BACK_DELAY); |
378 | } while (tries > 0); | 395 | } while (tries > 0); |
379 | if (rc) | 396 | |
397 | if (rc) { | ||
380 | pr_err("elantech.c: failed to read back register 0x10.\n"); | 398 | pr_err("elantech.c: failed to read back register 0x10.\n"); |
381 | break; | 399 | } else if (etd->hw_version == 1 && |
400 | !(val & ETP_R10_ABSOLUTE_MODE)) { | ||
401 | pr_err("elantech.c: touchpad refuses " | ||
402 | "to switch to absolute mode.\n"); | ||
403 | rc = -1; | ||
404 | } | ||
382 | } | 405 | } |
383 | 406 | ||
384 | if (rc) | 407 | if (rc) |
@@ -662,6 +685,17 @@ int elantech_init(struct psmouse *psmouse) | |||
662 | param[0], param[1], param[2]); | 685 | param[0], param[1], param[2]); |
663 | etd->capabilities = param[0]; | 686 | etd->capabilities = param[0]; |
664 | 687 | ||
688 | /* | ||
689 | * This firmware seems to suffer from misreporting coordinates when | ||
690 | * a touch action starts causing the mouse cursor or scrolled page | ||
691 | * to jump. Enable a workaround. | ||
692 | */ | ||
693 | if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) { | ||
694 | pr_info("elantech.c: firmware version 2.34 detected, " | ||
695 | "enabling jumpy cursor workaround\n"); | ||
696 | etd->jumpy_cursor = 1; | ||
697 | } | ||
698 | |||
665 | if (elantech_set_absolute_mode(psmouse)) { | 699 | if (elantech_set_absolute_mode(psmouse)) { |
666 | pr_err("elantech.c: failed to put touchpad into absolute mode.\n"); | 700 | pr_err("elantech.c: failed to put touchpad into absolute mode.\n"); |
667 | goto init_fail; | 701 | goto init_fail; |
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index bee282b540bc..ed848cc80814 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Elantech Touchpad driver (v5) | 2 | * Elantech Touchpad driver (v6) |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net> | 4 | * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published | 7 | * under the terms of the GNU General Public License version 2 as published |
@@ -104,6 +104,7 @@ struct elantech_data { | |||
104 | unsigned char fw_version_min; | 104 | unsigned char fw_version_min; |
105 | unsigned char hw_version; | 105 | unsigned char hw_version; |
106 | unsigned char paritycheck; | 106 | unsigned char paritycheck; |
107 | unsigned char jumpy_cursor; | ||
107 | unsigned char parity[256]; | 108 | unsigned char parity[256]; |
108 | }; | 109 | }; |
109 | 110 | ||
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c index 0db8d16c5edd..5e5eb88d8d1e 100644 --- a/drivers/input/mouse/gpio_mouse.c +++ b/drivers/input/mouse/gpio_mouse.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | /* | 19 | /* |
20 | * Timer function which is run every scan_ms ms when the device is opened. | 20 | * Timer function which is run every scan_ms ms when the device is opened. |
21 | * The dev input varaible is set to the the input_dev pointer. | 21 | * The dev input variable is set to the the input_dev pointer. |
22 | */ | 22 | */ |
23 | static void gpio_mouse_scan(struct input_polled_dev *dev) | 23 | static void gpio_mouse_scan(struct input_polled_dev *dev) |
24 | { | 24 | { |
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index a14a6b0f7af0..a1ad2f1a7bb3 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c | |||
@@ -381,7 +381,7 @@ static void hgpk_disconnect(struct psmouse *psmouse) | |||
381 | 381 | ||
382 | static void hgpk_recalib_work(struct work_struct *work) | 382 | static void hgpk_recalib_work(struct work_struct *work) |
383 | { | 383 | { |
384 | struct delayed_work *w = container_of(work, struct delayed_work, work); | 384 | struct delayed_work *w = to_delayed_work(work); |
385 | struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); | 385 | struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); |
386 | struct psmouse *psmouse = priv->psmouse; | 386 | struct psmouse *psmouse = priv->psmouse; |
387 | 387 | ||
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index df81b0aaa9f8..15ac3205ac05 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -61,6 +61,12 @@ static const struct dmi_system_id lifebook_dmi_table[] = { | |||
61 | }, | 61 | }, |
62 | }, | 62 | }, |
63 | { | 63 | { |
64 | .ident = "Lifebook B-2130", | ||
65 | .matches = { | ||
66 | DMI_MATCH(DMI_BOARD_NAME, "ZEPHYR"), | ||
67 | }, | ||
68 | }, | ||
69 | { | ||
64 | .ident = "Lifebook B213x/B2150", | 70 | .ident = "Lifebook B213x/B2150", |
65 | .matches = { | 71 | .matches = { |
66 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), | 72 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"), |
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index d196abfb68bc..5f278176eb9b 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * SEGA Dreamcast mouse driver | 2 | * SEGA Dreamcast mouse driver |
3 | * Based on drivers/usb/usbmouse.c | 3 | * Based on drivers/usb/usbmouse.c |
4 | * | 4 | * |
5 | * Copyright Yaegashi Takeshi, 2001 | 5 | * Copyright (c) Yaegashi Takeshi, 2001 |
6 | * Adrian McMenamin, 2008 | 6 | * Copyright (c) Adrian McMenamin, 2008 - 2009 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
@@ -29,7 +29,7 @@ static void dc_mouse_callback(struct mapleq *mq) | |||
29 | struct maple_device *mapledev = mq->dev; | 29 | struct maple_device *mapledev = mq->dev; |
30 | struct dc_mouse *mse = maple_get_drvdata(mapledev); | 30 | struct dc_mouse *mse = maple_get_drvdata(mapledev); |
31 | struct input_dev *dev = mse->dev; | 31 | struct input_dev *dev = mse->dev; |
32 | unsigned char *res = mq->recvbuf; | 32 | unsigned char *res = mq->recvbuf->buf; |
33 | 33 | ||
34 | buttons = ~res[8]; | 34 | buttons = ~res[8]; |
35 | relx = *(unsigned short *)(res + 12) - 512; | 35 | relx = *(unsigned short *)(res + 12) - 512; |
@@ -47,7 +47,7 @@ static void dc_mouse_callback(struct mapleq *mq) | |||
47 | 47 | ||
48 | static int dc_mouse_open(struct input_dev *dev) | 48 | static int dc_mouse_open(struct input_dev *dev) |
49 | { | 49 | { |
50 | struct dc_mouse *mse = dev->dev.platform_data; | 50 | struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev)); |
51 | 51 | ||
52 | maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50, | 52 | maple_getcond_callback(mse->mdev, dc_mouse_callback, HZ/50, |
53 | MAPLE_FUNC_MOUSE); | 53 | MAPLE_FUNC_MOUSE); |
@@ -57,29 +57,33 @@ static int dc_mouse_open(struct input_dev *dev) | |||
57 | 57 | ||
58 | static void dc_mouse_close(struct input_dev *dev) | 58 | static void dc_mouse_close(struct input_dev *dev) |
59 | { | 59 | { |
60 | struct dc_mouse *mse = dev->dev.platform_data; | 60 | struct dc_mouse *mse = maple_get_drvdata(to_maple_dev(&dev->dev)); |
61 | 61 | ||
62 | maple_getcond_callback(mse->mdev, dc_mouse_callback, 0, | 62 | maple_getcond_callback(mse->mdev, dc_mouse_callback, 0, |
63 | MAPLE_FUNC_MOUSE); | 63 | MAPLE_FUNC_MOUSE); |
64 | } | 64 | } |
65 | 65 | ||
66 | 66 | /* allow the mouse to be used */ | |
67 | static int __devinit probe_maple_mouse(struct device *dev) | 67 | static int __devinit probe_maple_mouse(struct device *dev) |
68 | { | 68 | { |
69 | struct maple_device *mdev = to_maple_dev(dev); | 69 | struct maple_device *mdev = to_maple_dev(dev); |
70 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | 70 | struct maple_driver *mdrv = to_maple_driver(dev->driver); |
71 | int error; | ||
71 | struct input_dev *input_dev; | 72 | struct input_dev *input_dev; |
72 | struct dc_mouse *mse; | 73 | struct dc_mouse *mse; |
73 | int error; | ||
74 | 74 | ||
75 | mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL); | 75 | mse = kzalloc(sizeof(struct dc_mouse), GFP_KERNEL); |
76 | input_dev = input_allocate_device(); | 76 | if (!mse) { |
77 | |||
78 | if (!mse || !input_dev) { | ||
79 | error = -ENOMEM; | 77 | error = -ENOMEM; |
80 | goto fail; | 78 | goto fail; |
81 | } | 79 | } |
82 | 80 | ||
81 | input_dev = input_allocate_device(); | ||
82 | if (!input_dev) { | ||
83 | error = -ENOMEM; | ||
84 | goto fail_nomem; | ||
85 | } | ||
86 | |||
83 | mse->dev = input_dev; | 87 | mse->dev = input_dev; |
84 | mse->mdev = mdev; | 88 | mse->mdev = mdev; |
85 | 89 | ||
@@ -89,25 +93,24 @@ static int __devinit probe_maple_mouse(struct device *dev) | |||
89 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | 93 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); |
90 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) | | 94 | input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) | |
91 | BIT_MASK(REL_WHEEL); | 95 | BIT_MASK(REL_WHEEL); |
92 | input_dev->name = mdev->product_name; | ||
93 | input_dev->id.bustype = BUS_HOST; | ||
94 | input_dev->open = dc_mouse_open; | 96 | input_dev->open = dc_mouse_open; |
95 | input_dev->close = dc_mouse_close; | 97 | input_dev->close = dc_mouse_close; |
98 | input_dev->name = mdev->product_name; | ||
99 | input_dev->id.bustype = BUS_HOST; | ||
100 | error = input_register_device(input_dev); | ||
101 | if (error) | ||
102 | goto fail_register; | ||
96 | 103 | ||
97 | mdev->driver = mdrv; | 104 | mdev->driver = mdrv; |
98 | maple_set_drvdata(mdev, mse); | 105 | maple_set_drvdata(mdev, mse); |
99 | 106 | ||
100 | error = input_register_device(input_dev); | 107 | return error; |
101 | if (error) | ||
102 | goto fail; | ||
103 | |||
104 | return 0; | ||
105 | 108 | ||
106 | fail: | 109 | fail_register: |
107 | input_free_device(input_dev); | 110 | input_free_device(input_dev); |
108 | maple_set_drvdata(mdev, NULL); | 111 | fail_nomem: |
109 | kfree(mse); | 112 | kfree(mse); |
110 | mdev->driver = NULL; | 113 | fail: |
111 | return error; | 114 | return error; |
112 | } | 115 | } |
113 | 116 | ||
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 56c079ef5018..272deddc8db6 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c | |||
@@ -22,10 +22,10 @@ | |||
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/io.h> | ||
25 | 26 | ||
26 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
27 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
28 | #include <asm/io.h> | ||
29 | #include <asm/hardware/iomd.h> | 29 | #include <asm/hardware/iomd.h> |
30 | 30 | ||
31 | MODULE_AUTHOR("Vojtech Pavlik, Russell King"); | 31 | MODULE_AUTHOR("Vojtech Pavlik, Russell King"); |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index ef99a7e6d40c..17fd6d46d082 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -403,12 +403,9 @@ static void mousedev_event(struct input_handle *handle, | |||
403 | 403 | ||
404 | static int mousedev_fasync(int fd, struct file *file, int on) | 404 | static int mousedev_fasync(int fd, struct file *file, int on) |
405 | { | 405 | { |
406 | int retval; | ||
407 | struct mousedev_client *client = file->private_data; | 406 | struct mousedev_client *client = file->private_data; |
408 | 407 | ||
409 | retval = fasync_helper(fd, file, on, &client->fasync); | 408 | return fasync_helper(fd, file, on, &client->fasync); |
410 | |||
411 | return retval < 0 ? retval : 0; | ||
412 | } | 409 | } |
413 | 410 | ||
414 | static void mousedev_free(struct device *dev) | 411 | static void mousedev_free(struct device *dev) |
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c index bfe49243f38b..1c9410d1822c 100644 --- a/drivers/input/serio/hp_sdc.c +++ b/drivers/input/serio/hp_sdc.c | |||
@@ -819,6 +819,7 @@ static const struct parisc_device_id hp_sdc_tbl[] = { | |||
819 | MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); | 819 | MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl); |
820 | 820 | ||
821 | static int __init hp_sdc_init_hppa(struct parisc_device *d); | 821 | static int __init hp_sdc_init_hppa(struct parisc_device *d); |
822 | static struct delayed_work moduleloader_work; | ||
822 | 823 | ||
823 | static struct parisc_driver hp_sdc_driver = { | 824 | static struct parisc_driver hp_sdc_driver = { |
824 | .name = "hp_sdc", | 825 | .name = "hp_sdc", |
@@ -930,8 +931,15 @@ static int __init hp_sdc_init(void) | |||
930 | 931 | ||
931 | #if defined(__hppa__) | 932 | #if defined(__hppa__) |
932 | 933 | ||
934 | static void request_module_delayed(struct work_struct *work) | ||
935 | { | ||
936 | request_module("hp_sdc_mlc"); | ||
937 | } | ||
938 | |||
933 | static int __init hp_sdc_init_hppa(struct parisc_device *d) | 939 | static int __init hp_sdc_init_hppa(struct parisc_device *d) |
934 | { | 940 | { |
941 | int ret; | ||
942 | |||
935 | if (!d) | 943 | if (!d) |
936 | return 1; | 944 | return 1; |
937 | if (hp_sdc.dev != NULL) | 945 | if (hp_sdc.dev != NULL) |
@@ -944,13 +952,26 @@ static int __init hp_sdc_init_hppa(struct parisc_device *d) | |||
944 | hp_sdc.data_io = d->hpa.start + 0x800; | 952 | hp_sdc.data_io = d->hpa.start + 0x800; |
945 | hp_sdc.status_io = d->hpa.start + 0x801; | 953 | hp_sdc.status_io = d->hpa.start + 0x801; |
946 | 954 | ||
947 | return hp_sdc_init(); | 955 | INIT_DELAYED_WORK(&moduleloader_work, request_module_delayed); |
956 | |||
957 | ret = hp_sdc_init(); | ||
958 | /* after sucessfull initialization give SDC some time to settle | ||
959 | * and then load the hp_sdc_mlc upper layer driver */ | ||
960 | if (!ret) | ||
961 | schedule_delayed_work(&moduleloader_work, | ||
962 | msecs_to_jiffies(2000)); | ||
963 | |||
964 | return ret; | ||
948 | } | 965 | } |
949 | 966 | ||
950 | #endif /* __hppa__ */ | 967 | #endif /* __hppa__ */ |
951 | 968 | ||
952 | static void hp_sdc_exit(void) | 969 | static void hp_sdc_exit(void) |
953 | { | 970 | { |
971 | /* do nothing if we don't have a SDC */ | ||
972 | if (!hp_sdc.dev) | ||
973 | return; | ||
974 | |||
954 | write_lock_irq(&hp_sdc.lock); | 975 | write_lock_irq(&hp_sdc.lock); |
955 | 976 | ||
956 | /* Turn off all maskable "sub-function" irq's. */ | 977 | /* Turn off all maskable "sub-function" irq's. */ |
@@ -969,6 +990,7 @@ static void hp_sdc_exit(void) | |||
969 | tasklet_kill(&hp_sdc.task); | 990 | tasklet_kill(&hp_sdc.task); |
970 | 991 | ||
971 | #if defined(__hppa__) | 992 | #if defined(__hppa__) |
993 | cancel_delayed_work_sync(&moduleloader_work); | ||
972 | if (unregister_parisc_driver(&hp_sdc_driver)) | 994 | if (unregister_parisc_driver(&hp_sdc_driver)) |
973 | printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); | 995 | printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); |
974 | #endif | 996 | #endif |
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 7f36edd34f8b..ed045c99f84b 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c | |||
@@ -33,10 +33,10 @@ | |||
33 | #include <linux/serio.h> | 33 | #include <linux/serio.h> |
34 | #include <linux/err.h> | 34 | #include <linux/err.h> |
35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
36 | #include <linux/io.h> | ||
36 | 37 | ||
37 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
38 | #include <mach/hardware.h> | 39 | #include <mach/hardware.h> |
39 | #include <asm/io.h> | ||
40 | #include <asm/hardware/iomd.h> | 40 | #include <asm/hardware/iomd.h> |
41 | #include <asm/system.h> | 41 | #include <asm/system.h> |
42 | 42 | ||
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 57953c0eb82f..f412c69478a8 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c | |||
@@ -77,7 +77,7 @@ static irqreturn_t ps2_txint(int irq, void *dev_id) | |||
77 | spin_lock(&ps2if->lock); | 77 | spin_lock(&ps2if->lock); |
78 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); | 78 | status = sa1111_readl(ps2if->base + SA1111_PS2STAT); |
79 | if (ps2if->head == ps2if->tail) { | 79 | if (ps2if->head == ps2if->tail) { |
80 | disable_irq(irq); | 80 | disable_irq_nosync(irq); |
81 | /* done */ | 81 | /* done */ |
82 | } else if (status & PS2STAT_TXE) { | 82 | } else if (status & PS2STAT_TXE) { |
83 | sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); | 83 | sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 06bbd0e74c6f..b03009bb7468 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -58,10 +58,8 @@ static unsigned int serio_raw_no; | |||
58 | static int serio_raw_fasync(int fd, struct file *file, int on) | 58 | static int serio_raw_fasync(int fd, struct file *file, int on) |
59 | { | 59 | { |
60 | struct serio_raw_list *list = file->private_data; | 60 | struct serio_raw_list *list = file->private_data; |
61 | int retval; | ||
62 | 61 | ||
63 | retval = fasync_helper(fd, file, on, &list->fasync); | 62 | return fasync_helper(fd, file, on, &list->fasync); |
64 | return retval < 0 ? retval : 0; | ||
65 | } | 63 | } |
66 | 64 | ||
67 | static struct serio_raw *serio_raw_locate(int minor) | 65 | static struct serio_raw *serio_raw_locate(int minor) |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 677680e9f54f..9710bfd49cf9 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -11,7 +11,7 @@ | |||
11 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> | 11 | * Copyright (c) 2000 Daniel Egger <egger@suse.de> |
12 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> | 12 | * Copyright (c) 2001 Frederic Lepied <flepied@mandrakesoft.com> |
13 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> | 13 | * Copyright (c) 2004 Panagiotis Issaris <panagiotis.issaris@mech.kuleuven.ac.be> |
14 | * Copyright (c) 2002-2008 Ping Cheng <pingc@wacom.com> | 14 | * Copyright (c) 2002-2009 Ping Cheng <pingc@wacom.com> |
15 | * | 15 | * |
16 | * ChangeLog: | 16 | * ChangeLog: |
17 | * v0.1 (vp) - Initial release | 17 | * v0.1 (vp) - Initial release |
@@ -67,6 +67,7 @@ | |||
67 | * v1.47 (pc) - Added support for Bamboo | 67 | * v1.47 (pc) - Added support for Bamboo |
68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX | 68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX |
69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) | 69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) |
70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 | ||
70 | */ | 71 | */ |
71 | 72 | ||
72 | /* | 73 | /* |
@@ -87,7 +88,7 @@ | |||
87 | /* | 88 | /* |
88 | * Version Information | 89 | * Version Information |
89 | */ | 90 | */ |
90 | #define DRIVER_VERSION "v1.49" | 91 | #define DRIVER_VERSION "v1.50" |
91 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 92 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
92 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 93 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
93 | #define DRIVER_LICENSE "GPL" | 94 | #define DRIVER_LICENSE "GPL" |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 484496daa0f3..b8624f27abf9 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -289,6 +289,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
289 | 5000); /* 5 secs */ | 289 | 5000); /* 5 secs */ |
290 | } while (result < 0 && limit++ < 5); | 290 | } while (result < 0 && limit++ < 5); |
291 | 291 | ||
292 | /* No need to parse the Descriptor. It isn't an error though */ | ||
292 | if (result < 0) | 293 | if (result < 0) |
293 | goto out; | 294 | goto out; |
294 | 295 | ||
@@ -368,9 +369,8 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
368 | } | 369 | } |
369 | } | 370 | } |
370 | 371 | ||
371 | result = 0; | ||
372 | |||
373 | out: | 372 | out: |
373 | result = 0; | ||
374 | kfree(report); | 374 | kfree(report); |
375 | return result; | 375 | return result; |
376 | } | 376 | } |
@@ -425,6 +425,15 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
425 | 425 | ||
426 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 426 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
427 | 427 | ||
428 | /* Initialize touch_x_max and touch_y_max in case it is not defined */ | ||
429 | if (wacom_wac->features->type == TABLETPC) { | ||
430 | features->touch_x_max = 1023; | ||
431 | features->touch_y_max = 1023; | ||
432 | } else { | ||
433 | features->touch_x_max = 0; | ||
434 | features->touch_y_max = 0; | ||
435 | } | ||
436 | |||
428 | /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ | 437 | /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ |
429 | if (wacom_wac->features->type == TABLETPC) { | 438 | if (wacom_wac->features->type == TABLETPC) { |
430 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | 439 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { |
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 8b6e30ac2919..2b01e56568f8 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
@@ -297,7 +297,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ | |||
297 | static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); | 297 | static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); |
298 | 298 | ||
299 | 299 | ||
300 | /* Sysfs conventions report temperatures in millidegrees Celcius. | 300 | /* Sysfs conventions report temperatures in millidegrees Celsius. |
301 | * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high | 301 | * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high |
302 | * accuracy scheme without calibration data. For now we won't try either; | 302 | * accuracy scheme without calibration data. For now we won't try either; |
303 | * userspace sees raw sensor values, and must scale/calibrate appropriately. | 303 | * userspace sees raw sensor values, and must scale/calibrate appropriately. |
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 3fb51b54fe61..94a1919d439d 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <mach/sharpsl.h> | 22 | #include <mach/sharpsl.h> |
23 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
24 | #include <mach/pxa-regs.h> | ||
25 | #include <mach/pxa2xx-gpio.h> | 24 | #include <mach/pxa2xx-gpio.h> |
26 | 25 | ||
27 | 26 | ||
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index 504ca11749a1..141dd584330e 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c | |||
@@ -198,6 +198,7 @@ static int migor_ts_probe(struct i2c_client *client, | |||
198 | goto err2; | 198 | goto err2; |
199 | } | 199 | } |
200 | 200 | ||
201 | device_init_wakeup(&client->dev, 1); | ||
201 | return 0; | 202 | return 0; |
202 | 203 | ||
203 | err2: | 204 | err2: |
@@ -224,6 +225,26 @@ static int migor_ts_remove(struct i2c_client *client) | |||
224 | return 0; | 225 | return 0; |
225 | } | 226 | } |
226 | 227 | ||
228 | static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) | ||
229 | { | ||
230 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | ||
231 | |||
232 | if (device_may_wakeup(&client->dev)) | ||
233 | enable_irq_wake(priv->irq); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int migor_ts_resume(struct i2c_client *client) | ||
239 | { | ||
240 | struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); | ||
241 | |||
242 | if (device_may_wakeup(&client->dev)) | ||
243 | disable_irq_wake(priv->irq); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
227 | static const struct i2c_device_id migor_ts_id[] = { | 248 | static const struct i2c_device_id migor_ts_id[] = { |
228 | { "migor_ts", 0 }, | 249 | { "migor_ts", 0 }, |
229 | { } | 250 | { } |
@@ -236,6 +257,8 @@ static struct i2c_driver migor_ts_driver = { | |||
236 | }, | 257 | }, |
237 | .probe = migor_ts_probe, | 258 | .probe = migor_ts_probe, |
238 | .remove = migor_ts_remove, | 259 | .remove = migor_ts_remove, |
260 | .suspend = migor_ts_suspend, | ||
261 | .resume = migor_ts_resume, | ||
239 | .id_table = migor_ts_id, | 262 | .id_table = migor_ts_id, |
240 | }; | 263 | }; |
241 | 264 | ||
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 4ab070246892..536668fbda22 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
@@ -235,7 +235,7 @@ static irqreturn_t tsc2007_irq(int irq, void *handle) | |||
235 | spin_lock_irqsave(&ts->lock, flags); | 235 | spin_lock_irqsave(&ts->lock, flags); |
236 | 236 | ||
237 | if (likely(ts->get_pendown_state())) { | 237 | if (likely(ts->get_pendown_state())) { |
238 | disable_irq(ts->irq); | 238 | disable_irq_nosync(ts->irq); |
239 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), | 239 | hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), |
240 | HRTIMER_MODE_REL); | 240 | HRTIMER_MODE_REL); |
241 | } | 241 | } |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index e868264fe799..f100c7f4c1db 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -256,7 +256,7 @@ static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid) | |||
256 | struct ucb1400_ts *ucb = devid; | 256 | struct ucb1400_ts *ucb = devid; |
257 | 257 | ||
258 | if (irqnr == ucb->irq) { | 258 | if (irqnr == ucb->irq) { |
259 | disable_irq(ucb->irq); | 259 | disable_irq_nosync(ucb->irq); |
260 | ucb->irq_pending = 1; | 260 | ucb->irq_pending = 1; |
261 | wake_up(&ucb->ts_wait); | 261 | wake_up(&ucb->ts_wait); |
262 | return IRQ_HANDLED; | 262 | return IRQ_HANDLED; |