aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/joydev.c10
-rw-r--r--drivers/input/keyboard/amikbd.c97
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/max8925_onkey.c148
-rw-r--r--drivers/input/misc/twl4030-vibra.c2
-rw-r--r--drivers/input/misc/uinput.c4
-rw-r--r--drivers/input/mouse/amimouse.c98
-rw-r--r--drivers/input/touchscreen/Kconfig13
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ads7846.c4
-rw-r--r--drivers/input/touchscreen/s3c2410_ts.c2
-rw-r--r--drivers/input/touchscreen/tps6507x-ts.c400
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c7
14 files changed, 712 insertions, 85 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 423e0e6031a..34157bb97ed 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -47,15 +47,15 @@ struct joydev {
47 struct mutex mutex; 47 struct mutex mutex;
48 struct device dev; 48 struct device dev;
49 49
50 struct js_corr corr[ABS_MAX + 1]; 50 struct js_corr corr[ABS_CNT];
51 struct JS_DATA_SAVE_TYPE glue; 51 struct JS_DATA_SAVE_TYPE glue;
52 int nabs; 52 int nabs;
53 int nkey; 53 int nkey;
54 __u16 keymap[KEY_MAX - BTN_MISC + 1]; 54 __u16 keymap[KEY_MAX - BTN_MISC + 1];
55 __u16 keypam[KEY_MAX - BTN_MISC + 1]; 55 __u16 keypam[KEY_MAX - BTN_MISC + 1];
56 __u8 absmap[ABS_MAX + 1]; 56 __u8 absmap[ABS_CNT];
57 __u8 abspam[ABS_MAX + 1]; 57 __u8 abspam[ABS_CNT];
58 __s16 abs[ABS_MAX + 1]; 58 __s16 abs[ABS_CNT];
59}; 59};
60 60
61struct joydev_client { 61struct joydev_client {
@@ -826,7 +826,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
826 joydev->handle.handler = handler; 826 joydev->handle.handler = handler;
827 joydev->handle.private = joydev; 827 joydev->handle.private = joydev;
828 828
829 for (i = 0; i < ABS_MAX + 1; i++) 829 for (i = 0; i < ABS_CNT; i++)
830 if (test_bit(i, dev->absbit)) { 830 if (test_bit(i, dev->absbit)) {
831 joydev->absmap[i] = joydev->nabs; 831 joydev->absmap[i] = joydev->nabs;
832 joydev->abspam[joydev->nabs] = i; 832 joydev->abspam[joydev->nabs] = i;
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 35149ec455a..79172af164f 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -35,6 +35,7 @@
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/keyboard.h> 37#include <linux/keyboard.h>
38#include <linux/platform_device.h>
38 39
39#include <asm/amigaints.h> 40#include <asm/amigaints.h>
40#include <asm/amigahw.h> 41#include <asm/amigahw.h>
@@ -154,10 +155,9 @@ static const char *amikbd_messages[8] = {
154 [7] = KERN_WARNING "amikbd: keyboard interrupt\n" 155 [7] = KERN_WARNING "amikbd: keyboard interrupt\n"
155}; 156};
156 157
157static struct input_dev *amikbd_dev; 158static irqreturn_t amikbd_interrupt(int irq, void *data)
158
159static irqreturn_t amikbd_interrupt(int irq, void *dummy)
160{ 159{
160 struct input_dev *dev = data;
161 unsigned char scancode, down; 161 unsigned char scancode, down;
162 162
163 scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */ 163 scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */
@@ -170,47 +170,42 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy)
170 170
171 if (scancode < 0x78) { /* scancodes < 0x78 are keys */ 171 if (scancode < 0x78) { /* scancodes < 0x78 are keys */
172 if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */ 172 if (scancode == 98) { /* CapsLock is a toggle switch key on Amiga */
173 input_report_key(amikbd_dev, scancode, 1); 173 input_report_key(dev, scancode, 1);
174 input_report_key(amikbd_dev, scancode, 0); 174 input_report_key(dev, scancode, 0);
175 } else { 175 } else {
176 input_report_key(amikbd_dev, scancode, down); 176 input_report_key(dev, scancode, down);
177 } 177 }
178 178
179 input_sync(amikbd_dev); 179 input_sync(dev);
180 } else /* scancodes >= 0x78 are error codes */ 180 } else /* scancodes >= 0x78 are error codes */
181 printk(amikbd_messages[scancode - 0x78]); 181 printk(amikbd_messages[scancode - 0x78]);
182 182
183 return IRQ_HANDLED; 183 return IRQ_HANDLED;
184} 184}
185 185
186static int __init amikbd_init(void) 186static int __init amikbd_probe(struct platform_device *pdev)
187{ 187{
188 struct input_dev *dev;
188 int i, j, err; 189 int i, j, err;
189 190
190 if (!AMIGAHW_PRESENT(AMI_KEYBOARD)) 191 dev = input_allocate_device();
191 return -ENODEV; 192 if (!dev) {
192 193 dev_err(&pdev->dev, "Not enough memory for input device\n");
193 if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb")) 194 return -ENOMEM;
194 return -EBUSY;
195
196 amikbd_dev = input_allocate_device();
197 if (!amikbd_dev) {
198 printk(KERN_ERR "amikbd: not enough memory for input device\n");
199 err = -ENOMEM;
200 goto fail1;
201 } 195 }
202 196
203 amikbd_dev->name = "Amiga Keyboard"; 197 dev->name = pdev->name;
204 amikbd_dev->phys = "amikbd/input0"; 198 dev->phys = "amikbd/input0";
205 amikbd_dev->id.bustype = BUS_AMIGA; 199 dev->id.bustype = BUS_AMIGA;
206 amikbd_dev->id.vendor = 0x0001; 200 dev->id.vendor = 0x0001;
207 amikbd_dev->id.product = 0x0001; 201 dev->id.product = 0x0001;
208 amikbd_dev->id.version = 0x0100; 202 dev->id.version = 0x0100;
203 dev->dev.parent = &pdev->dev;
209 204
210 amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); 205 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
211 206
212 for (i = 0; i < 0x78; i++) 207 for (i = 0; i < 0x78; i++)
213 set_bit(i, amikbd_dev->keybit); 208 set_bit(i, dev->keybit);
214 209
215 for (i = 0; i < MAX_NR_KEYMAPS; i++) { 210 for (i = 0; i < MAX_NR_KEYMAPS; i++) {
216 static u_short temp_map[NR_KEYS] __initdata; 211 static u_short temp_map[NR_KEYS] __initdata;
@@ -229,30 +224,54 @@ static int __init amikbd_init(void)
229 memcpy(key_maps[i], temp_map, sizeof(temp_map)); 224 memcpy(key_maps[i], temp_map, sizeof(temp_map));
230 } 225 }
231 ciaa.cra &= ~0x41; /* serial data in, turn off TA */ 226 ciaa.cra &= ~0x41; /* serial data in, turn off TA */
232 if (request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", 227 err = request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd",
233 amikbd_interrupt)) { 228 dev);
234 err = -EBUSY; 229 if (err)
235 goto fail2; 230 goto fail2;
236 }
237 231
238 err = input_register_device(amikbd_dev); 232 err = input_register_device(dev);
239 if (err) 233 if (err)
240 goto fail3; 234 goto fail3;
241 235
236 platform_set_drvdata(pdev, dev);
237
242 return 0; 238 return 0;
243 239
244 fail3: free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); 240 fail3: free_irq(IRQ_AMIGA_CIAA_SP, dev);
245 fail2: input_free_device(amikbd_dev); 241 fail2: input_free_device(dev);
246 fail1: release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
247 return err; 242 return err;
248} 243}
249 244
250static void __exit amikbd_exit(void) 245static int __exit amikbd_remove(struct platform_device *pdev)
246{
247 struct input_dev *dev = platform_get_drvdata(pdev);
248
249 platform_set_drvdata(pdev, NULL);
250 free_irq(IRQ_AMIGA_CIAA_SP, dev);
251 input_unregister_device(dev);
252 return 0;
253}
254
255static struct platform_driver amikbd_driver = {
256 .remove = __exit_p(amikbd_remove),
257 .driver = {
258 .name = "amiga-keyboard",
259 .owner = THIS_MODULE,
260 },
261};
262
263static int __init amikbd_init(void)
251{ 264{
252 free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt); 265 return platform_driver_probe(&amikbd_driver, amikbd_probe);
253 input_unregister_device(amikbd_dev);
254 release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
255} 266}
256 267
257module_init(amikbd_init); 268module_init(amikbd_init);
269
270static void __exit amikbd_exit(void)
271{
272 platform_driver_unregister(&amikbd_driver);
273}
274
258module_exit(amikbd_exit); 275module_exit(amikbd_exit);
276
277MODULE_ALIAS("platform:amiga-keyboard");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 48cdabec372..c44b9eafc55 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -80,6 +80,16 @@ config INPUT_M68K_BEEP
80 tristate "M68k Beeper support" 80 tristate "M68k Beeper support"
81 depends on M68K 81 depends on M68K
82 82
83config INPUT_MAX8925_ONKEY
84 tristate "MAX8925 ONKEY support"
85 depends on MFD_MAX8925
86 help
87 Support the ONKEY of MAX8925 PMICs as an input device
88 reporting power button status.
89
90 To compile this driver as a module, choose M here: the module
91 will be called max8925_onkey.
92
83config INPUT_APANEL 93config INPUT_APANEL
84 tristate "Fujitsu Lifebook Application Panel buttons" 94 tristate "Fujitsu Lifebook Application Panel buttons"
85 depends on X86 && I2C && LEDS_CLASS 95 depends on X86 && I2C && LEDS_CLASS
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index f9f577031e0..71fe57d8023 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
20obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o 20obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
21obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o 21obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
22obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o 22obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
23obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
23obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o 24obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
24obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o 25obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
25obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o 26obj-$(CONFIG_INPUT_PCF8574) += pcf8574_keypad.o
diff --git a/drivers/input/misc/max8925_onkey.c b/drivers/input/misc/max8925_onkey.c
new file mode 100644
index 00000000000..80af4460801
--- /dev/null
+++ b/drivers/input/misc/max8925_onkey.c
@@ -0,0 +1,148 @@
1/**
2 * max8925_onkey.c - MAX8925 ONKEY driver
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General
8 * Public License. See the file "COPYING" in the main directory of this
9 * archive for more details.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <linux/i2c.h>
25#include <linux/input.h>
26#include <linux/interrupt.h>
27#include <linux/mfd/max8925.h>
28#include <linux/slab.h>
29
30#define HARDRESET_EN (1 << 7)
31#define PWREN_EN (1 << 7)
32
33struct max8925_onkey_info {
34 struct input_dev *idev;
35 struct i2c_client *i2c;
36 int irq;
37};
38
39/*
40 * MAX8925 gives us an interrupt when ONKEY is held for 3 seconds.
41 * max8925_set_bits() operates I2C bus and may sleep. So implement
42 * it in thread IRQ handler.
43 */
44static irqreturn_t max8925_onkey_handler(int irq, void *data)
45{
46 struct max8925_onkey_info *info = data;
47
48 input_report_key(info->idev, KEY_POWER, 1);
49 input_sync(info->idev);
50
51 /* Enable hardreset to halt if system isn't shutdown on time */
52 max8925_set_bits(info->i2c, MAX8925_SYSENSEL,
53 HARDRESET_EN, HARDRESET_EN);
54
55 return IRQ_HANDLED;
56}
57
58static int __devinit max8925_onkey_probe(struct platform_device *pdev)
59{
60 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
61 struct max8925_onkey_info *info;
62 int error;
63
64 info = kzalloc(sizeof(struct max8925_onkey_info), GFP_KERNEL);
65 if (!info)
66 return -ENOMEM;
67
68 info->i2c = chip->i2c;
69 info->irq = chip->irq_base + MAX8925_IRQ_GPM_SW_3SEC;
70
71 info->idev = input_allocate_device();
72 if (!info->idev) {
73 dev_err(chip->dev, "Failed to allocate input dev\n");
74 error = -ENOMEM;
75 goto out_input;
76 }
77
78 info->idev->name = "max8925_on";
79 info->idev->phys = "max8925_on/input0";
80 info->idev->id.bustype = BUS_I2C;
81 info->idev->dev.parent = &pdev->dev;
82 info->idev->evbit[0] = BIT_MASK(EV_KEY);
83 info->idev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
84
85 error = request_threaded_irq(info->irq, NULL, max8925_onkey_handler,
86 IRQF_ONESHOT, "onkey", info);
87 if (error < 0) {
88 dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
89 info->irq, error);
90 goto out_irq;
91 }
92
93 error = input_register_device(info->idev);
94 if (error) {
95 dev_err(chip->dev, "Can't register input device: %d\n", error);
96 goto out;
97 }
98
99 platform_set_drvdata(pdev, info);
100
101 return 0;
102
103out:
104 free_irq(info->irq, info);
105out_irq:
106 input_free_device(info->idev);
107out_input:
108 kfree(info);
109 return error;
110}
111
112static int __devexit max8925_onkey_remove(struct platform_device *pdev)
113{
114 struct max8925_onkey_info *info = platform_get_drvdata(pdev);
115
116 free_irq(info->irq, info);
117 input_unregister_device(info->idev);
118 kfree(info);
119
120 platform_set_drvdata(pdev, NULL);
121
122 return 0;
123}
124
125static struct platform_driver max8925_onkey_driver = {
126 .driver = {
127 .name = "max8925-onkey",
128 .owner = THIS_MODULE,
129 },
130 .probe = max8925_onkey_probe,
131 .remove = __devexit_p(max8925_onkey_remove),
132};
133
134static int __init max8925_onkey_init(void)
135{
136 return platform_driver_register(&max8925_onkey_driver);
137}
138module_init(max8925_onkey_init);
139
140static void __exit max8925_onkey_exit(void)
141{
142 platform_driver_unregister(&max8925_onkey_driver);
143}
144module_exit(max8925_onkey_exit);
145
146MODULE_DESCRIPTION("Maxim MAX8925 ONKEY driver");
147MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
148MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index fee9eac8e04..4f9b2afc24e 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -90,8 +90,8 @@ static void vibra_disable(struct vibra_info *info)
90 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 90 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
91 (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL); 91 (reg & ~TWL4030_VIBRA_EN), TWL4030_REG_VIBRA_CTL);
92 92
93 twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
94 twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL); 93 twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
94 twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
95 95
96 info->enabled = false; 96 info->enabled = false;
97} 97}
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 1477466076a..b71eb55f2db 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -300,7 +300,7 @@ static int uinput_validate_absbits(struct input_dev *dev)
300 unsigned int cnt; 300 unsigned int cnt;
301 int retval = 0; 301 int retval = 0;
302 302
303 for (cnt = 0; cnt < ABS_MAX + 1; cnt++) { 303 for (cnt = 0; cnt < ABS_CNT; cnt++) {
304 if (!test_bit(cnt, dev->absbit)) 304 if (!test_bit(cnt, dev->absbit))
305 continue; 305 continue;
306 306
@@ -387,7 +387,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
387 dev->id.product = user_dev->id.product; 387 dev->id.product = user_dev->id.product;
388 dev->id.version = user_dev->id.version; 388 dev->id.version = user_dev->id.version;
389 389
390 size = sizeof(int) * (ABS_MAX + 1); 390 size = sizeof(int) * ABS_CNT;
391 memcpy(dev->absmax, user_dev->absmax, size); 391 memcpy(dev->absmax, user_dev->absmax, size);
392 memcpy(dev->absmin, user_dev->absmin, size); 392 memcpy(dev->absmin, user_dev->absmin, size);
393 memcpy(dev->absfuzz, user_dev->absfuzz, size); 393 memcpy(dev->absfuzz, user_dev->absfuzz, size);
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index a185ac78a42..ff5f61a0fd3 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/input.h> 22#include <linux/input.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/irq.h> 26#include <asm/irq.h>
26#include <asm/setup.h> 27#include <asm/setup.h>
@@ -34,10 +35,10 @@ MODULE_DESCRIPTION("Amiga mouse driver");
34MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
35 36
36static int amimouse_lastx, amimouse_lasty; 37static int amimouse_lastx, amimouse_lasty;
37static struct input_dev *amimouse_dev;
38 38
39static irqreturn_t amimouse_interrupt(int irq, void *dummy) 39static irqreturn_t amimouse_interrupt(int irq, void *data)
40{ 40{
41 struct input_dev *dev = data;
41 unsigned short joy0dat, potgor; 42 unsigned short joy0dat, potgor;
42 int nx, ny, dx, dy; 43 int nx, ny, dx, dy;
43 44
@@ -59,14 +60,14 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy)
59 60
60 potgor = amiga_custom.potgor; 61 potgor = amiga_custom.potgor;
61 62
62 input_report_rel(amimouse_dev, REL_X, dx); 63 input_report_rel(dev, REL_X, dx);
63 input_report_rel(amimouse_dev, REL_Y, dy); 64 input_report_rel(dev, REL_Y, dy);
64 65
65 input_report_key(amimouse_dev, BTN_LEFT, ciaa.pra & 0x40); 66 input_report_key(dev, BTN_LEFT, ciaa.pra & 0x40);
66 input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100); 67 input_report_key(dev, BTN_MIDDLE, potgor & 0x0100);
67 input_report_key(amimouse_dev, BTN_RIGHT, potgor & 0x0400); 68 input_report_key(dev, BTN_RIGHT, potgor & 0x0400);
68 69
69 input_sync(amimouse_dev); 70 input_sync(dev);
70 71
71 return IRQ_HANDLED; 72 return IRQ_HANDLED;
72} 73}
@@ -74,63 +75,90 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy)
74static int amimouse_open(struct input_dev *dev) 75static int amimouse_open(struct input_dev *dev)
75{ 76{
76 unsigned short joy0dat; 77 unsigned short joy0dat;
78 int error;
77 79
78 joy0dat = amiga_custom.joy0dat; 80 joy0dat = amiga_custom.joy0dat;
79 81
80 amimouse_lastx = joy0dat & 0xff; 82 amimouse_lastx = joy0dat & 0xff;
81 amimouse_lasty = joy0dat >> 8; 83 amimouse_lasty = joy0dat >> 8;
82 84
83 if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { 85 error = request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse",
84 printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); 86 dev);
85 return -EBUSY; 87 if (error)
86 } 88 dev_err(&dev->dev, "Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
87 89
88 return 0; 90 return error;
89} 91}
90 92
91static void amimouse_close(struct input_dev *dev) 93static void amimouse_close(struct input_dev *dev)
92{ 94{
93 free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); 95 free_irq(IRQ_AMIGA_VERTB, dev);
94} 96}
95 97
96static int __init amimouse_init(void) 98static int __init amimouse_probe(struct platform_device *pdev)
97{ 99{
98 int err; 100 int err;
101 struct input_dev *dev;
99 102
100 if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE)) 103 dev = input_allocate_device();
101 return -ENODEV; 104 if (!dev)
102
103 amimouse_dev = input_allocate_device();
104 if (!amimouse_dev)
105 return -ENOMEM; 105 return -ENOMEM;
106 106
107 amimouse_dev->name = "Amiga mouse"; 107 dev->name = pdev->name;
108 amimouse_dev->phys = "amimouse/input0"; 108 dev->phys = "amimouse/input0";
109 amimouse_dev->id.bustype = BUS_AMIGA; 109 dev->id.bustype = BUS_AMIGA;
110 amimouse_dev->id.vendor = 0x0001; 110 dev->id.vendor = 0x0001;
111 amimouse_dev->id.product = 0x0002; 111 dev->id.product = 0x0002;
112 amimouse_dev->id.version = 0x0100; 112 dev->id.version = 0x0100;
113 113
114 amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); 114 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
115 amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); 115 dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
116 amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | 116 dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
117 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); 117 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
118 amimouse_dev->open = amimouse_open; 118 dev->open = amimouse_open;
119 amimouse_dev->close = amimouse_close; 119 dev->close = amimouse_close;
120 dev->dev.parent = &pdev->dev;
120 121
121 err = input_register_device(amimouse_dev); 122 err = input_register_device(dev);
122 if (err) { 123 if (err) {
123 input_free_device(amimouse_dev); 124 input_free_device(dev);
124 return err; 125 return err;
125 } 126 }
126 127
128 platform_set_drvdata(pdev, dev);
129
127 return 0; 130 return 0;
128} 131}
129 132
130static void __exit amimouse_exit(void) 133static int __exit amimouse_remove(struct platform_device *pdev)
131{ 134{
132 input_unregister_device(amimouse_dev); 135 struct input_dev *dev = platform_get_drvdata(pdev);
136
137 platform_set_drvdata(pdev, NULL);
138 input_unregister_device(dev);
139 return 0;
140}
141
142static struct platform_driver amimouse_driver = {
143 .remove = __exit_p(amimouse_remove),
144 .driver = {
145 .name = "amiga-mouse",
146 .owner = THIS_MODULE,
147 },
148};
149
150static int __init amimouse_init(void)
151{
152 return platform_driver_probe(&amimouse_driver, amimouse_probe);
133} 153}
134 154
135module_init(amimouse_init); 155module_init(amimouse_init);
156
157static void __exit amimouse_exit(void)
158{
159 platform_driver_unregister(&amimouse_driver);
160}
161
136module_exit(amimouse_exit); 162module_exit(amimouse_exit);
163
164MODULE_ALIAS("platform:amiga-mouse");
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index b9f58ca82fd..6703c6b9800 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -590,4 +590,17 @@ config TOUCHSCREEN_PCAP
590 590
591 To compile this driver as a module, choose M here: the 591 To compile this driver as a module, choose M here: the
592 module will be called pcap_ts. 592 module will be called pcap_ts.
593
594config TOUCHSCREEN_TPS6507X
595 tristate "TPS6507x based touchscreens"
596 depends on I2C
597 help
598 Say Y here if you have a TPS6507x based touchscreen
599 controller.
600
601 If unsure, say N.
602
603 To compile this driver as a module, choose M here: the
604 module will be called tps6507x_ts.
605
593endif 606endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 8ad36eef90a..497964a7a21 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -46,3 +46,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o
46obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o 46obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
47obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o 47obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
48obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o 48obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
49obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 532279cda0e..634f6f6b9b1 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -1163,8 +1163,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
1163 1163
1164 ts->reg = regulator_get(&spi->dev, "vcc"); 1164 ts->reg = regulator_get(&spi->dev, "vcc");
1165 if (IS_ERR(ts->reg)) { 1165 if (IS_ERR(ts->reg)) {
1166 dev_err(&spi->dev, "unable to get regulator: %ld\n", 1166 err = PTR_ERR(ts->reg);
1167 PTR_ERR(ts->reg)); 1167 dev_err(&spi->dev, "unable to get regulator: %ld\n", err);
1168 goto err_free_gpio; 1168 goto err_free_gpio;
1169 } 1169 }
1170 1170
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c
index e0b7c834111..ac5d0f9b0cb 100644
--- a/drivers/input/touchscreen/s3c2410_ts.c
+++ b/drivers/input/touchscreen/s3c2410_ts.c
@@ -413,6 +413,8 @@ static struct dev_pm_ops s3c_ts_pmops = {
413#endif 413#endif
414 414
415static struct platform_device_id s3cts_driver_ids[] = { 415static struct platform_device_id s3cts_driver_ids[] = {
416 { "s3c2410-ts", 0 },
417 { "s3c2440-ts", 0 },
416 { "s3c64xx-ts", FEAT_PEN_IRQ }, 418 { "s3c64xx-ts", FEAT_PEN_IRQ },
417 { } 419 { }
418}; 420};
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c
new file mode 100644
index 00000000000..5de80a1a730
--- /dev/null
+++ b/drivers/input/touchscreen/tps6507x-ts.c
@@ -0,0 +1,400 @@
1/*
2 * drivers/input/touchscreen/tps6507x_ts.c
3 *
4 * Touchscreen driver for the tps6507x chip.
5 *
6 * Copyright (c) 2009 RidgeRun (todd.fischer@ridgerun.com)
7 *
8 * Credits:
9 *
10 * Using code from tsc2007, MtekVision Co., Ltd.
11 *
12 * For licencing details see kernel-base/COPYING
13 *
14 * TPS65070, TPS65073, TPS650731, and TPS650732 support
15 * 10 bit touch screen interface.
16 */
17
18#include <linux/module.h>
19#include <linux/workqueue.h>
20#include <linux/slab.h>
21#include <linux/input.h>
22#include <linux/platform_device.h>
23#include <linux/mfd/tps6507x.h>
24#include <linux/input/tps6507x-ts.h>
25#include <linux/delay.h>
26
27#define TSC_DEFAULT_POLL_PERIOD 30 /* ms */
28#define TPS_DEFAULT_MIN_PRESSURE 0x30
29#define MAX_10BIT ((1 << 10) - 1)
30
31#define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \
32 TPS6507X_ADCONFIG_START_CONVERSION | \
33 TPS6507X_ADCONFIG_INPUT_REAL_TSC)
34#define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC)
35
36struct ts_event {
37 u16 x;
38 u16 y;
39 u16 pressure;
40};
41
42struct tps6507x_ts {
43 struct input_dev *input_dev;
44 struct device *dev;
45 char phys[32];
46 struct workqueue_struct *wq;
47 struct delayed_work work;
48 unsigned polling; /* polling is active */
49 struct ts_event tc;
50 struct tps6507x_dev *mfd;
51 u16 model;
52 unsigned pendown;
53 int irq;
54 void (*clear_penirq)(void);
55 unsigned long poll_period; /* ms */
56 u16 min_pressure;
57 int vref; /* non-zero to leave vref on */
58};
59
60static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data)
61{
62 int err;
63
64 err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data);
65
66 if (err)
67 return err;
68
69 return 0;
70}
71
72static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data)
73{
74 return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data);
75}
76
77static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc,
78 u8 tsc_mode, u16 *value)
79{
80 s32 ret;
81 u8 adc_status;
82 u8 result;
83
84 /* Route input signal to A/D converter */
85
86 ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode);
87 if (ret) {
88 dev_err(tsc->dev, "TSC mode read failed\n");
89 goto err;
90 }
91
92 /* Start A/D conversion */
93
94 ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
95 TPS6507X_ADCONFIG_CONVERT_TS);
96 if (ret) {
97 dev_err(tsc->dev, "ADC config write failed\n");
98 return ret;
99 }
100
101 do {
102 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG,
103 &adc_status);
104 if (ret) {
105 dev_err(tsc->dev, "ADC config read failed\n");
106 goto err;
107 }
108 } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION);
109
110 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result);
111 if (ret) {
112 dev_err(tsc->dev, "ADC result 2 read failed\n");
113 goto err;
114 }
115
116 *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8;
117
118 ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result);
119 if (ret) {
120 dev_err(tsc->dev, "ADC result 1 read failed\n");
121 goto err;
122 }
123
124 *value |= result;
125
126 dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value);
127
128err:
129 return ret;
130}
131
132/* Need to call tps6507x_adc_standby() after using A/D converter for the
133 * touch screen interrupt to work properly.
134 */
135
136static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc)
137{
138 s32 ret;
139 s32 loops = 0;
140 u8 val;
141
142 ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG,
143 TPS6507X_ADCONFIG_INPUT_TSC);
144 if (ret)
145 return ret;
146
147 ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE,
148 TPS6507X_TSCMODE_STANDBY);
149 if (ret)
150 return ret;
151
152 ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
153 if (ret)
154 return ret;
155
156 while (val & TPS6507X_REG_TSC_INT) {
157 mdelay(10);
158 ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val);
159 if (ret)
160 return ret;
161 loops++;
162 }
163
164 return ret;
165}
166
167static void tps6507x_ts_handler(struct work_struct *work)
168{
169 struct tps6507x_ts *tsc = container_of(work,
170 struct tps6507x_ts, work.work);
171 struct input_dev *input_dev = tsc->input_dev;
172 int pendown;
173 int schd;
174 int poll = 0;
175 s32 ret;
176
177 ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE,
178 &tsc->tc.pressure);
179 if (ret)
180 goto done;
181
182 pendown = tsc->tc.pressure > tsc->min_pressure;
183
184 if (unlikely(!pendown && tsc->pendown)) {
185 dev_dbg(tsc->dev, "UP\n");
186 input_report_key(input_dev, BTN_TOUCH, 0);
187 input_report_abs(input_dev, ABS_PRESSURE, 0);
188 input_sync(input_dev);
189 tsc->pendown = 0;
190 }
191
192 if (pendown) {
193
194 if (!tsc->pendown) {
195 dev_dbg(tsc->dev, "DOWN\n");
196 input_report_key(input_dev, BTN_TOUCH, 1);
197 } else
198 dev_dbg(tsc->dev, "still down\n");
199
200 ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION,
201 &tsc->tc.x);
202 if (ret)
203 goto done;
204
205 ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION,
206 &tsc->tc.y);
207 if (ret)
208 goto done;
209
210 input_report_abs(input_dev, ABS_X, tsc->tc.x);
211 input_report_abs(input_dev, ABS_Y, tsc->tc.y);
212 input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure);
213 input_sync(input_dev);
214 tsc->pendown = 1;
215 poll = 1;
216 }
217
218done:
219 /* always poll if not using interrupts */
220 poll = 1;
221
222 if (poll) {
223 schd = queue_delayed_work(tsc->wq, &tsc->work,
224 tsc->poll_period * HZ / 1000);
225 if (schd)
226 tsc->polling = 1;
227 else {
228 tsc->polling = 0;
229 dev_err(tsc->dev, "re-schedule failed");
230 }
231 } else
232 tsc->polling = 0;
233
234 ret = tps6507x_adc_standby(tsc);
235}
236
237static int tps6507x_ts_probe(struct platform_device *pdev)
238{
239 int error;
240 struct tps6507x_ts *tsc;
241 struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
242 struct touchscreen_init_data *init_data;
243 struct input_dev *input_dev;
244 struct tps6507x_board *tps_board;
245 int schd;
246
247 /**
248 * tps_board points to pmic related constants
249 * coming from the board-evm file.
250 */
251
252 tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data;
253
254 if (!tps_board) {
255 dev_err(tps6507x_dev->dev,
256 "Could not find tps6507x platform data\n");
257 return -EIO;
258 }
259
260 /**
261 * init_data points to array of regulator_init structures
262 * coming from the board-evm file.
263 */
264
265 init_data = tps_board->tps6507x_ts_init_data;
266
267 tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL);
268 if (!tsc) {
269 dev_err(tps6507x_dev->dev, "failed to allocate driver data\n");
270 error = -ENOMEM;
271 goto err0;
272 }
273
274 tps6507x_dev->ts = tsc;
275 tsc->mfd = tps6507x_dev;
276 tsc->dev = tps6507x_dev->dev;
277 input_dev = input_allocate_device();
278 if (!input_dev) {
279 dev_err(tsc->dev, "Failed to allocate input device.\n");
280 error = -ENOMEM;
281 goto err1;
282 }
283
284 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
285 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
286
287 input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0);
288 input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0);
289 input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0);
290
291 input_dev->name = "TPS6507x Touchscreen";
292 input_dev->id.bustype = BUS_I2C;
293 input_dev->dev.parent = tsc->dev;
294
295 snprintf(tsc->phys, sizeof(tsc->phys),
296 "%s/input0", dev_name(tsc->dev));
297 input_dev->phys = tsc->phys;
298
299 dev_dbg(tsc->dev, "device: %s\n", input_dev->phys);
300
301 input_set_drvdata(input_dev, tsc);
302
303 tsc->input_dev = input_dev;
304
305 INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler);
306 tsc->wq = create_workqueue("TPS6507x Touchscreen");
307
308 if (init_data) {
309 tsc->poll_period = init_data->poll_period;
310 tsc->vref = init_data->vref;
311 tsc->min_pressure = init_data->min_pressure;
312 input_dev->id.vendor = init_data->vendor;
313 input_dev->id.product = init_data->product;
314 input_dev->id.version = init_data->version;
315 } else {
316 tsc->poll_period = TSC_DEFAULT_POLL_PERIOD;
317 tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE;
318 }
319
320 error = tps6507x_adc_standby(tsc);
321 if (error)
322 goto err2;
323
324 error = input_register_device(input_dev);
325 if (error)
326 goto err2;
327
328 schd = queue_delayed_work(tsc->wq, &tsc->work,
329 tsc->poll_period * HZ / 1000);
330
331 if (schd)
332 tsc->polling = 1;
333 else {
334 tsc->polling = 0;
335 dev_err(tsc->dev, "schedule failed");
336 goto err2;
337 }
338
339 return 0;
340
341err2:
342 cancel_delayed_work(&tsc->work);
343 flush_workqueue(tsc->wq);
344 destroy_workqueue(tsc->wq);
345 tsc->wq = 0;
346 input_free_device(input_dev);
347err1:
348 kfree(tsc);
349 tps6507x_dev->ts = NULL;
350err0:
351 return error;
352}
353
354static int __devexit tps6507x_ts_remove(struct platform_device *pdev)
355{
356 struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev);
357 struct tps6507x_ts *tsc = tps6507x_dev->ts;
358 struct input_dev *input_dev = tsc->input_dev;
359
360 if (!tsc)
361 return 0;
362
363 cancel_delayed_work(&tsc->work);
364 flush_workqueue(tsc->wq);
365 destroy_workqueue(tsc->wq);
366 tsc->wq = 0;
367
368 input_free_device(input_dev);
369
370 tps6507x_dev->ts = NULL;
371 kfree(tsc);
372
373 return 0;
374}
375
376static struct platform_driver tps6507x_ts_driver = {
377 .driver = {
378 .name = "tps6507x-ts",
379 .owner = THIS_MODULE,
380 },
381 .probe = tps6507x_ts_probe,
382 .remove = __devexit_p(tps6507x_ts_remove),
383};
384
385static int __init tps6507x_ts_init(void)
386{
387 return platform_driver_register(&tps6507x_ts_driver);
388}
389module_init(tps6507x_ts_init);
390
391static void __exit tps6507x_ts_exit(void)
392{
393 platform_driver_unregister(&tps6507x_ts_driver);
394}
395module_exit(tps6507x_ts_exit);
396
397MODULE_AUTHOR("Todd Fischer <todd.fischer@ridgerun.com>");
398MODULE_DESCRIPTION("TPS6507x - TouchScreen driver");
399MODULE_LICENSE("GPL v2");
400MODULE_ALIAS("platform:tps6507x-tsc");
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 29a8bbf3f08..567d57215c2 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -857,6 +857,11 @@ static int nexio_read_data(struct usbtouch_usb *usbtouch, unsigned char *pkt)
857 if ((pkt[0] & 0xe0) != 0xe0) 857 if ((pkt[0] & 0xe0) != 0xe0)
858 return 0; 858 return 0;
859 859
860 if (be16_to_cpu(packet->data_len) > 0xff)
861 packet->data_len = cpu_to_be16(be16_to_cpu(packet->data_len) - 0x100);
862 if (be16_to_cpu(packet->x_len) > 0xff)
863 packet->x_len = cpu_to_be16(be16_to_cpu(packet->x_len) - 0x80);
864
860 /* send ACK */ 865 /* send ACK */
861 ret = usb_submit_urb(priv->ack, GFP_ATOMIC); 866 ret = usb_submit_urb(priv->ack, GFP_ATOMIC);
862 867
@@ -1112,7 +1117,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
1112 1117
1113#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO 1118#ifdef CONFIG_TOUCHSCREEN_USB_NEXIO
1114 [DEVTYPE_NEXIO] = { 1119 [DEVTYPE_NEXIO] = {
1115 .rept_size = 128, 1120 .rept_size = 1024,
1116 .irq_always = true, 1121 .irq_always = true,
1117 .read_data = nexio_read_data, 1122 .read_data = nexio_read_data,
1118 .init = nexio_init, 1123 .init = nexio_init,