diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-09-18 10:58:33 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-09-18 10:58:33 -0400 |
commit | 4ba25a496f62129a2ad8c2436ab2b402752dc66c (patch) | |
tree | 8abf41a79f293832a430a9609530c24cd365466c /drivers/input | |
parent | 390de835b61228abf6646f2b14530edca8d7512f (diff) | |
parent | 6e4664525b1db28f8c4e1130957f70a94c19213e (diff) |
Merge tag 'v3.11' into next
Merge with mainline to bring in sync changes to cyttsp4 driver.
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/joystick/xpad.c | 3 | ||||
-rw-r--r-- | drivers/input/keyboard/Kconfig | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/cros_ec_keyb.c | 54 | ||||
-rw-r--r-- | drivers/input/keyboard/samsung-keypad.c | 52 | ||||
-rw-r--r-- | drivers/input/misc/da9055_onkey.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 36 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 44 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 1 | ||||
-rw-r--r-- | drivers/input/serio/Kconfig | 4 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 12 | ||||
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp4_core.c | 15 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp4_core.h | 12 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp4_spi.c | 20 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_core.c | 28 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_core.h | 10 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_i2c_common.c | 30 | ||||
-rw-r--r-- | drivers/input/touchscreen/cyttsp_spi.c | 6 | ||||
-rw-r--r-- | drivers/input/touchscreen/ti_am335x_tsc.c | 288 | ||||
-rw-r--r-- | drivers/input/touchscreen/tps6507x-ts.c | 158 |
20 files changed, 452 insertions, 325 deletions
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d6cbfe9df218..75e3b102ce45 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -137,7 +137,7 @@ static const struct xpad_device { | |||
137 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 137 | { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
138 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, | 138 | { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", 0, XTYPE_XBOX }, |
139 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, | 139 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
140 | { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", XTYPE_XBOX360 }, | 140 | { 0x0738, 0x4728, "Mad Catz Street Fighter IV FightPad", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
141 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, | 141 | { 0x0738, 0x4738, "Mad Catz Wired Xbox 360 Controller (SFIV)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, |
142 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 142 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
143 | { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, | 143 | { 0x0738, 0xbeef, "Mad Catz JOYTECH NEO SE Advanced GamePad", XTYPE_XBOX360 }, |
@@ -167,6 +167,7 @@ static const struct xpad_device { | |||
167 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 167 | { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
168 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, | 168 | { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, |
169 | { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 169 | { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
170 | { 0x1689, 0xfd01, "Razer Onza Classic Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | ||
170 | { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, | 171 | { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, |
171 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, | 172 | { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, |
172 | { 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 }, | 173 | { 0x1bad, 0xf016, "Mad Catz Xbox 360 Controller", 0, XTYPE_XBOX360 }, |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 77412d824963..269d4c3658cb 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -441,6 +441,7 @@ config KEYBOARD_TEGRA | |||
441 | 441 | ||
442 | config KEYBOARD_OPENCORES | 442 | config KEYBOARD_OPENCORES |
443 | tristate "OpenCores Keyboard Controller" | 443 | tristate "OpenCores Keyboard Controller" |
444 | depends on HAS_IOMEM | ||
444 | help | 445 | help |
445 | Say Y here if you want to use the OpenCores Keyboard Controller | 446 | Say Y here if you want to use the OpenCores Keyboard Controller |
446 | http://www.opencores.org/project,keyboardcontroller | 447 | http://www.opencores.org/project,keyboardcontroller |
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 49557f27bfa6..7e8b0a52af25 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c | |||
@@ -206,33 +206,6 @@ static int cros_ec_keyb_work(struct notifier_block *nb, | |||
206 | return NOTIFY_DONE; | 206 | return NOTIFY_DONE; |
207 | } | 207 | } |
208 | 208 | ||
209 | /* Clear any keys in the buffer */ | ||
210 | static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) | ||
211 | { | ||
212 | uint8_t old_state[ckdev->cols]; | ||
213 | uint8_t new_state[ckdev->cols]; | ||
214 | unsigned long duration; | ||
215 | int i, ret; | ||
216 | |||
217 | /* | ||
218 | * Keep reading until we see that the scan state does not change. | ||
219 | * That indicates that we are done. | ||
220 | * | ||
221 | * Assume that the EC keyscan buffer is at most 32 deep. | ||
222 | */ | ||
223 | duration = jiffies; | ||
224 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
225 | for (i = 1; !ret && i < 32; i++) { | ||
226 | memcpy(old_state, new_state, sizeof(old_state)); | ||
227 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
228 | if (0 == memcmp(old_state, new_state, sizeof(old_state))) | ||
229 | break; | ||
230 | } | ||
231 | duration = jiffies - duration; | ||
232 | dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, | ||
233 | jiffies_to_usecs(duration)); | ||
234 | } | ||
235 | |||
236 | static int cros_ec_keyb_probe(struct platform_device *pdev) | 209 | static int cros_ec_keyb_probe(struct platform_device *pdev) |
237 | { | 210 | { |
238 | struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); | 211 | struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); |
@@ -299,6 +272,33 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) | |||
299 | } | 272 | } |
300 | 273 | ||
301 | #ifdef CONFIG_PM_SLEEP | 274 | #ifdef CONFIG_PM_SLEEP |
275 | /* Clear any keys in the buffer */ | ||
276 | static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) | ||
277 | { | ||
278 | uint8_t old_state[ckdev->cols]; | ||
279 | uint8_t new_state[ckdev->cols]; | ||
280 | unsigned long duration; | ||
281 | int i, ret; | ||
282 | |||
283 | /* | ||
284 | * Keep reading until we see that the scan state does not change. | ||
285 | * That indicates that we are done. | ||
286 | * | ||
287 | * Assume that the EC keyscan buffer is at most 32 deep. | ||
288 | */ | ||
289 | duration = jiffies; | ||
290 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
291 | for (i = 1; !ret && i < 32; i++) { | ||
292 | memcpy(old_state, new_state, sizeof(old_state)); | ||
293 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
294 | if (0 == memcmp(old_state, new_state, sizeof(old_state))) | ||
295 | break; | ||
296 | } | ||
297 | duration = jiffies - duration; | ||
298 | dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, | ||
299 | jiffies_to_usecs(duration)); | ||
300 | } | ||
301 | |||
302 | static int cros_ec_keyb_resume(struct device *dev) | 302 | static int cros_ec_keyb_resume(struct device *dev) |
303 | { | 303 | { |
304 | struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); | 304 | struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 7b938b481bd5..ac43a486c775 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/of.h> | 26 | #include <linux/of.h> |
27 | #include <linux/of_gpio.h> | ||
28 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
29 | #include <linux/input/samsung-keypad.h> | 28 | #include <linux/input/samsung-keypad.h> |
30 | 29 | ||
@@ -79,10 +78,6 @@ struct samsung_keypad { | |||
79 | unsigned int rows; | 78 | unsigned int rows; |
80 | unsigned int cols; | 79 | unsigned int cols; |
81 | unsigned int row_state[SAMSUNG_MAX_COLS]; | 80 | unsigned int row_state[SAMSUNG_MAX_COLS]; |
82 | #ifdef CONFIG_OF | ||
83 | int row_gpios[SAMSUNG_MAX_ROWS]; | ||
84 | int col_gpios[SAMSUNG_MAX_COLS]; | ||
85 | #endif | ||
86 | unsigned short keycodes[]; | 81 | unsigned short keycodes[]; |
87 | }; | 82 | }; |
88 | 83 | ||
@@ -304,45 +299,6 @@ static struct samsung_keypad_platdata *samsung_keypad_parse_dt( | |||
304 | 299 | ||
305 | return pdata; | 300 | return pdata; |
306 | } | 301 | } |
307 | |||
308 | static void samsung_keypad_parse_dt_gpio(struct device *dev, | ||
309 | struct samsung_keypad *keypad) | ||
310 | { | ||
311 | struct device_node *np = dev->of_node; | ||
312 | int gpio, error, row, col; | ||
313 | |||
314 | for (row = 0; row < keypad->rows; row++) { | ||
315 | gpio = of_get_named_gpio(np, "row-gpios", row); | ||
316 | keypad->row_gpios[row] = gpio; | ||
317 | if (!gpio_is_valid(gpio)) { | ||
318 | dev_err(dev, "keypad row[%d]: invalid gpio %d\n", | ||
319 | row, gpio); | ||
320 | continue; | ||
321 | } | ||
322 | |||
323 | error = devm_gpio_request(dev, gpio, "keypad-row"); | ||
324 | if (error) | ||
325 | dev_err(dev, | ||
326 | "keypad row[%d] gpio request failed: %d\n", | ||
327 | row, error); | ||
328 | } | ||
329 | |||
330 | for (col = 0; col < keypad->cols; col++) { | ||
331 | gpio = of_get_named_gpio(np, "col-gpios", col); | ||
332 | keypad->col_gpios[col] = gpio; | ||
333 | if (!gpio_is_valid(gpio)) { | ||
334 | dev_err(dev, "keypad column[%d]: invalid gpio %d\n", | ||
335 | col, gpio); | ||
336 | continue; | ||
337 | } | ||
338 | |||
339 | error = devm_gpio_request(dev, gpio, "keypad-col"); | ||
340 | if (error) | ||
341 | dev_err(dev, | ||
342 | "keypad column[%d] gpio request failed: %d\n", | ||
343 | col, error); | ||
344 | } | ||
345 | } | ||
346 | #else | 302 | #else |
347 | static | 303 | static |
348 | struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) | 304 | struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev) |
@@ -424,15 +380,11 @@ static int samsung_keypad_probe(struct platform_device *pdev) | |||
424 | keypad->stopped = true; | 380 | keypad->stopped = true; |
425 | init_waitqueue_head(&keypad->wait); | 381 | init_waitqueue_head(&keypad->wait); |
426 | 382 | ||
427 | if (pdev->dev.of_node) { | 383 | if (pdev->dev.of_node) |
428 | #ifdef CONFIG_OF | ||
429 | samsung_keypad_parse_dt_gpio(&pdev->dev, keypad); | ||
430 | keypad->type = of_device_is_compatible(pdev->dev.of_node, | 384 | keypad->type = of_device_is_compatible(pdev->dev.of_node, |
431 | "samsung,s5pv210-keypad"); | 385 | "samsung,s5pv210-keypad"); |
432 | #endif | 386 | else |
433 | } else { | ||
434 | keypad->type = platform_get_device_id(pdev)->driver_data; | 387 | keypad->type = platform_get_device_id(pdev)->driver_data; |
435 | } | ||
436 | 388 | ||
437 | input_dev->name = pdev->name; | 389 | input_dev->name = pdev->name; |
438 | input_dev->id.bustype = BUS_HOST; | 390 | input_dev->id.bustype = BUS_HOST; |
diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c index ee6ae3a00174..a0af8b2506ce 100644 --- a/drivers/input/misc/da9055_onkey.c +++ b/drivers/input/misc/da9055_onkey.c | |||
@@ -36,7 +36,7 @@ static void da9055_onkey_query(struct da9055_onkey *onkey) | |||
36 | } else { | 36 | } else { |
37 | key_stat &= DA9055_NOKEY_STS; | 37 | key_stat &= DA9055_NOKEY_STS; |
38 | /* | 38 | /* |
39 | * Onkey status bit is cleared when onkey button is relased. | 39 | * Onkey status bit is cleared when onkey button is released. |
40 | */ | 40 | */ |
41 | if (!key_stat) { | 41 | if (!key_stat) { |
42 | input_report_key(onkey->input, KEY_POWER, 0); | 42 | input_report_key(onkey->input, KEY_POWER, 0); |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2baff1b79a55..4ef4d5e198ae 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -88,6 +88,10 @@ | |||
88 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 | 88 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 |
89 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | 89 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a |
90 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | 90 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b |
91 | /* MacbookAir6,2 (unibody, June 2013) */ | ||
92 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0291 | ||
93 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0292 | ||
94 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0293 | ||
91 | 95 | ||
92 | #define BCM5974_DEVICE(prod) { \ | 96 | #define BCM5974_DEVICE(prod) { \ |
93 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 97 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
@@ -145,6 +149,10 @@ static const struct usb_device_id bcm5974_table[] = { | |||
145 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), | 149 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), |
146 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), | 150 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), |
147 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), | 151 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), |
152 | /* MacbookAir6,2 */ | ||
153 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI), | ||
154 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO), | ||
155 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), | ||
148 | /* Terminating entry */ | 156 | /* Terminating entry */ |
149 | {} | 157 | {} |
150 | }; | 158 | }; |
@@ -172,15 +180,18 @@ struct bt_data { | |||
172 | /* trackpad header types */ | 180 | /* trackpad header types */ |
173 | enum tp_type { | 181 | enum tp_type { |
174 | TYPE1, /* plain trackpad */ | 182 | TYPE1, /* plain trackpad */ |
175 | TYPE2 /* button integrated in trackpad */ | 183 | TYPE2, /* button integrated in trackpad */ |
184 | TYPE3 /* additional header fields since June 2013 */ | ||
176 | }; | 185 | }; |
177 | 186 | ||
178 | /* trackpad finger data offsets, le16-aligned */ | 187 | /* trackpad finger data offsets, le16-aligned */ |
179 | #define FINGER_TYPE1 (13 * sizeof(__le16)) | 188 | #define FINGER_TYPE1 (13 * sizeof(__le16)) |
180 | #define FINGER_TYPE2 (15 * sizeof(__le16)) | 189 | #define FINGER_TYPE2 (15 * sizeof(__le16)) |
190 | #define FINGER_TYPE3 (19 * sizeof(__le16)) | ||
181 | 191 | ||
182 | /* trackpad button data offsets */ | 192 | /* trackpad button data offsets */ |
183 | #define BUTTON_TYPE2 15 | 193 | #define BUTTON_TYPE2 15 |
194 | #define BUTTON_TYPE3 23 | ||
184 | 195 | ||
185 | /* list of device capability bits */ | 196 | /* list of device capability bits */ |
186 | #define HAS_INTEGRATED_BUTTON 1 | 197 | #define HAS_INTEGRATED_BUTTON 1 |
@@ -400,6 +411,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
400 | { SN_COORD, -150, 6730 }, | 411 | { SN_COORD, -150, 6730 }, |
401 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | 412 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } |
402 | }, | 413 | }, |
414 | { | ||
415 | USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI, | ||
416 | USB_DEVICE_ID_APPLE_WELLSPRING8_ISO, | ||
417 | USB_DEVICE_ID_APPLE_WELLSPRING8_JIS, | ||
418 | HAS_INTEGRATED_BUTTON, | ||
419 | 0, sizeof(struct bt_data), | ||
420 | 0x83, TYPE3, FINGER_TYPE3, FINGER_TYPE3 + SIZEOF_ALL_FINGERS, | ||
421 | { SN_PRESSURE, 0, 300 }, | ||
422 | { SN_WIDTH, 0, 2048 }, | ||
423 | { SN_COORD, -4620, 5140 }, | ||
424 | { SN_COORD, -150, 6600 }, | ||
425 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
426 | }, | ||
403 | {} | 427 | {} |
404 | }; | 428 | }; |
405 | 429 | ||
@@ -557,6 +581,9 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
557 | input_report_key(input, BTN_LEFT, ibt); | 581 | input_report_key(input, BTN_LEFT, ibt); |
558 | } | 582 | } |
559 | 583 | ||
584 | if (c->tp_type == TYPE3) | ||
585 | input_report_key(input, BTN_LEFT, dev->tp_data[BUTTON_TYPE3]); | ||
586 | |||
560 | input_sync(input); | 587 | input_sync(input); |
561 | 588 | ||
562 | return 0; | 589 | return 0; |
@@ -572,9 +599,14 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
572 | 599 | ||
573 | static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) | 600 | static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) |
574 | { | 601 | { |
575 | char *data = kmalloc(8, GFP_KERNEL); | ||
576 | int retval = 0, size; | 602 | int retval = 0, size; |
603 | char *data; | ||
604 | |||
605 | /* Type 3 does not require a mode switch */ | ||
606 | if (dev->cfg.tp_type == TYPE3) | ||
607 | return 0; | ||
577 | 608 | ||
609 | data = kmalloc(8, GFP_KERNEL); | ||
578 | if (!data) { | 610 | if (!data) { |
579 | dev_err(&dev->intf->dev, "out of memory\n"); | 611 | dev_err(&dev->intf->dev, "out of memory\n"); |
580 | retval = -ENOMEM; | 612 | retval = -ENOMEM; |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 57b2637e153a..8551dcaf24db 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -672,6 +672,7 @@ static int elantech_packet_check_v2(struct psmouse *psmouse) | |||
672 | */ | 672 | */ |
673 | static int elantech_packet_check_v3(struct psmouse *psmouse) | 673 | static int elantech_packet_check_v3(struct psmouse *psmouse) |
674 | { | 674 | { |
675 | struct elantech_data *etd = psmouse->private; | ||
675 | const u8 debounce_packet[] = { 0xc4, 0xff, 0xff, 0x02, 0xff, 0xff }; | 676 | const u8 debounce_packet[] = { 0xc4, 0xff, 0xff, 0x02, 0xff, 0xff }; |
676 | unsigned char *packet = psmouse->packet; | 677 | unsigned char *packet = psmouse->packet; |
677 | 678 | ||
@@ -682,19 +683,48 @@ static int elantech_packet_check_v3(struct psmouse *psmouse) | |||
682 | if (!memcmp(packet, debounce_packet, sizeof(debounce_packet))) | 683 | if (!memcmp(packet, debounce_packet, sizeof(debounce_packet))) |
683 | return PACKET_DEBOUNCE; | 684 | return PACKET_DEBOUNCE; |
684 | 685 | ||
685 | if ((packet[0] & 0x0c) == 0x04 && (packet[3] & 0xcf) == 0x02) | 686 | /* |
686 | return PACKET_V3_HEAD; | 687 | * If the hardware flag 'crc_enabled' is set the packets have |
688 | * different signatures. | ||
689 | */ | ||
690 | if (etd->crc_enabled) { | ||
691 | if ((packet[3] & 0x09) == 0x08) | ||
692 | return PACKET_V3_HEAD; | ||
693 | |||
694 | if ((packet[3] & 0x09) == 0x09) | ||
695 | return PACKET_V3_TAIL; | ||
696 | } else { | ||
697 | if ((packet[0] & 0x0c) == 0x04 && (packet[3] & 0xcf) == 0x02) | ||
698 | return PACKET_V3_HEAD; | ||
687 | 699 | ||
688 | if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) | 700 | if ((packet[0] & 0x0c) == 0x0c && (packet[3] & 0xce) == 0x0c) |
689 | return PACKET_V3_TAIL; | 701 | return PACKET_V3_TAIL; |
702 | } | ||
690 | 703 | ||
691 | return PACKET_UNKNOWN; | 704 | return PACKET_UNKNOWN; |
692 | } | 705 | } |
693 | 706 | ||
694 | static int elantech_packet_check_v4(struct psmouse *psmouse) | 707 | static int elantech_packet_check_v4(struct psmouse *psmouse) |
695 | { | 708 | { |
709 | struct elantech_data *etd = psmouse->private; | ||
696 | unsigned char *packet = psmouse->packet; | 710 | unsigned char *packet = psmouse->packet; |
697 | unsigned char packet_type = packet[3] & 0x03; | 711 | unsigned char packet_type = packet[3] & 0x03; |
712 | bool sanity_check; | ||
713 | |||
714 | /* | ||
715 | * Sanity check based on the constant bits of a packet. | ||
716 | * The constant bits change depending on the value of | ||
717 | * the hardware flag 'crc_enabled' but are the same for | ||
718 | * every packet, regardless of the type. | ||
719 | */ | ||
720 | if (etd->crc_enabled) | ||
721 | sanity_check = ((packet[3] & 0x08) == 0x00); | ||
722 | else | ||
723 | sanity_check = ((packet[0] & 0x0c) == 0x04 && | ||
724 | (packet[3] & 0x1c) == 0x10); | ||
725 | |||
726 | if (!sanity_check) | ||
727 | return PACKET_UNKNOWN; | ||
698 | 728 | ||
699 | switch (packet_type) { | 729 | switch (packet_type) { |
700 | case 0: | 730 | case 0: |
@@ -1313,6 +1343,12 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1313 | etd->reports_pressure = true; | 1343 | etd->reports_pressure = true; |
1314 | } | 1344 | } |
1315 | 1345 | ||
1346 | /* | ||
1347 | * The signatures of v3 and v4 packets change depending on the | ||
1348 | * value of this hardware flag. | ||
1349 | */ | ||
1350 | etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); | ||
1351 | |||
1316 | return 0; | 1352 | return 0; |
1317 | } | 1353 | } |
1318 | 1354 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 46db3be45ac9..036a04abaef7 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -129,6 +129,7 @@ struct elantech_data { | |||
129 | bool paritycheck; | 129 | bool paritycheck; |
130 | bool jumpy_cursor; | 130 | bool jumpy_cursor; |
131 | bool reports_pressure; | 131 | bool reports_pressure; |
132 | bool crc_enabled; | ||
132 | unsigned char hw_version; | 133 | unsigned char hw_version; |
133 | unsigned int fw_version; | 134 | unsigned int fw_version; |
134 | unsigned int single_finger_reports; | 135 | unsigned int single_finger_reports; |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index d401a7dccaa7..1e691a3a79cb 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -22,7 +22,8 @@ config SERIO_I8042 | |||
22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 | 22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 |
23 | default y | 23 | default y |
24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ | 24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ |
25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 | 25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \ |
26 | !ARC | ||
26 | help | 27 | help |
27 | i8042 is the chip over which the standard AT keyboard and PS/2 | 28 | i8042 is the chip over which the standard AT keyboard and PS/2 |
28 | mouse are connected to the computer. If you use these devices, | 29 | mouse are connected to the computer. If you use these devices, |
@@ -205,6 +206,7 @@ config SERIO_XILINX_XPS_PS2 | |||
205 | 206 | ||
206 | config SERIO_ALTERA_PS2 | 207 | config SERIO_ALTERA_PS2 |
207 | tristate "Altera UP PS/2 controller" | 208 | tristate "Altera UP PS/2 controller" |
209 | depends on HAS_IOMEM | ||
208 | help | 210 | help |
209 | Say Y here if you have Altera University Program PS/2 ports. | 211 | Say Y here if you have Altera University Program PS/2 ports. |
210 | 212 | ||
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 541197b7b973..b2aa503c16b1 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -363,6 +363,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
363 | case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ | 363 | case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */ |
364 | case 0x160802: /* Cintiq 13HD Pro Pen */ | 364 | case 0x160802: /* Cintiq 13HD Pro Pen */ |
365 | case 0x180802: /* DTH2242 Pen */ | 365 | case 0x180802: /* DTH2242 Pen */ |
366 | case 0x100802: /* Intuos4/5 13HD/24HD General Pen */ | ||
366 | wacom->tool[idx] = BTN_TOOL_PEN; | 367 | wacom->tool[idx] = BTN_TOOL_PEN; |
367 | break; | 368 | break; |
368 | 369 | ||
@@ -401,6 +402,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
401 | case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ | 402 | case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */ |
402 | case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ | 403 | case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */ |
403 | case 0x18080a: /* DTH2242 Eraser */ | 404 | case 0x18080a: /* DTH2242 Eraser */ |
405 | case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */ | ||
404 | wacom->tool[idx] = BTN_TOOL_RUBBER; | 406 | wacom->tool[idx] = BTN_TOOL_RUBBER; |
405 | break; | 407 | break; |
406 | 408 | ||
@@ -2099,7 +2101,7 @@ static const struct wacom_features wacom_features_0xDA = | |||
2099 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, | 2101 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, |
2100 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 2102 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
2101 | .touch_max = 2 }; | 2103 | .touch_max = 2 }; |
2102 | static struct wacom_features wacom_features_0xDB = | 2104 | static const struct wacom_features wacom_features_0xDB = |
2103 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, | 2105 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13700, 1023, |
2104 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 2106 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
2105 | .touch_max = 2 }; | 2107 | .touch_max = 2 }; |
@@ -2114,6 +2116,12 @@ static const struct wacom_features wacom_features_0xDF = | |||
2114 | { "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN, 21648, 13700, 1023, | 2116 | { "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN, 21648, 13700, 1023, |
2115 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, | 2117 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, |
2116 | .touch_max = 16 }; | 2118 | .touch_max = 16 }; |
2119 | static const struct wacom_features wacom_features_0x300 = | ||
2120 | { "Wacom Bamboo One S", WACOM_PKGLEN_BBPEN, 14720, 9225, 1023, | ||
2121 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
2122 | static const struct wacom_features wacom_features_0x301 = | ||
2123 | { "Wacom Bamboo One M", WACOM_PKGLEN_BBPEN, 21648, 13530, 1023, | ||
2124 | 31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
2117 | static const struct wacom_features wacom_features_0x6004 = | 2125 | static const struct wacom_features wacom_features_0x6004 = |
2118 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, | 2126 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, |
2119 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2127 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -2240,6 +2248,8 @@ const struct usb_device_id wacom_ids[] = { | |||
2240 | { USB_DEVICE_WACOM(0x100) }, | 2248 | { USB_DEVICE_WACOM(0x100) }, |
2241 | { USB_DEVICE_WACOM(0x101) }, | 2249 | { USB_DEVICE_WACOM(0x101) }, |
2242 | { USB_DEVICE_WACOM(0x10D) }, | 2250 | { USB_DEVICE_WACOM(0x10D) }, |
2251 | { USB_DEVICE_WACOM(0x300) }, | ||
2252 | { USB_DEVICE_WACOM(0x301) }, | ||
2243 | { USB_DEVICE_WACOM(0x304) }, | 2253 | { USB_DEVICE_WACOM(0x304) }, |
2244 | { USB_DEVICE_WACOM(0x4001) }, | 2254 | { USB_DEVICE_WACOM(0x4001) }, |
2245 | { USB_DEVICE_WACOM(0x47) }, | 2255 | { USB_DEVICE_WACOM(0x47) }, |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 2d70089c1183..3b9758b5f4d7 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -909,6 +909,7 @@ config TOUCHSCREEN_STMPE | |||
909 | config TOUCHSCREEN_TPS6507X | 909 | config TOUCHSCREEN_TPS6507X |
910 | tristate "TPS6507x based touchscreens" | 910 | tristate "TPS6507x based touchscreens" |
911 | depends on I2C | 911 | depends on I2C |
912 | select INPUT_POLLDEV | ||
912 | help | 913 | help |
913 | Say Y here if you have a TPS6507x based touchscreen | 914 | Say Y here if you have a TPS6507x based touchscreen |
914 | controller. | 915 | controller. |
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index 580004049b9e..d038575f49db 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c | |||
@@ -153,7 +153,7 @@ static int cyttsp4_hw_reset(struct cyttsp4 *cd) | |||
153 | */ | 153 | */ |
154 | static int cyttsp4_bits_2_bytes(unsigned int nbits, size_t *max) | 154 | static int cyttsp4_bits_2_bytes(unsigned int nbits, size_t *max) |
155 | { | 155 | { |
156 | *max = 1 << nbits; | 156 | *max = 1UL << nbits; |
157 | return (nbits + 7) / 8; | 157 | return (nbits + 7) / 8; |
158 | } | 158 | } |
159 | 159 | ||
@@ -1447,11 +1447,6 @@ static void cyttsp4_watchdog_work(struct work_struct *work) | |||
1447 | u8 *mode; | 1447 | u8 *mode; |
1448 | int retval; | 1448 | int retval; |
1449 | 1449 | ||
1450 | if (cd == NULL) { | ||
1451 | dev_err(cd->dev, "%s: NULL context pointer\n", __func__); | ||
1452 | return; | ||
1453 | } | ||
1454 | |||
1455 | mutex_lock(&cd->system_lock); | 1450 | mutex_lock(&cd->system_lock); |
1456 | retval = cyttsp4_load_status_regs(cd); | 1451 | retval = cyttsp4_load_status_regs(cd); |
1457 | if (retval < 0) { | 1452 | if (retval < 0) { |
@@ -2027,7 +2022,7 @@ struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, | |||
2027 | if (!cd->xfer_buf) { | 2022 | if (!cd->xfer_buf) { |
2028 | dev_err(dev, "%s: Error, kzalloc\n", __func__); | 2023 | dev_err(dev, "%s: Error, kzalloc\n", __func__); |
2029 | rc = -ENOMEM; | 2024 | rc = -ENOMEM; |
2030 | goto error_alloc_data; | 2025 | goto error_free_cd; |
2031 | } | 2026 | } |
2032 | 2027 | ||
2033 | /* Initialize device info */ | 2028 | /* Initialize device info */ |
@@ -2051,7 +2046,7 @@ struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, | |||
2051 | cd->irq = gpio_to_irq(cd->cpdata->irq_gpio); | 2046 | cd->irq = gpio_to_irq(cd->cpdata->irq_gpio); |
2052 | if (cd->irq < 0) { | 2047 | if (cd->irq < 0) { |
2053 | rc = -EINVAL; | 2048 | rc = -EINVAL; |
2054 | goto error_gpio_irq; | 2049 | goto error_free_xfer; |
2055 | } | 2050 | } |
2056 | 2051 | ||
2057 | dev_set_drvdata(dev, cd); | 2052 | dev_set_drvdata(dev, cd); |
@@ -2119,7 +2114,9 @@ error_request_irq: | |||
2119 | if (cd->cpdata->init) | 2114 | if (cd->cpdata->init) |
2120 | cd->cpdata->init(cd->cpdata, 0, dev); | 2115 | cd->cpdata->init(cd->cpdata, 0, dev); |
2121 | dev_set_drvdata(dev, NULL); | 2116 | dev_set_drvdata(dev, NULL); |
2122 | error_gpio_irq: | 2117 | error_free_xfer: |
2118 | kfree(cd->xfer_buf); | ||
2119 | error_free_cd: | ||
2123 | kfree(cd); | 2120 | kfree(cd); |
2124 | error_alloc_data: | 2121 | error_alloc_data: |
2125 | error_no_pdata: | 2122 | error_no_pdata: |
diff --git a/drivers/input/touchscreen/cyttsp4_core.h b/drivers/input/touchscreen/cyttsp4_core.h index 86a254354136..8e0d4d490b20 100644 --- a/drivers/input/touchscreen/cyttsp4_core.h +++ b/drivers/input/touchscreen/cyttsp4_core.h | |||
@@ -369,9 +369,9 @@ struct cyttsp4 { | |||
369 | 369 | ||
370 | struct cyttsp4_bus_ops { | 370 | struct cyttsp4_bus_ops { |
371 | u16 bustype; | 371 | u16 bustype; |
372 | int (*write)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 372 | int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
373 | const void *values); | 373 | const void *values); |
374 | int (*read)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 374 | int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
375 | void *values); | 375 | void *values); |
376 | }; | 376 | }; |
377 | 377 | ||
@@ -448,13 +448,13 @@ enum cyttsp4_event_id { | |||
448 | /* y-axis, 0:origin is on top side of panel, 1: bottom */ | 448 | /* y-axis, 0:origin is on top side of panel, 1: bottom */ |
449 | #define CY_PCFG_ORIGIN_Y_MASK 0x80 | 449 | #define CY_PCFG_ORIGIN_Y_MASK 0x80 |
450 | 450 | ||
451 | static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u8 addr, int size, | 451 | static inline int cyttsp4_adap_read(struct cyttsp4 *ts, u16 addr, int size, |
452 | void *buf) | 452 | void *buf) |
453 | { | 453 | { |
454 | return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf); | 454 | return ts->bus_ops->read(ts->dev, ts->xfer_buf, addr, size, buf); |
455 | } | 455 | } |
456 | 456 | ||
457 | static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u8 addr, int size, | 457 | static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u16 addr, int size, |
458 | const void *buf) | 458 | const void *buf) |
459 | { | 459 | { |
460 | return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf); | 460 | return ts->bus_ops->write(ts->dev, ts->xfer_buf, addr, size, buf); |
@@ -463,9 +463,9 @@ static inline int cyttsp4_adap_write(struct cyttsp4 *ts, u8 addr, int size, | |||
463 | extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, | 463 | extern struct cyttsp4 *cyttsp4_probe(const struct cyttsp4_bus_ops *ops, |
464 | struct device *dev, u16 irq, size_t xfer_buf_size); | 464 | struct device *dev, u16 irq, size_t xfer_buf_size); |
465 | extern int cyttsp4_remove(struct cyttsp4 *ts); | 465 | extern int cyttsp4_remove(struct cyttsp4 *ts); |
466 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 466 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
467 | u8 length, const void *values); | 467 | u8 length, const void *values); |
468 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 468 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
469 | u8 length, void *values); | 469 | u8 length, void *values); |
470 | extern const struct dev_pm_ops cyttsp4_pm_ops; | 470 | extern const struct dev_pm_ops cyttsp4_pm_ops; |
471 | 471 | ||
diff --git a/drivers/input/touchscreen/cyttsp4_spi.c b/drivers/input/touchscreen/cyttsp4_spi.c index f8f891bead34..a71e1141d638 100644 --- a/drivers/input/touchscreen/cyttsp4_spi.c +++ b/drivers/input/touchscreen/cyttsp4_spi.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE) | 44 | #define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE) |
45 | 45 | ||
46 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | 46 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, |
47 | u8 op, u8 reg, u8 *buf, int length) | 47 | u8 op, u16 reg, u8 *buf, int length) |
48 | { | 48 | { |
49 | struct spi_device *spi = to_spi_device(dev); | 49 | struct spi_device *spi = to_spi_device(dev); |
50 | struct spi_message msg; | 50 | struct spi_message msg; |
@@ -63,14 +63,12 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | |||
63 | memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE); | 63 | memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE); |
64 | memset(rd_buf, 0, CY_SPI_CMD_BYTES); | 64 | memset(rd_buf, 0, CY_SPI_CMD_BYTES); |
65 | 65 | ||
66 | if (reg > 255) | 66 | wr_buf[0] = op + (((reg >> 8) & 0x1) ? CY_SPI_A8_BIT : 0); |
67 | wr_buf[0] = op + CY_SPI_A8_BIT; | 67 | if (op == CY_SPI_WR_OP) { |
68 | else | 68 | wr_buf[1] = reg & 0xFF; |
69 | wr_buf[0] = op; | 69 | if (length > 0) |
70 | if (op == CY_SPI_WR_OP) | 70 | memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length); |
71 | wr_buf[1] = reg % 256; | 71 | } |
72 | if (op == CY_SPI_WR_OP && length > 0) | ||
73 | memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length); | ||
74 | 72 | ||
75 | memset(xfer, 0, sizeof(xfer)); | 73 | memset(xfer, 0, sizeof(xfer)); |
76 | spi_message_init(&msg); | 74 | spi_message_init(&msg); |
@@ -130,7 +128,7 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | |||
130 | } | 128 | } |
131 | 129 | ||
132 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, | 130 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, |
133 | u8 addr, u8 length, void *data) | 131 | u16 addr, u8 length, void *data) |
134 | { | 132 | { |
135 | int rc; | 133 | int rc; |
136 | 134 | ||
@@ -143,7 +141,7 @@ static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, | |||
143 | } | 141 | } |
144 | 142 | ||
145 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, | 143 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, |
146 | u8 addr, u8 length, const void *data) | 144 | u16 addr, u8 length, const void *data) |
147 | { | 145 | { |
148 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, | 146 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, |
149 | length); | 147 | length); |
diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c index 4824fa343897..d53e0b72a407 100644 --- a/drivers/input/touchscreen/cyttsp_core.c +++ b/drivers/input/touchscreen/cyttsp_core.c | |||
@@ -118,6 +118,15 @@ static int ttsp_send_command(struct cyttsp *ts, u8 cmd) | |||
118 | return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); | 118 | return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); |
119 | } | 119 | } |
120 | 120 | ||
121 | static int cyttsp_handshake(struct cyttsp *ts) | ||
122 | { | ||
123 | if (ts->pdata->use_hndshk) | ||
124 | return ttsp_send_command(ts, | ||
125 | ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
121 | static int cyttsp_load_bl_regs(struct cyttsp *ts) | 130 | static int cyttsp_load_bl_regs(struct cyttsp *ts) |
122 | { | 131 | { |
123 | memset(&ts->bl_data, 0, sizeof(ts->bl_data)); | 132 | memset(&ts->bl_data, 0, sizeof(ts->bl_data)); |
@@ -135,7 +144,7 @@ static int cyttsp_exit_bl_mode(struct cyttsp *ts) | |||
135 | memcpy(bl_cmd, bl_command, sizeof(bl_command)); | 144 | memcpy(bl_cmd, bl_command, sizeof(bl_command)); |
136 | if (ts->pdata->bl_keys) | 145 | if (ts->pdata->bl_keys) |
137 | memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], | 146 | memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], |
138 | ts->pdata->bl_keys, sizeof(bl_command)); | 147 | ts->pdata->bl_keys, CY_NUM_BL_KEYS); |
139 | 148 | ||
140 | error = ttsp_write_block_data(ts, CY_REG_BASE, | 149 | error = ttsp_write_block_data(ts, CY_REG_BASE, |
141 | sizeof(bl_cmd), bl_cmd); | 150 | sizeof(bl_cmd), bl_cmd); |
@@ -169,6 +178,10 @@ static int cyttsp_set_operational_mode(struct cyttsp *ts) | |||
169 | if (error) | 178 | if (error) |
170 | return error; | 179 | return error; |
171 | 180 | ||
181 | error = cyttsp_handshake(ts); | ||
182 | if (error) | ||
183 | return error; | ||
184 | |||
172 | return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; | 185 | return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; |
173 | } | 186 | } |
174 | 187 | ||
@@ -190,6 +203,10 @@ static int cyttsp_set_sysinfo_mode(struct cyttsp *ts) | |||
190 | if (error) | 203 | if (error) |
191 | return error; | 204 | return error; |
192 | 205 | ||
206 | error = cyttsp_handshake(ts); | ||
207 | if (error) | ||
208 | return error; | ||
209 | |||
193 | if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) | 210 | if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) |
194 | return -EIO; | 211 | return -EIO; |
195 | 212 | ||
@@ -346,12 +363,9 @@ static irqreturn_t cyttsp_irq(int irq, void *handle) | |||
346 | goto out; | 363 | goto out; |
347 | 364 | ||
348 | /* provide flow control handshake */ | 365 | /* provide flow control handshake */ |
349 | if (ts->pdata->use_hndshk) { | 366 | error = cyttsp_handshake(ts); |
350 | error = ttsp_send_command(ts, | 367 | if (error) |
351 | ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); | 368 | goto out; |
352 | if (error) | ||
353 | goto out; | ||
354 | } | ||
355 | 369 | ||
356 | if (unlikely(ts->state == CY_IDLE_STATE)) | 370 | if (unlikely(ts->state == CY_IDLE_STATE)) |
357 | goto out; | 371 | goto out; |
diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h index d0c9e488b05d..07074110a902 100644 --- a/drivers/input/touchscreen/cyttsp_core.h +++ b/drivers/input/touchscreen/cyttsp_core.h | |||
@@ -67,8 +67,8 @@ struct cyttsp_xydata { | |||
67 | /* TTSP System Information interface definition */ | 67 | /* TTSP System Information interface definition */ |
68 | struct cyttsp_sysinfo_data { | 68 | struct cyttsp_sysinfo_data { |
69 | u8 hst_mode; | 69 | u8 hst_mode; |
70 | u8 mfg_cmd; | ||
71 | u8 mfg_stat; | 70 | u8 mfg_stat; |
71 | u8 mfg_cmd; | ||
72 | u8 cid[3]; | 72 | u8 cid[3]; |
73 | u8 tt_undef1; | 73 | u8 tt_undef1; |
74 | u8 uid[8]; | 74 | u8 uid[8]; |
@@ -112,9 +112,9 @@ struct cyttsp; | |||
112 | 112 | ||
113 | struct cyttsp_bus_ops { | 113 | struct cyttsp_bus_ops { |
114 | u16 bustype; | 114 | u16 bustype; |
115 | int (*write)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 115 | int (*write)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
116 | const void *values); | 116 | const void *values); |
117 | int (*read)(struct device *dev, u8 *xfer_buf, u8 addr, u8 length, | 117 | int (*read)(struct device *dev, u8 *xfer_buf, u16 addr, u8 length, |
118 | void *values); | 118 | void *values); |
119 | }; | 119 | }; |
120 | 120 | ||
@@ -145,9 +145,9 @@ struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, | |||
145 | struct device *dev, int irq, size_t xfer_buf_size); | 145 | struct device *dev, int irq, size_t xfer_buf_size); |
146 | void cyttsp_remove(struct cyttsp *ts); | 146 | void cyttsp_remove(struct cyttsp *ts); |
147 | 147 | ||
148 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 148 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
149 | u8 length, const void *values); | 149 | u8 length, const void *values); |
150 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u8 addr, | 150 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, u16 addr, |
151 | u8 length, void *values); | 151 | u8 length, void *values); |
152 | extern const struct dev_pm_ops cyttsp_pm_ops; | 152 | extern const struct dev_pm_ops cyttsp_pm_ops; |
153 | 153 | ||
diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c index 07c553fbcef2..1d7b6f154168 100644 --- a/drivers/input/touchscreen/cyttsp_i2c_common.c +++ b/drivers/input/touchscreen/cyttsp_i2c_common.c | |||
@@ -32,18 +32,20 @@ | |||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | 33 | ||
34 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, | 34 | int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, |
35 | u8 addr, u8 length, void *values) | 35 | u16 addr, u8 length, void *values) |
36 | { | 36 | { |
37 | struct i2c_client *client = to_i2c_client(dev); | 37 | struct i2c_client *client = to_i2c_client(dev); |
38 | u8 client_addr = client->addr | ((addr >> 8) & 0x1); | ||
39 | u8 addr_lo = addr & 0xFF; | ||
38 | struct i2c_msg msgs[] = { | 40 | struct i2c_msg msgs[] = { |
39 | { | 41 | { |
40 | .addr = client->addr, | 42 | .addr = client_addr, |
41 | .flags = 0, | 43 | .flags = 0, |
42 | .len = 1, | 44 | .len = 1, |
43 | .buf = &addr, | 45 | .buf = &addr_lo, |
44 | }, | 46 | }, |
45 | { | 47 | { |
46 | .addr = client->addr, | 48 | .addr = client_addr, |
47 | .flags = I2C_M_RD, | 49 | .flags = I2C_M_RD, |
48 | .len = length, | 50 | .len = length, |
49 | .buf = values, | 51 | .buf = values, |
@@ -60,17 +62,29 @@ int cyttsp_i2c_read_block_data(struct device *dev, u8 *xfer_buf, | |||
60 | EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data); | 62 | EXPORT_SYMBOL_GPL(cyttsp_i2c_read_block_data); |
61 | 63 | ||
62 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, | 64 | int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf, |
63 | u8 addr, u8 length, const void *values) | 65 | u16 addr, u8 length, const void *values) |
64 | { | 66 | { |
65 | struct i2c_client *client = to_i2c_client(dev); | 67 | struct i2c_client *client = to_i2c_client(dev); |
68 | u8 client_addr = client->addr | ((addr >> 8) & 0x1); | ||
69 | u8 addr_lo = addr & 0xFF; | ||
70 | struct i2c_msg msgs[] = { | ||
71 | { | ||
72 | .addr = client_addr, | ||
73 | .flags = 0, | ||
74 | .len = length + 1, | ||
75 | .buf = xfer_buf, | ||
76 | }, | ||
77 | }; | ||
66 | int retval; | 78 | int retval; |
67 | 79 | ||
68 | xfer_buf[0] = addr; | 80 | xfer_buf[0] = addr_lo; |
69 | memcpy(&xfer_buf[1], values, length); | 81 | memcpy(&xfer_buf[1], values, length); |
70 | 82 | ||
71 | retval = i2c_master_send(client, xfer_buf, length + 1); | 83 | retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); |
84 | if (retval < 0) | ||
85 | return retval; | ||
72 | 86 | ||
73 | return retval < 0 ? retval : 0; | 87 | return retval != ARRAY_SIZE(msgs) ? -EIO : 0; |
74 | } | 88 | } |
75 | EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data); | 89 | EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data); |
76 | 90 | ||
diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c index 1df625337b84..4728bcb1916c 100644 --- a/drivers/input/touchscreen/cyttsp_spi.c +++ b/drivers/input/touchscreen/cyttsp_spi.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #define CY_SPI_BITS_PER_WORD 8 | 41 | #define CY_SPI_BITS_PER_WORD 8 |
42 | 42 | ||
43 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | 43 | static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, |
44 | u8 op, u8 reg, u8 *buf, int length) | 44 | u8 op, u16 reg, u8 *buf, int length) |
45 | { | 45 | { |
46 | struct spi_device *spi = to_spi_device(dev); | 46 | struct spi_device *spi = to_spi_device(dev); |
47 | struct spi_message msg; | 47 | struct spi_message msg; |
@@ -126,14 +126,14 @@ static int cyttsp_spi_xfer(struct device *dev, u8 *xfer_buf, | |||
126 | } | 126 | } |
127 | 127 | ||
128 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, | 128 | static int cyttsp_spi_read_block_data(struct device *dev, u8 *xfer_buf, |
129 | u8 addr, u8 length, void *data) | 129 | u16 addr, u8 length, void *data) |
130 | { | 130 | { |
131 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data, | 131 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_RD_OP, addr, data, |
132 | length); | 132 | length); |
133 | } | 133 | } |
134 | 134 | ||
135 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, | 135 | static int cyttsp_spi_write_block_data(struct device *dev, u8 *xfer_buf, |
136 | u8 addr, u8 length, const void *data) | 136 | u16 addr, u8 length, const void *data) |
137 | { | 137 | { |
138 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, | 138 | return cyttsp_spi_xfer(dev, xfer_buf, CY_SPI_WR_OP, addr, (void *)data, |
139 | length); | 139 | length); |
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 50fb1293874e..e1c5300cacfc 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c | |||
@@ -24,8 +24,9 @@ | |||
24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/input/ti_am335x_tsc.h> | ||
28 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/of_device.h> | ||
29 | 30 | ||
30 | #include <linux/mfd/ti_am335x_tscadc.h> | 31 | #include <linux/mfd/ti_am335x_tscadc.h> |
31 | 32 | ||
@@ -33,6 +34,13 @@ | |||
33 | #define SEQ_SETTLE 275 | 34 | #define SEQ_SETTLE 275 |
34 | #define MAX_12BIT ((1 << 12) - 1) | 35 | #define MAX_12BIT ((1 << 12) - 1) |
35 | 36 | ||
37 | static const int config_pins[] = { | ||
38 | STEPCONFIG_XPP, | ||
39 | STEPCONFIG_XNN, | ||
40 | STEPCONFIG_YPP, | ||
41 | STEPCONFIG_YNN, | ||
42 | }; | ||
43 | |||
36 | struct titsc { | 44 | struct titsc { |
37 | struct input_dev *input; | 45 | struct input_dev *input; |
38 | struct ti_tscadc_dev *mfd_tscadc; | 46 | struct ti_tscadc_dev *mfd_tscadc; |
@@ -40,7 +48,10 @@ struct titsc { | |||
40 | unsigned int wires; | 48 | unsigned int wires; |
41 | unsigned int x_plate_resistance; | 49 | unsigned int x_plate_resistance; |
42 | bool pen_down; | 50 | bool pen_down; |
43 | int steps_to_configure; | 51 | int coordinate_readouts; |
52 | u32 config_inp[4]; | ||
53 | u32 bit_xp, bit_xn, bit_yp, bit_yn; | ||
54 | u32 inp_xp, inp_xn, inp_yp, inp_yn; | ||
44 | }; | 55 | }; |
45 | 56 | ||
46 | static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) | 57 | static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) |
@@ -54,92 +65,153 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg, | |||
54 | writel(val, tsc->mfd_tscadc->tscadc_base + reg); | 65 | writel(val, tsc->mfd_tscadc->tscadc_base + reg); |
55 | } | 66 | } |
56 | 67 | ||
68 | static int titsc_config_wires(struct titsc *ts_dev) | ||
69 | { | ||
70 | u32 analog_line[4]; | ||
71 | u32 wire_order[4]; | ||
72 | int i, bit_cfg; | ||
73 | |||
74 | for (i = 0; i < 4; i++) { | ||
75 | /* | ||
76 | * Get the order in which TSC wires are attached | ||
77 | * w.r.t. each of the analog input lines on the EVM. | ||
78 | */ | ||
79 | analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4; | ||
80 | wire_order[i] = ts_dev->config_inp[i] & 0x0F; | ||
81 | if (WARN_ON(analog_line[i] > 7)) | ||
82 | return -EINVAL; | ||
83 | if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins))) | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | for (i = 0; i < 4; i++) { | ||
88 | int an_line; | ||
89 | int wi_order; | ||
90 | |||
91 | an_line = analog_line[i]; | ||
92 | wi_order = wire_order[i]; | ||
93 | bit_cfg = config_pins[wi_order]; | ||
94 | if (bit_cfg == 0) | ||
95 | return -EINVAL; | ||
96 | switch (wi_order) { | ||
97 | case 0: | ||
98 | ts_dev->bit_xp = bit_cfg; | ||
99 | ts_dev->inp_xp = an_line; | ||
100 | break; | ||
101 | |||
102 | case 1: | ||
103 | ts_dev->bit_xn = bit_cfg; | ||
104 | ts_dev->inp_xn = an_line; | ||
105 | break; | ||
106 | |||
107 | case 2: | ||
108 | ts_dev->bit_yp = bit_cfg; | ||
109 | ts_dev->inp_yp = an_line; | ||
110 | break; | ||
111 | case 3: | ||
112 | ts_dev->bit_yn = bit_cfg; | ||
113 | ts_dev->inp_yn = an_line; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | return 0; | ||
118 | } | ||
119 | |||
57 | static void titsc_step_config(struct titsc *ts_dev) | 120 | static void titsc_step_config(struct titsc *ts_dev) |
58 | { | 121 | { |
59 | unsigned int config; | 122 | unsigned int config; |
60 | int i, total_steps; | 123 | int i; |
61 | 124 | int end_step; | |
62 | /* Configure the Step registers */ | 125 | u32 stepenable; |
63 | total_steps = 2 * ts_dev->steps_to_configure; | ||
64 | 126 | ||
65 | config = STEPCONFIG_MODE_HWSYNC | | 127 | config = STEPCONFIG_MODE_HWSYNC | |
66 | STEPCONFIG_AVG_16 | STEPCONFIG_XPP; | 128 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; |
67 | switch (ts_dev->wires) { | 129 | switch (ts_dev->wires) { |
68 | case 4: | 130 | case 4: |
69 | config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; | 131 | config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
70 | break; | 132 | break; |
71 | case 5: | 133 | case 5: |
72 | config |= STEPCONFIG_YNN | | 134 | config |= ts_dev->bit_yn | |
73 | STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | | 135 | STEPCONFIG_INP_AN4 | ts_dev->bit_xn | |
74 | STEPCONFIG_YPP; | 136 | ts_dev->bit_yp; |
75 | break; | 137 | break; |
76 | case 8: | 138 | case 8: |
77 | config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; | 139 | config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
78 | break; | 140 | break; |
79 | } | 141 | } |
80 | 142 | ||
81 | for (i = 1; i <= ts_dev->steps_to_configure; i++) { | 143 | /* 1 … coordinate_readouts is for X */ |
144 | end_step = ts_dev->coordinate_readouts; | ||
145 | for (i = 0; i < end_step; i++) { | ||
82 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 146 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
83 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 147 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
84 | } | 148 | } |
85 | 149 | ||
86 | config = 0; | 150 | config = 0; |
87 | config = STEPCONFIG_MODE_HWSYNC | | 151 | config = STEPCONFIG_MODE_HWSYNC | |
88 | STEPCONFIG_AVG_16 | STEPCONFIG_YNN | | 152 | STEPCONFIG_AVG_16 | ts_dev->bit_yn | |
89 | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; | 153 | STEPCONFIG_INM_ADCREFM; |
90 | switch (ts_dev->wires) { | 154 | switch (ts_dev->wires) { |
91 | case 4: | 155 | case 4: |
92 | config |= STEPCONFIG_YPP; | 156 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
93 | break; | 157 | break; |
94 | case 5: | 158 | case 5: |
95 | config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | | 159 | config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | |
96 | STEPCONFIG_XNP | STEPCONFIG_YPN; | 160 | ts_dev->bit_xn | ts_dev->bit_yp; |
97 | break; | 161 | break; |
98 | case 8: | 162 | case 8: |
99 | config |= STEPCONFIG_YPP; | 163 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
100 | break; | 164 | break; |
101 | } | 165 | } |
102 | 166 | ||
103 | for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) { | 167 | /* coordinate_readouts … coordinate_readouts * 2 is for Y */ |
168 | end_step = ts_dev->coordinate_readouts * 2; | ||
169 | for (i = ts_dev->coordinate_readouts; i < end_step; i++) { | ||
104 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 170 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
105 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 171 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
106 | } | 172 | } |
107 | 173 | ||
108 | config = 0; | ||
109 | /* Charge step configuration */ | 174 | /* Charge step configuration */ |
110 | config = STEPCONFIG_XPP | STEPCONFIG_YNN | | 175 | config = ts_dev->bit_xp | ts_dev->bit_yn | |
111 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | | 176 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | |
112 | STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; | 177 | STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); |
113 | 178 | ||
114 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); | 179 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); |
115 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); | 180 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); |
116 | 181 | ||
117 | config = 0; | 182 | /* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */ |
118 | /* Configure to calculate pressure */ | ||
119 | config = STEPCONFIG_MODE_HWSYNC | | 183 | config = STEPCONFIG_MODE_HWSYNC | |
120 | STEPCONFIG_AVG_16 | STEPCONFIG_YPP | | 184 | STEPCONFIG_AVG_16 | ts_dev->bit_yp | |
121 | STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; | 185 | ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | |
122 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); | 186 | STEPCONFIG_INP(ts_dev->inp_xp); |
123 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), | 187 | titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); |
188 | titsc_writel(ts_dev, REG_STEPDELAY(end_step), | ||
124 | STEPCONFIG_OPENDLY); | 189 | STEPCONFIG_OPENDLY); |
125 | 190 | ||
126 | config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; | 191 | end_step++; |
127 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); | 192 | config |= STEPCONFIG_INP(ts_dev->inp_yn); |
128 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), | 193 | titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); |
194 | titsc_writel(ts_dev, REG_STEPDELAY(end_step), | ||
129 | STEPCONFIG_OPENDLY); | 195 | STEPCONFIG_OPENDLY); |
130 | 196 | ||
131 | titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); | 197 | /* The steps1 … end and bit 0 for TS_Charge */ |
198 | stepenable = (1 << (end_step + 2)) - 1; | ||
199 | am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable); | ||
132 | } | 200 | } |
133 | 201 | ||
134 | static void titsc_read_coordinates(struct titsc *ts_dev, | 202 | static void titsc_read_coordinates(struct titsc *ts_dev, |
135 | unsigned int *x, unsigned int *y) | 203 | u32 *x, u32 *y, u32 *z1, u32 *z2) |
136 | { | 204 | { |
137 | unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); | 205 | unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); |
138 | unsigned int prev_val_x = ~0, prev_val_y = ~0; | 206 | unsigned int prev_val_x = ~0, prev_val_y = ~0; |
139 | unsigned int prev_diff_x = ~0, prev_diff_y = ~0; | 207 | unsigned int prev_diff_x = ~0, prev_diff_y = ~0; |
140 | unsigned int read, diff; | 208 | unsigned int read, diff; |
141 | unsigned int i, channel; | 209 | unsigned int i, channel; |
210 | unsigned int creads = ts_dev->coordinate_readouts; | ||
142 | 211 | ||
212 | *z1 = *z2 = 0; | ||
213 | if (fifocount % (creads * 2 + 2)) | ||
214 | fifocount -= fifocount % (creads * 2 + 2); | ||
143 | /* | 215 | /* |
144 | * Delta filter is used to remove large variations in sampled | 216 | * Delta filter is used to remove large variations in sampled |
145 | * values from ADC. The filter tries to predict where the next | 217 | * values from ADC. The filter tries to predict where the next |
@@ -148,32 +220,32 @@ static void titsc_read_coordinates(struct titsc *ts_dev, | |||
148 | * algorithm compares the difference with that of a present value, | 220 | * algorithm compares the difference with that of a present value, |
149 | * if true the value is reported to the sub system. | 221 | * if true the value is reported to the sub system. |
150 | */ | 222 | */ |
151 | for (i = 0; i < fifocount - 1; i++) { | 223 | for (i = 0; i < fifocount; i++) { |
152 | read = titsc_readl(ts_dev, REG_FIFO0); | 224 | read = titsc_readl(ts_dev, REG_FIFO0); |
153 | channel = read & 0xf0000; | 225 | |
154 | channel = channel >> 0x10; | 226 | channel = (read & 0xf0000) >> 16; |
155 | if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) { | 227 | read &= 0xfff; |
156 | read &= 0xfff; | 228 | if (channel < creads) { |
157 | diff = abs(read - prev_val_x); | 229 | diff = abs(read - prev_val_x); |
158 | if (diff < prev_diff_x) { | 230 | if (diff < prev_diff_x) { |
159 | prev_diff_x = diff; | 231 | prev_diff_x = diff; |
160 | *x = read; | 232 | *x = read; |
161 | } | 233 | } |
162 | prev_val_x = read; | 234 | prev_val_x = read; |
163 | } | ||
164 | 235 | ||
165 | read = titsc_readl(ts_dev, REG_FIFO1); | 236 | } else if (channel < creads * 2) { |
166 | channel = read & 0xf0000; | ||
167 | channel = channel >> 0x10; | ||
168 | if ((channel >= ts_dev->steps_to_configure) && | ||
169 | (channel < (2 * ts_dev->steps_to_configure - 1))) { | ||
170 | read &= 0xfff; | ||
171 | diff = abs(read - prev_val_y); | 237 | diff = abs(read - prev_val_y); |
172 | if (diff < prev_diff_y) { | 238 | if (diff < prev_diff_y) { |
173 | prev_diff_y = diff; | 239 | prev_diff_y = diff; |
174 | *y = read; | 240 | *y = read; |
175 | } | 241 | } |
176 | prev_val_y = read; | 242 | prev_val_y = read; |
243 | |||
244 | } else if (channel < creads * 2 + 1) { | ||
245 | *z1 = read; | ||
246 | |||
247 | } else if (channel < creads * 2 + 2) { | ||
248 | *z2 = read; | ||
177 | } | 249 | } |
178 | } | 250 | } |
179 | } | 251 | } |
@@ -186,23 +258,11 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
186 | unsigned int x = 0, y = 0; | 258 | unsigned int x = 0, y = 0; |
187 | unsigned int z1, z2, z; | 259 | unsigned int z1, z2, z; |
188 | unsigned int fsm; | 260 | unsigned int fsm; |
189 | unsigned int fifo1count, fifo0count; | ||
190 | int i; | ||
191 | 261 | ||
192 | status = titsc_readl(ts_dev, REG_IRQSTATUS); | 262 | status = titsc_readl(ts_dev, REG_IRQSTATUS); |
193 | if (status & IRQENB_FIFO0THRES) { | 263 | if (status & IRQENB_FIFO0THRES) { |
194 | titsc_read_coordinates(ts_dev, &x, &y); | ||
195 | 264 | ||
196 | z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff; | 265 | titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2); |
197 | z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff; | ||
198 | |||
199 | fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT); | ||
200 | for (i = 0; i < fifo1count; i++) | ||
201 | titsc_readl(ts_dev, REG_FIFO1); | ||
202 | |||
203 | fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT); | ||
204 | for (i = 0; i < fifo0count; i++) | ||
205 | titsc_readl(ts_dev, REG_FIFO0); | ||
206 | 266 | ||
207 | if (ts_dev->pen_down && z1 != 0 && z2 != 0) { | 267 | if (ts_dev->pen_down && z1 != 0 && z2 != 0) { |
208 | /* | 268 | /* |
@@ -210,10 +270,10 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
210 | * Resistance(touch) = x plate resistance * | 270 | * Resistance(touch) = x plate resistance * |
211 | * x postion/4096 * ((z2 / z1) - 1) | 271 | * x postion/4096 * ((z2 / z1) - 1) |
212 | */ | 272 | */ |
213 | z = z2 - z1; | 273 | z = z1 - z2; |
214 | z *= x; | 274 | z *= x; |
215 | z *= ts_dev->x_plate_resistance; | 275 | z *= ts_dev->x_plate_resistance; |
216 | z /= z1; | 276 | z /= z2; |
217 | z = (z + 2047) >> 12; | 277 | z = (z + 2047) >> 12; |
218 | 278 | ||
219 | if (z <= MAX_12BIT) { | 279 | if (z <= MAX_12BIT) { |
@@ -248,10 +308,53 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
248 | irqclr |= IRQENB_PENUP; | 308 | irqclr |= IRQENB_PENUP; |
249 | } | 309 | } |
250 | 310 | ||
251 | titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); | 311 | if (status & IRQENB_HW_PEN) { |
312 | |||
313 | titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00); | ||
314 | titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); | ||
315 | } | ||
252 | 316 | ||
253 | titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); | 317 | if (irqclr) { |
254 | return IRQ_HANDLED; | 318 | titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); |
319 | am335x_tsc_se_update(ts_dev->mfd_tscadc); | ||
320 | return IRQ_HANDLED; | ||
321 | } | ||
322 | return IRQ_NONE; | ||
323 | } | ||
324 | |||
325 | static int titsc_parse_dt(struct platform_device *pdev, | ||
326 | struct titsc *ts_dev) | ||
327 | { | ||
328 | struct device_node *node = pdev->dev.of_node; | ||
329 | int err; | ||
330 | |||
331 | if (!node) | ||
332 | return -EINVAL; | ||
333 | |||
334 | err = of_property_read_u32(node, "ti,wires", &ts_dev->wires); | ||
335 | if (err < 0) | ||
336 | return err; | ||
337 | switch (ts_dev->wires) { | ||
338 | case 4: | ||
339 | case 5: | ||
340 | case 8: | ||
341 | break; | ||
342 | default: | ||
343 | return -EINVAL; | ||
344 | } | ||
345 | |||
346 | err = of_property_read_u32(node, "ti,x-plate-resistance", | ||
347 | &ts_dev->x_plate_resistance); | ||
348 | if (err < 0) | ||
349 | return err; | ||
350 | |||
351 | err = of_property_read_u32(node, "ti,coordiante-readouts", | ||
352 | &ts_dev->coordinate_readouts); | ||
353 | if (err < 0) | ||
354 | return err; | ||
355 | |||
356 | return of_property_read_u32_array(node, "ti,wire-config", | ||
357 | ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp)); | ||
255 | } | 358 | } |
256 | 359 | ||
257 | /* | 360 | /* |
@@ -262,17 +365,9 @@ static int titsc_probe(struct platform_device *pdev) | |||
262 | { | 365 | { |
263 | struct titsc *ts_dev; | 366 | struct titsc *ts_dev; |
264 | struct input_dev *input_dev; | 367 | struct input_dev *input_dev; |
265 | struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; | 368 | struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev); |
266 | struct mfd_tscadc_board *pdata; | ||
267 | int err; | 369 | int err; |
268 | 370 | ||
269 | pdata = tscadc_dev->dev->platform_data; | ||
270 | |||
271 | if (!pdata) { | ||
272 | dev_err(&pdev->dev, "Could not find platform data\n"); | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | |||
276 | /* Allocate memory for device */ | 371 | /* Allocate memory for device */ |
277 | ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); | 372 | ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); |
278 | input_dev = input_allocate_device(); | 373 | input_dev = input_allocate_device(); |
@@ -286,9 +381,12 @@ static int titsc_probe(struct platform_device *pdev) | |||
286 | ts_dev->mfd_tscadc = tscadc_dev; | 381 | ts_dev->mfd_tscadc = tscadc_dev; |
287 | ts_dev->input = input_dev; | 382 | ts_dev->input = input_dev; |
288 | ts_dev->irq = tscadc_dev->irq; | 383 | ts_dev->irq = tscadc_dev->irq; |
289 | ts_dev->wires = pdata->tsc_init->wires; | 384 | |
290 | ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; | 385 | err = titsc_parse_dt(pdev, ts_dev); |
291 | ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; | 386 | if (err) { |
387 | dev_err(&pdev->dev, "Could not find valid DT data.\n"); | ||
388 | goto err_free_mem; | ||
389 | } | ||
292 | 390 | ||
293 | err = request_irq(ts_dev->irq, titsc_irq, | 391 | err = request_irq(ts_dev->irq, titsc_irq, |
294 | 0, pdev->dev.driver->name, ts_dev); | 392 | 0, pdev->dev.driver->name, ts_dev); |
@@ -298,8 +396,14 @@ static int titsc_probe(struct platform_device *pdev) | |||
298 | } | 396 | } |
299 | 397 | ||
300 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); | 398 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); |
399 | err = titsc_config_wires(ts_dev); | ||
400 | if (err) { | ||
401 | dev_err(&pdev->dev, "wrong i/p wire configuration\n"); | ||
402 | goto err_free_irq; | ||
403 | } | ||
301 | titsc_step_config(ts_dev); | 404 | titsc_step_config(ts_dev); |
302 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); | 405 | titsc_writel(ts_dev, REG_FIFO0THR, |
406 | ts_dev->coordinate_readouts * 2 + 2 - 1); | ||
303 | 407 | ||
304 | input_dev->name = "ti-tsc"; | 408 | input_dev->name = "ti-tsc"; |
305 | input_dev->dev.parent = &pdev->dev; | 409 | input_dev->dev.parent = &pdev->dev; |
@@ -329,11 +433,16 @@ err_free_mem: | |||
329 | 433 | ||
330 | static int titsc_remove(struct platform_device *pdev) | 434 | static int titsc_remove(struct platform_device *pdev) |
331 | { | 435 | { |
332 | struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; | 436 | struct titsc *ts_dev = platform_get_drvdata(pdev); |
333 | struct titsc *ts_dev = tscadc_dev->tsc; | 437 | u32 steps; |
334 | 438 | ||
335 | free_irq(ts_dev->irq, ts_dev); | 439 | free_irq(ts_dev->irq, ts_dev); |
336 | 440 | ||
441 | /* total steps followed by the enable mask */ | ||
442 | steps = 2 * ts_dev->coordinate_readouts + 2; | ||
443 | steps = (1 << steps) - 1; | ||
444 | am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps); | ||
445 | |||
337 | input_unregister_device(ts_dev->input); | 446 | input_unregister_device(ts_dev->input); |
338 | 447 | ||
339 | kfree(ts_dev); | 448 | kfree(ts_dev); |
@@ -343,10 +452,11 @@ static int titsc_remove(struct platform_device *pdev) | |||
343 | #ifdef CONFIG_PM | 452 | #ifdef CONFIG_PM |
344 | static int titsc_suspend(struct device *dev) | 453 | static int titsc_suspend(struct device *dev) |
345 | { | 454 | { |
346 | struct ti_tscadc_dev *tscadc_dev = dev->platform_data; | 455 | struct titsc *ts_dev = dev_get_drvdata(dev); |
347 | struct titsc *ts_dev = tscadc_dev->tsc; | 456 | struct ti_tscadc_dev *tscadc_dev; |
348 | unsigned int idle; | 457 | unsigned int idle; |
349 | 458 | ||
459 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); | ||
350 | if (device_may_wakeup(tscadc_dev->dev)) { | 460 | if (device_may_wakeup(tscadc_dev->dev)) { |
351 | idle = titsc_readl(ts_dev, REG_IRQENABLE); | 461 | idle = titsc_readl(ts_dev, REG_IRQENABLE); |
352 | titsc_writel(ts_dev, REG_IRQENABLE, | 462 | titsc_writel(ts_dev, REG_IRQENABLE, |
@@ -358,9 +468,10 @@ static int titsc_suspend(struct device *dev) | |||
358 | 468 | ||
359 | static int titsc_resume(struct device *dev) | 469 | static int titsc_resume(struct device *dev) |
360 | { | 470 | { |
361 | struct ti_tscadc_dev *tscadc_dev = dev->platform_data; | 471 | struct titsc *ts_dev = dev_get_drvdata(dev); |
362 | struct titsc *ts_dev = tscadc_dev->tsc; | 472 | struct ti_tscadc_dev *tscadc_dev; |
363 | 473 | ||
474 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); | ||
364 | if (device_may_wakeup(tscadc_dev->dev)) { | 475 | if (device_may_wakeup(tscadc_dev->dev)) { |
365 | titsc_writel(ts_dev, REG_IRQWAKEUP, | 476 | titsc_writel(ts_dev, REG_IRQWAKEUP, |
366 | 0x00); | 477 | 0x00); |
@@ -368,7 +479,7 @@ static int titsc_resume(struct device *dev) | |||
368 | } | 479 | } |
369 | titsc_step_config(ts_dev); | 480 | titsc_step_config(ts_dev); |
370 | titsc_writel(ts_dev, REG_FIFO0THR, | 481 | titsc_writel(ts_dev, REG_FIFO0THR, |
371 | ts_dev->steps_to_configure); | 482 | ts_dev->coordinate_readouts * 2 + 2 - 1); |
372 | return 0; | 483 | return 0; |
373 | } | 484 | } |
374 | 485 | ||
@@ -381,13 +492,20 @@ static const struct dev_pm_ops titsc_pm_ops = { | |||
381 | #define TITSC_PM_OPS NULL | 492 | #define TITSC_PM_OPS NULL |
382 | #endif | 493 | #endif |
383 | 494 | ||
495 | static const struct of_device_id ti_tsc_dt_ids[] = { | ||
496 | { .compatible = "ti,am3359-tsc", }, | ||
497 | { } | ||
498 | }; | ||
499 | MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids); | ||
500 | |||
384 | static struct platform_driver ti_tsc_driver = { | 501 | static struct platform_driver ti_tsc_driver = { |
385 | .probe = titsc_probe, | 502 | .probe = titsc_probe, |
386 | .remove = titsc_remove, | 503 | .remove = titsc_remove, |
387 | .driver = { | 504 | .driver = { |
388 | .name = "tsc", | 505 | .name = "TI-am335x-tsc", |
389 | .owner = THIS_MODULE, | 506 | .owner = THIS_MODULE, |
390 | .pm = TITSC_PM_OPS, | 507 | .pm = TITSC_PM_OPS, |
508 | .of_match_table = of_match_ptr(ti_tsc_dt_ids), | ||
391 | }, | 509 | }, |
392 | }; | 510 | }; |
393 | module_platform_driver(ti_tsc_driver); | 511 | module_platform_driver(ti_tsc_driver); |
diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c index 820a066c3b8a..94cde2cb1491 100644 --- a/drivers/input/touchscreen/tps6507x-ts.c +++ b/drivers/input/touchscreen/tps6507x-ts.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/workqueue.h> | 17 | #include <linux/workqueue.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/input.h> | 19 | #include <linux/input.h> |
20 | #include <linux/input-polldev.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/mfd/tps6507x.h> | 22 | #include <linux/mfd/tps6507x.h> |
22 | #include <linux/input/tps6507x-ts.h> | 23 | #include <linux/input/tps6507x-ts.h> |
@@ -38,20 +39,13 @@ struct ts_event { | |||
38 | }; | 39 | }; |
39 | 40 | ||
40 | struct tps6507x_ts { | 41 | struct tps6507x_ts { |
41 | struct input_dev *input_dev; | ||
42 | struct device *dev; | 42 | struct device *dev; |
43 | struct input_polled_dev *poll_dev; | ||
44 | struct tps6507x_dev *mfd; | ||
43 | char phys[32]; | 45 | char phys[32]; |
44 | struct delayed_work work; | ||
45 | unsigned polling; /* polling is active */ | ||
46 | struct ts_event tc; | 46 | struct ts_event tc; |
47 | struct tps6507x_dev *mfd; | ||
48 | u16 model; | ||
49 | unsigned pendown; | ||
50 | int irq; | ||
51 | void (*clear_penirq)(void); | ||
52 | unsigned long poll_period; /* ms */ | ||
53 | u16 min_pressure; | 47 | u16 min_pressure; |
54 | int vref; /* non-zero to leave vref on */ | 48 | bool pendown; |
55 | }; | 49 | }; |
56 | 50 | ||
57 | static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) | 51 | static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) |
@@ -161,18 +155,15 @@ static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) | |||
161 | return ret; | 155 | return ret; |
162 | } | 156 | } |
163 | 157 | ||
164 | static void tps6507x_ts_handler(struct work_struct *work) | 158 | static void tps6507x_ts_poll(struct input_polled_dev *poll_dev) |
165 | { | 159 | { |
166 | struct tps6507x_ts *tsc = container_of(work, | 160 | struct tps6507x_ts *tsc = poll_dev->private; |
167 | struct tps6507x_ts, work.work); | 161 | struct input_dev *input_dev = poll_dev->input; |
168 | struct input_dev *input_dev = tsc->input_dev; | 162 | bool pendown; |
169 | int pendown; | ||
170 | int schd; | ||
171 | int poll = 0; | ||
172 | s32 ret; | 163 | s32 ret; |
173 | 164 | ||
174 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, | 165 | ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, |
175 | &tsc->tc.pressure); | 166 | &tsc->tc.pressure); |
176 | if (ret) | 167 | if (ret) |
177 | goto done; | 168 | goto done; |
178 | 169 | ||
@@ -183,7 +174,7 @@ static void tps6507x_ts_handler(struct work_struct *work) | |||
183 | input_report_key(input_dev, BTN_TOUCH, 0); | 174 | input_report_key(input_dev, BTN_TOUCH, 0); |
184 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 175 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
185 | input_sync(input_dev); | 176 | input_sync(input_dev); |
186 | tsc->pendown = 0; | 177 | tsc->pendown = false; |
187 | } | 178 | } |
188 | 179 | ||
189 | if (pendown) { | 180 | if (pendown) { |
@@ -208,76 +199,69 @@ static void tps6507x_ts_handler(struct work_struct *work) | |||
208 | input_report_abs(input_dev, ABS_Y, tsc->tc.y); | 199 | input_report_abs(input_dev, ABS_Y, tsc->tc.y); |
209 | input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); | 200 | input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); |
210 | input_sync(input_dev); | 201 | input_sync(input_dev); |
211 | tsc->pendown = 1; | 202 | tsc->pendown = true; |
212 | poll = 1; | ||
213 | } | 203 | } |
214 | 204 | ||
215 | done: | 205 | done: |
216 | /* always poll if not using interrupts */ | 206 | tps6507x_adc_standby(tsc); |
217 | poll = 1; | ||
218 | |||
219 | if (poll) { | ||
220 | schd = schedule_delayed_work(&tsc->work, | ||
221 | msecs_to_jiffies(tsc->poll_period)); | ||
222 | if (schd) | ||
223 | tsc->polling = 1; | ||
224 | else { | ||
225 | tsc->polling = 0; | ||
226 | dev_err(tsc->dev, "re-schedule failed"); | ||
227 | } | ||
228 | } else | ||
229 | tsc->polling = 0; | ||
230 | |||
231 | ret = tps6507x_adc_standby(tsc); | ||
232 | } | 207 | } |
233 | 208 | ||
234 | static int tps6507x_ts_probe(struct platform_device *pdev) | 209 | static int tps6507x_ts_probe(struct platform_device *pdev) |
235 | { | 210 | { |
236 | int error; | ||
237 | struct tps6507x_ts *tsc; | ||
238 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); | 211 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
239 | struct touchscreen_init_data *init_data; | 212 | const struct tps6507x_board *tps_board; |
213 | const struct touchscreen_init_data *init_data; | ||
214 | struct tps6507x_ts *tsc; | ||
215 | struct input_polled_dev *poll_dev; | ||
240 | struct input_dev *input_dev; | 216 | struct input_dev *input_dev; |
241 | struct tps6507x_board *tps_board; | 217 | int error; |
242 | int schd; | ||
243 | 218 | ||
244 | /** | 219 | /* |
245 | * tps_board points to pmic related constants | 220 | * tps_board points to pmic related constants |
246 | * coming from the board-evm file. | 221 | * coming from the board-evm file. |
247 | */ | 222 | */ |
248 | 223 | tps_board = dev_get_platdata(tps6507x_dev->dev); | |
249 | tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; | ||
250 | |||
251 | if (!tps_board) { | 224 | if (!tps_board) { |
252 | dev_err(tps6507x_dev->dev, | 225 | dev_err(tps6507x_dev->dev, |
253 | "Could not find tps6507x platform data\n"); | 226 | "Could not find tps6507x platform data\n"); |
254 | return -EIO; | 227 | return -ENODEV; |
255 | } | 228 | } |
256 | 229 | ||
257 | /** | 230 | /* |
258 | * init_data points to array of regulator_init structures | 231 | * init_data points to array of regulator_init structures |
259 | * coming from the board-evm file. | 232 | * coming from the board-evm file. |
260 | */ | 233 | */ |
261 | |||
262 | init_data = tps_board->tps6507x_ts_init_data; | 234 | init_data = tps_board->tps6507x_ts_init_data; |
263 | 235 | ||
264 | tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); | 236 | tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); |
265 | if (!tsc) { | 237 | if (!tsc) { |
266 | dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); | 238 | dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); |
267 | error = -ENOMEM; | 239 | return -ENOMEM; |
268 | goto err0; | ||
269 | } | 240 | } |
270 | 241 | ||
271 | tps6507x_dev->ts = tsc; | ||
272 | tsc->mfd = tps6507x_dev; | 242 | tsc->mfd = tps6507x_dev; |
273 | tsc->dev = tps6507x_dev->dev; | 243 | tsc->dev = tps6507x_dev->dev; |
274 | input_dev = input_allocate_device(); | 244 | tsc->min_pressure = init_data ? |
275 | if (!input_dev) { | 245 | init_data->min_pressure : TPS_DEFAULT_MIN_PRESSURE; |
276 | dev_err(tsc->dev, "Failed to allocate input device.\n"); | 246 | |
247 | snprintf(tsc->phys, sizeof(tsc->phys), | ||
248 | "%s/input0", dev_name(tsc->dev)); | ||
249 | |||
250 | poll_dev = input_allocate_polled_device(); | ||
251 | if (!poll_dev) { | ||
252 | dev_err(tsc->dev, "Failed to allocate polled input device.\n"); | ||
277 | error = -ENOMEM; | 253 | error = -ENOMEM; |
278 | goto err1; | 254 | goto err_free_mem; |
279 | } | 255 | } |
280 | 256 | ||
257 | tsc->poll_dev = poll_dev; | ||
258 | |||
259 | poll_dev->private = tsc; | ||
260 | poll_dev->poll = tps6507x_ts_poll; | ||
261 | poll_dev->poll_interval = init_data ? | ||
262 | init_data->poll_period : TSC_DEFAULT_POLL_PERIOD; | ||
263 | |||
264 | input_dev = poll_dev->input; | ||
281 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 265 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
282 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | 266 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); |
283 | 267 | ||
@@ -286,76 +270,42 @@ static int tps6507x_ts_probe(struct platform_device *pdev) | |||
286 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); | 270 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); |
287 | 271 | ||
288 | input_dev->name = "TPS6507x Touchscreen"; | 272 | input_dev->name = "TPS6507x Touchscreen"; |
289 | input_dev->id.bustype = BUS_I2C; | ||
290 | input_dev->dev.parent = tsc->dev; | ||
291 | |||
292 | snprintf(tsc->phys, sizeof(tsc->phys), | ||
293 | "%s/input0", dev_name(tsc->dev)); | ||
294 | input_dev->phys = tsc->phys; | 273 | input_dev->phys = tsc->phys; |
295 | 274 | input_dev->dev.parent = tsc->dev; | |
296 | dev_dbg(tsc->dev, "device: %s\n", input_dev->phys); | 275 | input_dev->id.bustype = BUS_I2C; |
297 | |||
298 | input_set_drvdata(input_dev, tsc); | ||
299 | |||
300 | tsc->input_dev = input_dev; | ||
301 | |||
302 | INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); | ||
303 | |||
304 | if (init_data) { | 276 | if (init_data) { |
305 | tsc->poll_period = init_data->poll_period; | ||
306 | tsc->vref = init_data->vref; | ||
307 | tsc->min_pressure = init_data->min_pressure; | ||
308 | input_dev->id.vendor = init_data->vendor; | 277 | input_dev->id.vendor = init_data->vendor; |
309 | input_dev->id.product = init_data->product; | 278 | input_dev->id.product = init_data->product; |
310 | input_dev->id.version = init_data->version; | 279 | input_dev->id.version = init_data->version; |
311 | } else { | ||
312 | tsc->poll_period = TSC_DEFAULT_POLL_PERIOD; | ||
313 | tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE; | ||
314 | } | 280 | } |
315 | 281 | ||
316 | error = tps6507x_adc_standby(tsc); | 282 | error = tps6507x_adc_standby(tsc); |
317 | if (error) | 283 | if (error) |
318 | goto err2; | 284 | goto err_free_polled_dev; |
319 | 285 | ||
320 | error = input_register_device(input_dev); | 286 | error = input_register_polled_device(poll_dev); |
321 | if (error) | 287 | if (error) |
322 | goto err2; | 288 | goto err_free_polled_dev; |
323 | 289 | ||
324 | schd = schedule_delayed_work(&tsc->work, | 290 | platform_set_drvdata(pdev, tsc); |
325 | msecs_to_jiffies(tsc->poll_period)); | ||
326 | |||
327 | if (schd) | ||
328 | tsc->polling = 1; | ||
329 | else { | ||
330 | tsc->polling = 0; | ||
331 | dev_err(tsc->dev, "schedule failed"); | ||
332 | goto err2; | ||
333 | } | ||
334 | platform_set_drvdata(pdev, tps6507x_dev); | ||
335 | 291 | ||
336 | return 0; | 292 | return 0; |
337 | 293 | ||
338 | err2: | 294 | err_free_polled_dev: |
339 | cancel_delayed_work_sync(&tsc->work); | 295 | input_free_polled_device(poll_dev); |
340 | input_free_device(input_dev); | 296 | err_free_mem: |
341 | err1: | ||
342 | kfree(tsc); | 297 | kfree(tsc); |
343 | tps6507x_dev->ts = NULL; | ||
344 | err0: | ||
345 | return error; | 298 | return error; |
346 | } | 299 | } |
347 | 300 | ||
348 | static int tps6507x_ts_remove(struct platform_device *pdev) | 301 | static int tps6507x_ts_remove(struct platform_device *pdev) |
349 | { | 302 | { |
350 | struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); | 303 | struct tps6507x_ts *tsc = platform_get_drvdata(pdev); |
351 | struct tps6507x_ts *tsc = tps6507x_dev->ts; | 304 | struct input_polled_dev *poll_dev = tsc->poll_dev; |
352 | struct input_dev *input_dev = tsc->input_dev; | ||
353 | |||
354 | cancel_delayed_work_sync(&tsc->work); | ||
355 | 305 | ||
356 | input_unregister_device(input_dev); | 306 | input_unregister_polled_device(poll_dev); |
307 | input_free_polled_device(poll_dev); | ||
357 | 308 | ||
358 | tps6507x_dev->ts = NULL; | ||
359 | kfree(tsc); | 309 | kfree(tsc); |
360 | 310 | ||
361 | return 0; | 311 | return 0; |