diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-15 20:16:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-15 20:16:28 -0400 |
commit | 2f39691f31a22e0c6d82573d91306059f8ef920c (patch) | |
tree | 6702165407caadb90325baf6042888f10343784a | |
parent | ffb29b42271c665cd652dfcaa590895c8a00ac97 (diff) | |
parent | 91167e1914673972511617b6f4165bb12c3e0dcf (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input layer fixes from Dmitry Torokhov:
"Second round of updates for the input subsystem. Mostly small fixups
to the code merged in the first round (atmel_mxt_ts, wacom) but also a
smallish patch to xbox driver to support Xbox One controllers and a
patch to better handle Synaptics profile sensors found in Cr-48
Chromebooks that should not affect any other devices"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: edt-ft5x06 - remove superfluous assignment
Input: xpad - add support for Xbox One controllers
Input: atmel_mxt_ts - fix a few issues reported by Coverity
Input: atmel_mxt_ts - split config update a bit
Input: atmel_mxt_ts - simplify mxt_initialize a bit
Input: joystick - use get_cycles on ARMv8
Input: wacom - fix compiler warning if !CONFIG_PM
Input: cap1106 - allow changing key mapping from userspace
Input: synaptics - use firmware data for Cr-48
Input: synaptics - properly initialize slots for semi-MT
Input: MT - make slot cleanup callable outside mt_sync_frame()
Input: atmel_mxt_ts - mXT224 DMA quirk was fixed in firmware v2.0.AA
-rw-r--r-- | drivers/hid/wacom_sys.c | 2 | ||||
-rw-r--r-- | drivers/input/input-mt.c | 38 | ||||
-rw-r--r-- | drivers/input/joystick/analog.c | 2 | ||||
-rw-r--r-- | drivers/input/joystick/xpad.c | 174 | ||||
-rw-r--r-- | drivers/input/keyboard/cap1106.c | 8 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 72 | ||||
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 366 | ||||
-rw-r--r-- | drivers/input/touchscreen/edt-ft5x06.c | 1 | ||||
-rw-r--r-- | include/linux/input/mt.h | 1 |
9 files changed, 462 insertions, 202 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 3e388ec31da8..f0db7eca9023 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c | |||
@@ -1416,6 +1416,7 @@ static void wacom_remove(struct hid_device *hdev) | |||
1416 | kfree(wacom); | 1416 | kfree(wacom); |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | #ifdef CONFIG_PM | ||
1419 | static int wacom_resume(struct hid_device *hdev) | 1420 | static int wacom_resume(struct hid_device *hdev) |
1420 | { | 1421 | { |
1421 | struct wacom *wacom = hid_get_drvdata(hdev); | 1422 | struct wacom *wacom = hid_get_drvdata(hdev); |
@@ -1436,6 +1437,7 @@ static int wacom_reset_resume(struct hid_device *hdev) | |||
1436 | { | 1437 | { |
1437 | return wacom_resume(hdev); | 1438 | return wacom_resume(hdev); |
1438 | } | 1439 | } |
1440 | #endif /* CONFIG_PM */ | ||
1439 | 1441 | ||
1440 | static struct hid_driver wacom_driver = { | 1442 | static struct hid_driver wacom_driver = { |
1441 | .name = "wacom", | 1443 | .name = "wacom", |
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index d398f1321f14..c30204f2fa30 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
@@ -237,6 +237,31 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count) | |||
237 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); | 237 | EXPORT_SYMBOL(input_mt_report_pointer_emulation); |
238 | 238 | ||
239 | /** | 239 | /** |
240 | * input_mt_drop_unused() - Inactivate slots not seen in this frame | ||
241 | * @dev: input device with allocated MT slots | ||
242 | * | ||
243 | * Lift all slots not seen since the last call to this function. | ||
244 | */ | ||
245 | void input_mt_drop_unused(struct input_dev *dev) | ||
246 | { | ||
247 | struct input_mt *mt = dev->mt; | ||
248 | int i; | ||
249 | |||
250 | if (!mt) | ||
251 | return; | ||
252 | |||
253 | for (i = 0; i < mt->num_slots; i++) { | ||
254 | if (!input_mt_is_used(mt, &mt->slots[i])) { | ||
255 | input_mt_slot(dev, i); | ||
256 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | mt->frame++; | ||
261 | } | ||
262 | EXPORT_SYMBOL(input_mt_drop_unused); | ||
263 | |||
264 | /** | ||
240 | * input_mt_sync_frame() - synchronize mt frame | 265 | * input_mt_sync_frame() - synchronize mt frame |
241 | * @dev: input device with allocated MT slots | 266 | * @dev: input device with allocated MT slots |
242 | * | 267 | * |
@@ -247,27 +272,18 @@ EXPORT_SYMBOL(input_mt_report_pointer_emulation); | |||
247 | void input_mt_sync_frame(struct input_dev *dev) | 272 | void input_mt_sync_frame(struct input_dev *dev) |
248 | { | 273 | { |
249 | struct input_mt *mt = dev->mt; | 274 | struct input_mt *mt = dev->mt; |
250 | struct input_mt_slot *s; | ||
251 | bool use_count = false; | 275 | bool use_count = false; |
252 | 276 | ||
253 | if (!mt) | 277 | if (!mt) |
254 | return; | 278 | return; |
255 | 279 | ||
256 | if (mt->flags & INPUT_MT_DROP_UNUSED) { | 280 | if (mt->flags & INPUT_MT_DROP_UNUSED) |
257 | for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { | 281 | input_mt_drop_unused(dev); |
258 | if (input_mt_is_used(mt, s)) | ||
259 | continue; | ||
260 | input_mt_slot(dev, s - mt->slots); | ||
261 | input_event(dev, EV_ABS, ABS_MT_TRACKING_ID, -1); | ||
262 | } | ||
263 | } | ||
264 | 282 | ||
265 | if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) | 283 | if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) |
266 | use_count = true; | 284 | use_count = true; |
267 | 285 | ||
268 | input_mt_report_pointer_emulation(dev, use_count); | 286 | input_mt_report_pointer_emulation(dev, use_count); |
269 | |||
270 | mt->frame++; | ||
271 | } | 287 | } |
272 | EXPORT_SYMBOL(input_mt_sync_frame); | 288 | EXPORT_SYMBOL(input_mt_sync_frame); |
273 | 289 | ||
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 9135606c8649..ab0fdcd36e18 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c | |||
@@ -158,7 +158,7 @@ static unsigned int get_time_pit(void) | |||
158 | #define GET_TIME(x) rdtscl(x) | 158 | #define GET_TIME(x) rdtscl(x) |
159 | #define DELTA(x,y) ((y)-(x)) | 159 | #define DELTA(x,y) ((y)-(x)) |
160 | #define TIME_NAME "TSC" | 160 | #define TIME_NAME "TSC" |
161 | #elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE) | 161 | #elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_TILE) |
162 | #define GET_TIME(x) do { x = get_cycles(); } while (0) | 162 | #define GET_TIME(x) do { x = get_cycles(); } while (0) |
163 | #define DELTA(x,y) ((y)-(x)) | 163 | #define DELTA(x,y) ((y)-(x)) |
164 | #define TIME_NAME "get_cycles" | 164 | #define TIME_NAME "get_cycles" |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 603fe0dd3682..177602cf7079 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -95,7 +95,8 @@ | |||
95 | #define XTYPE_XBOX 0 | 95 | #define XTYPE_XBOX 0 |
96 | #define XTYPE_XBOX360 1 | 96 | #define XTYPE_XBOX360 1 |
97 | #define XTYPE_XBOX360W 2 | 97 | #define XTYPE_XBOX360W 2 |
98 | #define XTYPE_UNKNOWN 3 | 98 | #define XTYPE_XBOXONE 3 |
99 | #define XTYPE_UNKNOWN 4 | ||
99 | 100 | ||
100 | static bool dpad_to_buttons; | 101 | static bool dpad_to_buttons; |
101 | module_param(dpad_to_buttons, bool, S_IRUGO); | 102 | module_param(dpad_to_buttons, bool, S_IRUGO); |
@@ -121,6 +122,7 @@ static const struct xpad_device { | |||
121 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, | 122 | { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, |
122 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, | 123 | { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", 0, XTYPE_XBOX }, |
123 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, | 124 | { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, |
125 | { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, | ||
124 | { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 126 | { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
125 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, | 127 | { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, |
126 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, | 128 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, |
@@ -231,10 +233,12 @@ static const signed short xpad_abs_triggers[] = { | |||
231 | -1 | 233 | -1 |
232 | }; | 234 | }; |
233 | 235 | ||
234 | /* Xbox 360 has a vendor-specific class, so we cannot match it with only | 236 | /* |
237 | * Xbox 360 has a vendor-specific class, so we cannot match it with only | ||
235 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we | 238 | * USB_INTERFACE_INFO (also specifically refused by USB subsystem), so we |
236 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, | 239 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
237 | * wireless controllers have protocol 129. */ | 240 | * wireless controllers have protocol 129. |
241 | */ | ||
238 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ | 242 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ |
239 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ | 243 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ |
240 | .idVendor = (vend), \ | 244 | .idVendor = (vend), \ |
@@ -245,9 +249,20 @@ static const signed short xpad_abs_triggers[] = { | |||
245 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ | 249 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ |
246 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } | 250 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } |
247 | 251 | ||
252 | /* The Xbox One controller uses subclass 71 and protocol 208. */ | ||
253 | #define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \ | ||
254 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ | ||
255 | .idVendor = (vend), \ | ||
256 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ | ||
257 | .bInterfaceSubClass = 71, \ | ||
258 | .bInterfaceProtocol = (pr) | ||
259 | #define XPAD_XBOXONE_VENDOR(vend) \ | ||
260 | { XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) } | ||
261 | |||
248 | static struct usb_device_id xpad_table[] = { | 262 | static struct usb_device_id xpad_table[] = { |
249 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ | 263 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ |
250 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ | 264 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ |
265 | XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ | ||
251 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ | 266 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ |
252 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ | 267 | XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ |
253 | { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ | 268 | { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ |
@@ -278,12 +293,10 @@ struct usb_xpad { | |||
278 | struct urb *bulk_out; | 293 | struct urb *bulk_out; |
279 | unsigned char *bdata; | 294 | unsigned char *bdata; |
280 | 295 | ||
281 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) | ||
282 | struct urb *irq_out; /* urb for interrupt out report */ | 296 | struct urb *irq_out; /* urb for interrupt out report */ |
283 | unsigned char *odata; /* output data */ | 297 | unsigned char *odata; /* output data */ |
284 | dma_addr_t odata_dma; | 298 | dma_addr_t odata_dma; |
285 | struct mutex odata_mutex; | 299 | struct mutex odata_mutex; |
286 | #endif | ||
287 | 300 | ||
288 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS) | 301 | #if defined(CONFIG_JOYSTICK_XPAD_LEDS) |
289 | struct xpad_led *led; | 302 | struct xpad_led *led; |
@@ -470,6 +483,105 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha | |||
470 | xpad360_process_packet(xpad, cmd, &data[4]); | 483 | xpad360_process_packet(xpad, cmd, &data[4]); |
471 | } | 484 | } |
472 | 485 | ||
486 | /* | ||
487 | * xpadone_process_buttons | ||
488 | * | ||
489 | * Process a button update packet from an Xbox one controller. | ||
490 | */ | ||
491 | static void xpadone_process_buttons(struct usb_xpad *xpad, | ||
492 | struct input_dev *dev, | ||
493 | unsigned char *data) | ||
494 | { | ||
495 | /* menu/view buttons */ | ||
496 | input_report_key(dev, BTN_START, data[4] & 0x04); | ||
497 | input_report_key(dev, BTN_SELECT, data[4] & 0x08); | ||
498 | |||
499 | /* buttons A,B,X,Y */ | ||
500 | input_report_key(dev, BTN_A, data[4] & 0x10); | ||
501 | input_report_key(dev, BTN_B, data[4] & 0x20); | ||
502 | input_report_key(dev, BTN_X, data[4] & 0x40); | ||
503 | input_report_key(dev, BTN_Y, data[4] & 0x80); | ||
504 | |||
505 | /* digital pad */ | ||
506 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { | ||
507 | /* dpad as buttons (left, right, up, down) */ | ||
508 | input_report_key(dev, BTN_TRIGGER_HAPPY1, data[5] & 0x04); | ||
509 | input_report_key(dev, BTN_TRIGGER_HAPPY2, data[5] & 0x08); | ||
510 | input_report_key(dev, BTN_TRIGGER_HAPPY3, data[5] & 0x01); | ||
511 | input_report_key(dev, BTN_TRIGGER_HAPPY4, data[5] & 0x02); | ||
512 | } else { | ||
513 | input_report_abs(dev, ABS_HAT0X, | ||
514 | !!(data[5] & 0x08) - !!(data[5] & 0x04)); | ||
515 | input_report_abs(dev, ABS_HAT0Y, | ||
516 | !!(data[5] & 0x02) - !!(data[5] & 0x01)); | ||
517 | } | ||
518 | |||
519 | /* TL/TR */ | ||
520 | input_report_key(dev, BTN_TL, data[5] & 0x10); | ||
521 | input_report_key(dev, BTN_TR, data[5] & 0x20); | ||
522 | |||
523 | /* stick press left/right */ | ||
524 | input_report_key(dev, BTN_THUMBL, data[5] & 0x40); | ||
525 | input_report_key(dev, BTN_THUMBR, data[5] & 0x80); | ||
526 | |||
527 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { | ||
528 | /* left stick */ | ||
529 | input_report_abs(dev, ABS_X, | ||
530 | (__s16) le16_to_cpup((__le16 *)(data + 10))); | ||
531 | input_report_abs(dev, ABS_Y, | ||
532 | ~(__s16) le16_to_cpup((__le16 *)(data + 12))); | ||
533 | |||
534 | /* right stick */ | ||
535 | input_report_abs(dev, ABS_RX, | ||
536 | (__s16) le16_to_cpup((__le16 *)(data + 14))); | ||
537 | input_report_abs(dev, ABS_RY, | ||
538 | ~(__s16) le16_to_cpup((__le16 *)(data + 16))); | ||
539 | } | ||
540 | |||
541 | /* triggers left/right */ | ||
542 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | ||
543 | input_report_key(dev, BTN_TL2, | ||
544 | (__u16) le16_to_cpup((__le16 *)(data + 6))); | ||
545 | input_report_key(dev, BTN_TR2, | ||
546 | (__u16) le16_to_cpup((__le16 *)(data + 8))); | ||
547 | } else { | ||
548 | input_report_abs(dev, ABS_Z, | ||
549 | (__u16) le16_to_cpup((__le16 *)(data + 6))); | ||
550 | input_report_abs(dev, ABS_RZ, | ||
551 | (__u16) le16_to_cpup((__le16 *)(data + 8))); | ||
552 | } | ||
553 | |||
554 | input_sync(dev); | ||
555 | } | ||
556 | |||
557 | /* | ||
558 | * xpadone_process_packet | ||
559 | * | ||
560 | * Completes a request by converting the data into events for the | ||
561 | * input subsystem. This version is for the Xbox One controller. | ||
562 | * | ||
563 | * The report format was gleaned from | ||
564 | * https://github.com/kylelemons/xbox/blob/master/xbox.go | ||
565 | */ | ||
566 | |||
567 | static void xpadone_process_packet(struct usb_xpad *xpad, | ||
568 | u16 cmd, unsigned char *data) | ||
569 | { | ||
570 | struct input_dev *dev = xpad->dev; | ||
571 | |||
572 | switch (data[0]) { | ||
573 | case 0x20: | ||
574 | xpadone_process_buttons(xpad, dev, data); | ||
575 | break; | ||
576 | |||
577 | case 0x07: | ||
578 | /* the xbox button has its own special report */ | ||
579 | input_report_key(dev, BTN_MODE, data[4] & 0x01); | ||
580 | input_sync(dev); | ||
581 | break; | ||
582 | } | ||
583 | } | ||
584 | |||
473 | static void xpad_irq_in(struct urb *urb) | 585 | static void xpad_irq_in(struct urb *urb) |
474 | { | 586 | { |
475 | struct usb_xpad *xpad = urb->context; | 587 | struct usb_xpad *xpad = urb->context; |
@@ -502,6 +614,9 @@ static void xpad_irq_in(struct urb *urb) | |||
502 | case XTYPE_XBOX360W: | 614 | case XTYPE_XBOX360W: |
503 | xpad360w_process_packet(xpad, 0, xpad->idata); | 615 | xpad360w_process_packet(xpad, 0, xpad->idata); |
504 | break; | 616 | break; |
617 | case XTYPE_XBOXONE: | ||
618 | xpadone_process_packet(xpad, 0, xpad->idata); | ||
619 | break; | ||
505 | default: | 620 | default: |
506 | xpad_process_packet(xpad, 0, xpad->idata); | 621 | xpad_process_packet(xpad, 0, xpad->idata); |
507 | } | 622 | } |
@@ -535,7 +650,6 @@ static void xpad_bulk_out(struct urb *urb) | |||
535 | } | 650 | } |
536 | } | 651 | } |
537 | 652 | ||
538 | #if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) | ||
539 | static void xpad_irq_out(struct urb *urb) | 653 | static void xpad_irq_out(struct urb *urb) |
540 | { | 654 | { |
541 | struct usb_xpad *xpad = urb->context; | 655 | struct usb_xpad *xpad = urb->context; |
@@ -573,6 +687,7 @@ exit: | |||
573 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | 687 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) |
574 | { | 688 | { |
575 | struct usb_endpoint_descriptor *ep_irq_out; | 689 | struct usb_endpoint_descriptor *ep_irq_out; |
690 | int ep_irq_out_idx; | ||
576 | int error; | 691 | int error; |
577 | 692 | ||
578 | if (xpad->xtype == XTYPE_UNKNOWN) | 693 | if (xpad->xtype == XTYPE_UNKNOWN) |
@@ -593,7 +708,10 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) | |||
593 | goto fail2; | 708 | goto fail2; |
594 | } | 709 | } |
595 | 710 | ||
596 | ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; | 711 | /* Xbox One controller has in/out endpoints swapped. */ |
712 | ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1; | ||
713 | ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc; | ||
714 | |||
597 | usb_fill_int_urb(xpad->irq_out, xpad->udev, | 715 | usb_fill_int_urb(xpad->irq_out, xpad->udev, |
598 | usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), | 716 | usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), |
599 | xpad->odata, XPAD_PKT_LEN, | 717 | xpad->odata, XPAD_PKT_LEN, |
@@ -621,11 +739,6 @@ static void xpad_deinit_output(struct usb_xpad *xpad) | |||
621 | xpad->odata, xpad->odata_dma); | 739 | xpad->odata, xpad->odata_dma); |
622 | } | 740 | } |
623 | } | 741 | } |
624 | #else | ||
625 | static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } | ||
626 | static void xpad_deinit_output(struct usb_xpad *xpad) {} | ||
627 | static void xpad_stop_output(struct usb_xpad *xpad) {} | ||
628 | #endif | ||
629 | 742 | ||
630 | #ifdef CONFIG_JOYSTICK_XPAD_FF | 743 | #ifdef CONFIG_JOYSTICK_XPAD_FF |
631 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) | 744 | static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) |
@@ -692,7 +805,7 @@ static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect | |||
692 | 805 | ||
693 | static int xpad_init_ff(struct usb_xpad *xpad) | 806 | static int xpad_init_ff(struct usb_xpad *xpad) |
694 | { | 807 | { |
695 | if (xpad->xtype == XTYPE_UNKNOWN) | 808 | if (xpad->xtype == XTYPE_UNKNOWN || xpad->xtype == XTYPE_XBOXONE) |
696 | return 0; | 809 | return 0; |
697 | 810 | ||
698 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); | 811 | input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); |
@@ -801,6 +914,14 @@ static int xpad_open(struct input_dev *dev) | |||
801 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) | 914 | if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) |
802 | return -EIO; | 915 | return -EIO; |
803 | 916 | ||
917 | if (xpad->xtype == XTYPE_XBOXONE) { | ||
918 | /* Xbox one controller needs to be initialized. */ | ||
919 | xpad->odata[0] = 0x05; | ||
920 | xpad->odata[1] = 0x20; | ||
921 | xpad->irq_out->transfer_buffer_length = 2; | ||
922 | return usb_submit_urb(xpad->irq_out, GFP_KERNEL); | ||
923 | } | ||
924 | |||
804 | return 0; | 925 | return 0; |
805 | } | 926 | } |
806 | 927 | ||
@@ -816,6 +937,7 @@ static void xpad_close(struct input_dev *dev) | |||
816 | 937 | ||
817 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | 938 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) |
818 | { | 939 | { |
940 | struct usb_xpad *xpad = input_get_drvdata(input_dev); | ||
819 | set_bit(abs, input_dev->absbit); | 941 | set_bit(abs, input_dev->absbit); |
820 | 942 | ||
821 | switch (abs) { | 943 | switch (abs) { |
@@ -827,7 +949,10 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | |||
827 | break; | 949 | break; |
828 | case ABS_Z: | 950 | case ABS_Z: |
829 | case ABS_RZ: /* the triggers (if mapped to axes) */ | 951 | case ABS_RZ: /* the triggers (if mapped to axes) */ |
830 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | 952 | if (xpad->xtype == XTYPE_XBOXONE) |
953 | input_set_abs_params(input_dev, abs, 0, 1023, 0, 0); | ||
954 | else | ||
955 | input_set_abs_params(input_dev, abs, 0, 255, 0, 0); | ||
831 | break; | 956 | break; |
832 | case ABS_HAT0X: | 957 | case ABS_HAT0X: |
833 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ | 958 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ |
@@ -842,6 +967,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
842 | struct usb_xpad *xpad; | 967 | struct usb_xpad *xpad; |
843 | struct input_dev *input_dev; | 968 | struct input_dev *input_dev; |
844 | struct usb_endpoint_descriptor *ep_irq_in; | 969 | struct usb_endpoint_descriptor *ep_irq_in; |
970 | int ep_irq_in_idx; | ||
845 | int i, error; | 971 | int i, error; |
846 | 972 | ||
847 | for (i = 0; xpad_device[i].idVendor; i++) { | 973 | for (i = 0; xpad_device[i].idVendor; i++) { |
@@ -850,6 +976,16 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
850 | break; | 976 | break; |
851 | } | 977 | } |
852 | 978 | ||
979 | if (xpad_device[i].xtype == XTYPE_XBOXONE && | ||
980 | intf->cur_altsetting->desc.bInterfaceNumber != 0) { | ||
981 | /* | ||
982 | * The Xbox One controller lists three interfaces all with the | ||
983 | * same interface class, subclass and protocol. Differentiate by | ||
984 | * interface number. | ||
985 | */ | ||
986 | return -ENODEV; | ||
987 | } | ||
988 | |||
853 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); | 989 | xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL); |
854 | input_dev = input_allocate_device(); | 990 | input_dev = input_allocate_device(); |
855 | if (!xpad || !input_dev) { | 991 | if (!xpad || !input_dev) { |
@@ -920,7 +1056,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
920 | __set_bit(xpad_common_btn[i], input_dev->keybit); | 1056 | __set_bit(xpad_common_btn[i], input_dev->keybit); |
921 | 1057 | ||
922 | /* set up model-specific ones */ | 1058 | /* set up model-specific ones */ |
923 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W) { | 1059 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W || |
1060 | xpad->xtype == XTYPE_XBOXONE) { | ||
924 | for (i = 0; xpad360_btn[i] >= 0; i++) | 1061 | for (i = 0; xpad360_btn[i] >= 0; i++) |
925 | __set_bit(xpad360_btn[i], input_dev->keybit); | 1062 | __set_bit(xpad360_btn[i], input_dev->keybit); |
926 | } else { | 1063 | } else { |
@@ -933,7 +1070,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
933 | __set_bit(xpad_btn_pad[i], input_dev->keybit); | 1070 | __set_bit(xpad_btn_pad[i], input_dev->keybit); |
934 | } else { | 1071 | } else { |
935 | for (i = 0; xpad_abs_pad[i] >= 0; i++) | 1072 | for (i = 0; xpad_abs_pad[i] >= 0; i++) |
936 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); | 1073 | xpad_set_up_abs(input_dev, xpad_abs_pad[i]); |
937 | } | 1074 | } |
938 | 1075 | ||
939 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | 1076 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
@@ -956,7 +1093,10 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
956 | if (error) | 1093 | if (error) |
957 | goto fail5; | 1094 | goto fail5; |
958 | 1095 | ||
959 | ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; | 1096 | /* Xbox One controller has in/out endpoints swapped. */ |
1097 | ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0; | ||
1098 | ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc; | ||
1099 | |||
960 | usb_fill_int_urb(xpad->irq_in, udev, | 1100 | usb_fill_int_urb(xpad->irq_in, udev, |
961 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), | 1101 | usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), |
962 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, | 1102 | xpad->idata, XPAD_PKT_LEN, xpad_irq_in, |
diff --git a/drivers/input/keyboard/cap1106.c b/drivers/input/keyboard/cap1106.c index f7d7a0d4ab4e..180b184ab90f 100644 --- a/drivers/input/keyboard/cap1106.c +++ b/drivers/input/keyboard/cap1106.c | |||
@@ -64,7 +64,7 @@ struct cap1106_priv { | |||
64 | struct input_dev *idev; | 64 | struct input_dev *idev; |
65 | 65 | ||
66 | /* config */ | 66 | /* config */ |
67 | unsigned int keycodes[CAP1106_NUM_CHN]; | 67 | unsigned short keycodes[CAP1106_NUM_CHN]; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static const struct reg_default cap1106_reg_defaults[] = { | 70 | static const struct reg_default cap1106_reg_defaults[] = { |
@@ -272,6 +272,12 @@ static int cap1106_i2c_probe(struct i2c_client *i2c_client, | |||
272 | for (i = 0; i < CAP1106_NUM_CHN; i++) | 272 | for (i = 0; i < CAP1106_NUM_CHN; i++) |
273 | __set_bit(priv->keycodes[i], priv->idev->keybit); | 273 | __set_bit(priv->keycodes[i], priv->idev->keybit); |
274 | 274 | ||
275 | __clear_bit(KEY_RESERVED, priv->idev->keybit); | ||
276 | |||
277 | priv->idev->keycode = priv->keycodes; | ||
278 | priv->idev->keycodesize = sizeof(priv->keycodes[0]); | ||
279 | priv->idev->keycodemax = ARRAY_SIZE(priv->keycodes); | ||
280 | |||
275 | priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; | 281 | priv->idev->id.vendor = CAP1106_MANUFACTURER_ID; |
276 | priv->idev->id.product = CAP1106_PRODUCT_ID; | 282 | priv->idev->id.product = CAP1106_PRODUCT_ID; |
277 | priv->idev->id.version = rev; | 283 | priv->idev->id.version = rev; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ef9e0b8a9aa7..e8573c68f77e 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -117,6 +117,9 @@ void synaptics_reset(struct psmouse *psmouse) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
120 | |||
121 | static bool cr48_profile_sensor; | ||
122 | |||
120 | struct min_max_quirk { | 123 | struct min_max_quirk { |
121 | const char * const *pnp_ids; | 124 | const char * const *pnp_ids; |
122 | int x_min, x_max, y_min, y_max; | 125 | int x_min, x_max, y_min, y_max; |
@@ -1152,6 +1155,42 @@ static void synaptics_image_sensor_process(struct psmouse *psmouse, | |||
1152 | priv->agm_pending = false; | 1155 | priv->agm_pending = false; |
1153 | } | 1156 | } |
1154 | 1157 | ||
1158 | static void synaptics_profile_sensor_process(struct psmouse *psmouse, | ||
1159 | struct synaptics_hw_state *sgm, | ||
1160 | int num_fingers) | ||
1161 | { | ||
1162 | struct input_dev *dev = psmouse->dev; | ||
1163 | struct synaptics_data *priv = psmouse->private; | ||
1164 | struct synaptics_hw_state *hw[2] = { sgm, &priv->agm }; | ||
1165 | struct input_mt_pos pos[2]; | ||
1166 | int slot[2], nsemi, i; | ||
1167 | |||
1168 | nsemi = clamp_val(num_fingers, 0, 2); | ||
1169 | |||
1170 | for (i = 0; i < nsemi; i++) { | ||
1171 | pos[i].x = hw[i]->x; | ||
1172 | pos[i].y = synaptics_invert_y(hw[i]->y); | ||
1173 | } | ||
1174 | |||
1175 | input_mt_assign_slots(dev, slot, pos, nsemi); | ||
1176 | |||
1177 | for (i = 0; i < nsemi; i++) { | ||
1178 | input_mt_slot(dev, slot[i]); | ||
1179 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, true); | ||
1180 | input_report_abs(dev, ABS_MT_POSITION_X, pos[i].x); | ||
1181 | input_report_abs(dev, ABS_MT_POSITION_Y, pos[i].y); | ||
1182 | input_report_abs(dev, ABS_MT_PRESSURE, hw[i]->z); | ||
1183 | } | ||
1184 | |||
1185 | input_mt_drop_unused(dev); | ||
1186 | input_mt_report_pointer_emulation(dev, false); | ||
1187 | input_mt_report_finger_count(dev, num_fingers); | ||
1188 | |||
1189 | synaptics_report_buttons(psmouse, sgm); | ||
1190 | |||
1191 | input_sync(dev); | ||
1192 | } | ||
1193 | |||
1155 | /* | 1194 | /* |
1156 | * called for each full received packet from the touchpad | 1195 | * called for each full received packet from the touchpad |
1157 | */ | 1196 | */ |
@@ -1215,6 +1254,11 @@ static void synaptics_process_packet(struct psmouse *psmouse) | |||
1215 | finger_width = 0; | 1254 | finger_width = 0; |
1216 | } | 1255 | } |
1217 | 1256 | ||
1257 | if (cr48_profile_sensor) { | ||
1258 | synaptics_profile_sensor_process(psmouse, &hw, num_fingers); | ||
1259 | return; | ||
1260 | } | ||
1261 | |||
1218 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) | 1262 | if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) |
1219 | synaptics_report_semi_mt_data(dev, &hw, &priv->agm, | 1263 | synaptics_report_semi_mt_data(dev, &hw, &priv->agm, |
1220 | num_fingers); | 1264 | num_fingers); |
@@ -1360,6 +1404,9 @@ static void set_input_params(struct psmouse *psmouse, | |||
1360 | set_abs_position_params(dev, priv, ABS_X, ABS_Y); | 1404 | set_abs_position_params(dev, priv, ABS_X, ABS_Y); |
1361 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1405 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
1362 | 1406 | ||
1407 | if (cr48_profile_sensor) | ||
1408 | input_set_abs_params(dev, ABS_MT_PRESSURE, 0, 255, 0, 0); | ||
1409 | |||
1363 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1410 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
1364 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1411 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1365 | ABS_MT_POSITION_Y); | 1412 | ABS_MT_POSITION_Y); |
@@ -1371,11 +1418,16 @@ static void set_input_params(struct psmouse *psmouse, | |||
1371 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 1418 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
1372 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); | 1419 | __set_bit(BTN_TOOL_QUINTTAP, dev->keybit); |
1373 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 1420 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
1374 | /* Non-image sensors with AGM use semi-mt */ | ||
1375 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | ||
1376 | input_mt_init_slots(dev, 2, 0); | ||
1377 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1421 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1378 | ABS_MT_POSITION_Y); | 1422 | ABS_MT_POSITION_Y); |
1423 | /* | ||
1424 | * Profile sensor in CR-48 tracks contacts reasonably well, | ||
1425 | * other non-image sensors with AGM use semi-mt. | ||
1426 | */ | ||
1427 | input_mt_init_slots(dev, 2, | ||
1428 | INPUT_MT_POINTER | | ||
1429 | (cr48_profile_sensor ? | ||
1430 | INPUT_MT_TRACK : INPUT_MT_SEMI_MT)); | ||
1379 | } | 1431 | } |
1380 | 1432 | ||
1381 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | 1433 | if (SYN_CAP_PALMDETECT(priv->capabilities)) |
@@ -1577,10 +1629,24 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { | |||
1577 | { } | 1629 | { } |
1578 | }; | 1630 | }; |
1579 | 1631 | ||
1632 | static const struct dmi_system_id __initconst cr48_dmi_table[] = { | ||
1633 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1634 | { | ||
1635 | /* Cr-48 Chromebook (Codename Mario) */ | ||
1636 | .matches = { | ||
1637 | DMI_MATCH(DMI_SYS_VENDOR, "IEC"), | ||
1638 | DMI_MATCH(DMI_PRODUCT_NAME, "Mario"), | ||
1639 | }, | ||
1640 | }, | ||
1641 | #endif | ||
1642 | { } | ||
1643 | }; | ||
1644 | |||
1580 | void __init synaptics_module_init(void) | 1645 | void __init synaptics_module_init(void) |
1581 | { | 1646 | { |
1582 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 1647 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
1583 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | 1648 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); |
1649 | cr48_profile_sensor = dmi_check_system(cr48_dmi_table); | ||
1584 | } | 1650 | } |
1585 | 1651 | ||
1586 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | 1652 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 03b85711cb70..db178ed2b47e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -359,7 +359,6 @@ static int mxt_bootloader_read(struct mxt_data *data, | |||
359 | msg.buf = val; | 359 | msg.buf = val; |
360 | 360 | ||
361 | ret = i2c_transfer(data->client->adapter, &msg, 1); | 361 | ret = i2c_transfer(data->client->adapter, &msg, 1); |
362 | |||
363 | if (ret == 1) { | 362 | if (ret == 1) { |
364 | ret = 0; | 363 | ret = 0; |
365 | } else { | 364 | } else { |
@@ -414,6 +413,7 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) | |||
414 | case 0x5b: | 413 | case 0x5b: |
415 | bootloader = appmode - 0x26; | 414 | bootloader = appmode - 0x26; |
416 | break; | 415 | break; |
416 | |||
417 | default: | 417 | default: |
418 | dev_err(&data->client->dev, | 418 | dev_err(&data->client->dev, |
419 | "Appmode i2c address 0x%02x not found\n", | 419 | "Appmode i2c address 0x%02x not found\n", |
@@ -425,20 +425,20 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) | |||
425 | return 0; | 425 | return 0; |
426 | } | 426 | } |
427 | 427 | ||
428 | static int mxt_probe_bootloader(struct mxt_data *data, bool retry) | 428 | static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address) |
429 | { | 429 | { |
430 | struct device *dev = &data->client->dev; | 430 | struct device *dev = &data->client->dev; |
431 | int ret; | 431 | int error; |
432 | u8 val; | 432 | u8 val; |
433 | bool crc_failure; | 433 | bool crc_failure; |
434 | 434 | ||
435 | ret = mxt_lookup_bootloader_address(data, retry); | 435 | error = mxt_lookup_bootloader_address(data, alt_address); |
436 | if (ret) | 436 | if (error) |
437 | return ret; | 437 | return error; |
438 | 438 | ||
439 | ret = mxt_bootloader_read(data, &val, 1); | 439 | error = mxt_bootloader_read(data, &val, 1); |
440 | if (ret) | 440 | if (error) |
441 | return ret; | 441 | return error; |
442 | 442 | ||
443 | /* Check app crc fail mode */ | 443 | /* Check app crc fail mode */ |
444 | crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL; | 444 | crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL; |
@@ -1064,6 +1064,137 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, off_t end_off) | |||
1064 | return crc; | 1064 | return crc; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | static int mxt_prepare_cfg_mem(struct mxt_data *data, | ||
1068 | const struct firmware *cfg, | ||
1069 | unsigned int data_pos, | ||
1070 | unsigned int cfg_start_ofs, | ||
1071 | u8 *config_mem, | ||
1072 | size_t config_mem_size) | ||
1073 | { | ||
1074 | struct device *dev = &data->client->dev; | ||
1075 | struct mxt_object *object; | ||
1076 | unsigned int type, instance, size, byte_offset; | ||
1077 | int offset; | ||
1078 | int ret; | ||
1079 | int i; | ||
1080 | u16 reg; | ||
1081 | u8 val; | ||
1082 | |||
1083 | while (data_pos < cfg->size) { | ||
1084 | /* Read type, instance, length */ | ||
1085 | ret = sscanf(cfg->data + data_pos, "%x %x %x%n", | ||
1086 | &type, &instance, &size, &offset); | ||
1087 | if (ret == 0) { | ||
1088 | /* EOF */ | ||
1089 | break; | ||
1090 | } else if (ret != 3) { | ||
1091 | dev_err(dev, "Bad format: failed to parse object\n"); | ||
1092 | return -EINVAL; | ||
1093 | } | ||
1094 | data_pos += offset; | ||
1095 | |||
1096 | object = mxt_get_object(data, type); | ||
1097 | if (!object) { | ||
1098 | /* Skip object */ | ||
1099 | for (i = 0; i < size; i++) { | ||
1100 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1101 | &val, &offset); | ||
1102 | if (ret != 1) { | ||
1103 | dev_err(dev, "Bad format in T%d at %d\n", | ||
1104 | type, i); | ||
1105 | return -EINVAL; | ||
1106 | } | ||
1107 | data_pos += offset; | ||
1108 | } | ||
1109 | continue; | ||
1110 | } | ||
1111 | |||
1112 | if (size > mxt_obj_size(object)) { | ||
1113 | /* | ||
1114 | * Either we are in fallback mode due to wrong | ||
1115 | * config or config from a later fw version, | ||
1116 | * or the file is corrupt or hand-edited. | ||
1117 | */ | ||
1118 | dev_warn(dev, "Discarding %zu byte(s) in T%u\n", | ||
1119 | size - mxt_obj_size(object), type); | ||
1120 | } else if (mxt_obj_size(object) > size) { | ||
1121 | /* | ||
1122 | * If firmware is upgraded, new bytes may be added to | ||
1123 | * end of objects. It is generally forward compatible | ||
1124 | * to zero these bytes - previous behaviour will be | ||
1125 | * retained. However this does invalidate the CRC and | ||
1126 | * will force fallback mode until the configuration is | ||
1127 | * updated. We warn here but do nothing else - the | ||
1128 | * malloc has zeroed the entire configuration. | ||
1129 | */ | ||
1130 | dev_warn(dev, "Zeroing %zu byte(s) in T%d\n", | ||
1131 | mxt_obj_size(object) - size, type); | ||
1132 | } | ||
1133 | |||
1134 | if (instance >= mxt_obj_instances(object)) { | ||
1135 | dev_err(dev, "Object instances exceeded!\n"); | ||
1136 | return -EINVAL; | ||
1137 | } | ||
1138 | |||
1139 | reg = object->start_address + mxt_obj_size(object) * instance; | ||
1140 | |||
1141 | for (i = 0; i < size; i++) { | ||
1142 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1143 | &val, | ||
1144 | &offset); | ||
1145 | if (ret != 1) { | ||
1146 | dev_err(dev, "Bad format in T%d at %d\n", | ||
1147 | type, i); | ||
1148 | return -EINVAL; | ||
1149 | } | ||
1150 | data_pos += offset; | ||
1151 | |||
1152 | if (i > mxt_obj_size(object)) | ||
1153 | continue; | ||
1154 | |||
1155 | byte_offset = reg + i - cfg_start_ofs; | ||
1156 | |||
1157 | if (byte_offset >= 0 && byte_offset < config_mem_size) { | ||
1158 | *(config_mem + byte_offset) = val; | ||
1159 | } else { | ||
1160 | dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n", | ||
1161 | reg, object->type, byte_offset); | ||
1162 | return -EINVAL; | ||
1163 | } | ||
1164 | } | ||
1165 | } | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start, | ||
1171 | u8 *config_mem, size_t config_mem_size) | ||
1172 | { | ||
1173 | unsigned int byte_offset = 0; | ||
1174 | int error; | ||
1175 | |||
1176 | /* Write configuration as blocks */ | ||
1177 | while (byte_offset < config_mem_size) { | ||
1178 | unsigned int size = config_mem_size - byte_offset; | ||
1179 | |||
1180 | if (size > MXT_MAX_BLOCK_WRITE) | ||
1181 | size = MXT_MAX_BLOCK_WRITE; | ||
1182 | |||
1183 | error = __mxt_write_reg(data->client, | ||
1184 | cfg_start + byte_offset, | ||
1185 | size, config_mem + byte_offset); | ||
1186 | if (error) { | ||
1187 | dev_err(&data->client->dev, | ||
1188 | "Config write error, ret=%d\n", error); | ||
1189 | return error; | ||
1190 | } | ||
1191 | |||
1192 | byte_offset += size; | ||
1193 | } | ||
1194 | |||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1067 | /* | 1198 | /* |
1068 | * mxt_update_cfg - download configuration to chip | 1199 | * mxt_update_cfg - download configuration to chip |
1069 | * | 1200 | * |
@@ -1087,26 +1218,20 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1087 | { | 1218 | { |
1088 | struct device *dev = &data->client->dev; | 1219 | struct device *dev = &data->client->dev; |
1089 | struct mxt_info cfg_info; | 1220 | struct mxt_info cfg_info; |
1090 | struct mxt_object *object; | ||
1091 | int ret; | 1221 | int ret; |
1092 | int offset; | 1222 | int offset; |
1093 | int data_pos; | 1223 | int data_pos; |
1094 | int byte_offset; | ||
1095 | int i; | 1224 | int i; |
1096 | int cfg_start_ofs; | 1225 | int cfg_start_ofs; |
1097 | u32 info_crc, config_crc, calculated_crc; | 1226 | u32 info_crc, config_crc, calculated_crc; |
1098 | u8 *config_mem; | 1227 | u8 *config_mem; |
1099 | size_t config_mem_size; | 1228 | size_t config_mem_size; |
1100 | unsigned int type, instance, size; | ||
1101 | u8 val; | ||
1102 | u16 reg; | ||
1103 | 1229 | ||
1104 | mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); | 1230 | mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); |
1105 | 1231 | ||
1106 | if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { | 1232 | if (strncmp(cfg->data, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { |
1107 | dev_err(dev, "Unrecognised config file\n"); | 1233 | dev_err(dev, "Unrecognised config file\n"); |
1108 | ret = -EINVAL; | 1234 | return -EINVAL; |
1109 | goto release; | ||
1110 | } | 1235 | } |
1111 | 1236 | ||
1112 | data_pos = strlen(MXT_CFG_MAGIC); | 1237 | data_pos = strlen(MXT_CFG_MAGIC); |
@@ -1118,8 +1243,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1118 | &offset); | 1243 | &offset); |
1119 | if (ret != 1) { | 1244 | if (ret != 1) { |
1120 | dev_err(dev, "Bad format\n"); | 1245 | dev_err(dev, "Bad format\n"); |
1121 | ret = -EINVAL; | 1246 | return -EINVAL; |
1122 | goto release; | ||
1123 | } | 1247 | } |
1124 | 1248 | ||
1125 | data_pos += offset; | 1249 | data_pos += offset; |
@@ -1127,30 +1251,26 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1127 | 1251 | ||
1128 | if (cfg_info.family_id != data->info.family_id) { | 1252 | if (cfg_info.family_id != data->info.family_id) { |
1129 | dev_err(dev, "Family ID mismatch!\n"); | 1253 | dev_err(dev, "Family ID mismatch!\n"); |
1130 | ret = -EINVAL; | 1254 | return -EINVAL; |
1131 | goto release; | ||
1132 | } | 1255 | } |
1133 | 1256 | ||
1134 | if (cfg_info.variant_id != data->info.variant_id) { | 1257 | if (cfg_info.variant_id != data->info.variant_id) { |
1135 | dev_err(dev, "Variant ID mismatch!\n"); | 1258 | dev_err(dev, "Variant ID mismatch!\n"); |
1136 | ret = -EINVAL; | 1259 | return -EINVAL; |
1137 | goto release; | ||
1138 | } | 1260 | } |
1139 | 1261 | ||
1140 | /* Read CRCs */ | 1262 | /* Read CRCs */ |
1141 | ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset); | 1263 | ret = sscanf(cfg->data + data_pos, "%x%n", &info_crc, &offset); |
1142 | if (ret != 1) { | 1264 | if (ret != 1) { |
1143 | dev_err(dev, "Bad format: failed to parse Info CRC\n"); | 1265 | dev_err(dev, "Bad format: failed to parse Info CRC\n"); |
1144 | ret = -EINVAL; | 1266 | return -EINVAL; |
1145 | goto release; | ||
1146 | } | 1267 | } |
1147 | data_pos += offset; | 1268 | data_pos += offset; |
1148 | 1269 | ||
1149 | ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset); | 1270 | ret = sscanf(cfg->data + data_pos, "%x%n", &config_crc, &offset); |
1150 | if (ret != 1) { | 1271 | if (ret != 1) { |
1151 | dev_err(dev, "Bad format: failed to parse Config CRC\n"); | 1272 | dev_err(dev, "Bad format: failed to parse Config CRC\n"); |
1152 | ret = -EINVAL; | 1273 | return -EINVAL; |
1153 | goto release; | ||
1154 | } | 1274 | } |
1155 | data_pos += offset; | 1275 | data_pos += offset; |
1156 | 1276 | ||
@@ -1166,8 +1286,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1166 | } else if (config_crc == data->config_crc) { | 1286 | } else if (config_crc == data->config_crc) { |
1167 | dev_dbg(dev, "Config CRC 0x%06X: OK\n", | 1287 | dev_dbg(dev, "Config CRC 0x%06X: OK\n", |
1168 | data->config_crc); | 1288 | data->config_crc); |
1169 | ret = 0; | 1289 | return 0; |
1170 | goto release; | ||
1171 | } else { | 1290 | } else { |
1172 | dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", | 1291 | dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", |
1173 | data->config_crc, config_crc); | 1292 | data->config_crc, config_crc); |
@@ -1186,93 +1305,13 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1186 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); | 1305 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); |
1187 | if (!config_mem) { | 1306 | if (!config_mem) { |
1188 | dev_err(dev, "Failed to allocate memory\n"); | 1307 | dev_err(dev, "Failed to allocate memory\n"); |
1189 | ret = -ENOMEM; | 1308 | return -ENOMEM; |
1190 | goto release; | ||
1191 | } | 1309 | } |
1192 | 1310 | ||
1193 | while (data_pos < cfg->size) { | 1311 | ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs, |
1194 | /* Read type, instance, length */ | 1312 | config_mem, config_mem_size); |
1195 | ret = sscanf(cfg->data + data_pos, "%x %x %x%n", | 1313 | if (ret) |
1196 | &type, &instance, &size, &offset); | 1314 | goto release_mem; |
1197 | if (ret == 0) { | ||
1198 | /* EOF */ | ||
1199 | break; | ||
1200 | } else if (ret != 3) { | ||
1201 | dev_err(dev, "Bad format: failed to parse object\n"); | ||
1202 | ret = -EINVAL; | ||
1203 | goto release_mem; | ||
1204 | } | ||
1205 | data_pos += offset; | ||
1206 | |||
1207 | object = mxt_get_object(data, type); | ||
1208 | if (!object) { | ||
1209 | /* Skip object */ | ||
1210 | for (i = 0; i < size; i++) { | ||
1211 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1212 | &val, | ||
1213 | &offset); | ||
1214 | data_pos += offset; | ||
1215 | } | ||
1216 | continue; | ||
1217 | } | ||
1218 | |||
1219 | if (size > mxt_obj_size(object)) { | ||
1220 | /* | ||
1221 | * Either we are in fallback mode due to wrong | ||
1222 | * config or config from a later fw version, | ||
1223 | * or the file is corrupt or hand-edited. | ||
1224 | */ | ||
1225 | dev_warn(dev, "Discarding %zu byte(s) in T%u\n", | ||
1226 | size - mxt_obj_size(object), type); | ||
1227 | } else if (mxt_obj_size(object) > size) { | ||
1228 | /* | ||
1229 | * If firmware is upgraded, new bytes may be added to | ||
1230 | * end of objects. It is generally forward compatible | ||
1231 | * to zero these bytes - previous behaviour will be | ||
1232 | * retained. However this does invalidate the CRC and | ||
1233 | * will force fallback mode until the configuration is | ||
1234 | * updated. We warn here but do nothing else - the | ||
1235 | * malloc has zeroed the entire configuration. | ||
1236 | */ | ||
1237 | dev_warn(dev, "Zeroing %zu byte(s) in T%d\n", | ||
1238 | mxt_obj_size(object) - size, type); | ||
1239 | } | ||
1240 | |||
1241 | if (instance >= mxt_obj_instances(object)) { | ||
1242 | dev_err(dev, "Object instances exceeded!\n"); | ||
1243 | ret = -EINVAL; | ||
1244 | goto release_mem; | ||
1245 | } | ||
1246 | |||
1247 | reg = object->start_address + mxt_obj_size(object) * instance; | ||
1248 | |||
1249 | for (i = 0; i < size; i++) { | ||
1250 | ret = sscanf(cfg->data + data_pos, "%hhx%n", | ||
1251 | &val, | ||
1252 | &offset); | ||
1253 | if (ret != 1) { | ||
1254 | dev_err(dev, "Bad format in T%d\n", type); | ||
1255 | ret = -EINVAL; | ||
1256 | goto release_mem; | ||
1257 | } | ||
1258 | data_pos += offset; | ||
1259 | |||
1260 | if (i > mxt_obj_size(object)) | ||
1261 | continue; | ||
1262 | |||
1263 | byte_offset = reg + i - cfg_start_ofs; | ||
1264 | |||
1265 | if ((byte_offset >= 0) | ||
1266 | && (byte_offset <= config_mem_size)) { | ||
1267 | *(config_mem + byte_offset) = val; | ||
1268 | } else { | ||
1269 | dev_err(dev, "Bad object: reg:%d, T%d, ofs=%d\n", | ||
1270 | reg, object->type, byte_offset); | ||
1271 | ret = -EINVAL; | ||
1272 | goto release_mem; | ||
1273 | } | ||
1274 | } | ||
1275 | } | ||
1276 | 1315 | ||
1277 | /* Calculate crc of the received configs (not the raw config file) */ | 1316 | /* Calculate crc of the received configs (not the raw config file) */ |
1278 | if (data->T7_address < cfg_start_ofs) { | 1317 | if (data->T7_address < cfg_start_ofs) { |
@@ -1286,28 +1325,14 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1286 | data->T7_address - cfg_start_ofs, | 1325 | data->T7_address - cfg_start_ofs, |
1287 | config_mem_size); | 1326 | config_mem_size); |
1288 | 1327 | ||
1289 | if (config_crc > 0 && (config_crc != calculated_crc)) | 1328 | if (config_crc > 0 && config_crc != calculated_crc) |
1290 | dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n", | 1329 | dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n", |
1291 | calculated_crc, config_crc); | 1330 | calculated_crc, config_crc); |
1292 | 1331 | ||
1293 | /* Write configuration as blocks */ | 1332 | ret = mxt_upload_cfg_mem(data, cfg_start_ofs, |
1294 | byte_offset = 0; | 1333 | config_mem, config_mem_size); |
1295 | while (byte_offset < config_mem_size) { | 1334 | if (ret) |
1296 | size = config_mem_size - byte_offset; | 1335 | goto release_mem; |
1297 | |||
1298 | if (size > MXT_MAX_BLOCK_WRITE) | ||
1299 | size = MXT_MAX_BLOCK_WRITE; | ||
1300 | |||
1301 | ret = __mxt_write_reg(data->client, | ||
1302 | cfg_start_ofs + byte_offset, | ||
1303 | size, config_mem + byte_offset); | ||
1304 | if (ret != 0) { | ||
1305 | dev_err(dev, "Config write error, ret=%d\n", ret); | ||
1306 | goto release_mem; | ||
1307 | } | ||
1308 | |||
1309 | byte_offset += size; | ||
1310 | } | ||
1311 | 1336 | ||
1312 | mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); | 1337 | mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); |
1313 | 1338 | ||
@@ -1319,8 +1344,6 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1319 | 1344 | ||
1320 | release_mem: | 1345 | release_mem: |
1321 | kfree(config_mem); | 1346 | kfree(config_mem); |
1322 | release: | ||
1323 | release_firmware(cfg); | ||
1324 | return ret; | 1347 | return ret; |
1325 | } | 1348 | } |
1326 | 1349 | ||
@@ -1422,10 +1445,12 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1422 | 1445 | ||
1423 | switch (object->type) { | 1446 | switch (object->type) { |
1424 | case MXT_GEN_MESSAGE_T5: | 1447 | case MXT_GEN_MESSAGE_T5: |
1425 | if (data->info.family_id == 0x80) { | 1448 | if (data->info.family_id == 0x80 && |
1449 | data->info.version < 0x20) { | ||
1426 | /* | 1450 | /* |
1427 | * On mXT224 read and discard unused CRC byte | 1451 | * On mXT224 firmware versions prior to V2.0 |
1428 | * otherwise DMA reads are misaligned | 1452 | * read and discard unused CRC byte otherwise |
1453 | * DMA reads are misaligned. | ||
1429 | */ | 1454 | */ |
1430 | data->T5_msg_size = mxt_obj_size(object); | 1455 | data->T5_msg_size = mxt_obj_size(object); |
1431 | } else { | 1456 | } else { |
@@ -1433,6 +1458,7 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1433 | data->T5_msg_size = mxt_obj_size(object) - 1; | 1458 | data->T5_msg_size = mxt_obj_size(object) - 1; |
1434 | } | 1459 | } |
1435 | data->T5_address = object->start_address; | 1460 | data->T5_address = object->start_address; |
1461 | break; | ||
1436 | case MXT_GEN_COMMAND_T6: | 1462 | case MXT_GEN_COMMAND_T6: |
1437 | data->T6_reportid = min_id; | 1463 | data->T6_reportid = min_id; |
1438 | data->T6_address = object->start_address; | 1464 | data->T6_address = object->start_address; |
@@ -1638,46 +1664,45 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
1638 | static void mxt_config_cb(const struct firmware *cfg, void *ctx) | 1664 | static void mxt_config_cb(const struct firmware *cfg, void *ctx) |
1639 | { | 1665 | { |
1640 | mxt_configure_objects(ctx, cfg); | 1666 | mxt_configure_objects(ctx, cfg); |
1667 | release_firmware(cfg); | ||
1641 | } | 1668 | } |
1642 | 1669 | ||
1643 | static int mxt_initialize(struct mxt_data *data) | 1670 | static int mxt_initialize(struct mxt_data *data) |
1644 | { | 1671 | { |
1645 | struct i2c_client *client = data->client; | 1672 | struct i2c_client *client = data->client; |
1673 | int recovery_attempts = 0; | ||
1646 | int error; | 1674 | int error; |
1647 | bool alt_bootloader_addr = false; | ||
1648 | bool retry = false; | ||
1649 | 1675 | ||
1650 | retry_info: | 1676 | while (1) { |
1651 | error = mxt_get_info(data); | 1677 | error = mxt_get_info(data); |
1652 | if (error) { | 1678 | if (!error) |
1653 | retry_bootloader: | 1679 | break; |
1654 | error = mxt_probe_bootloader(data, alt_bootloader_addr); | 1680 | |
1681 | /* Check bootloader state */ | ||
1682 | error = mxt_probe_bootloader(data, false); | ||
1655 | if (error) { | 1683 | if (error) { |
1656 | if (alt_bootloader_addr) { | 1684 | dev_info(&client->dev, "Trying alternate bootloader address\n"); |
1685 | error = mxt_probe_bootloader(data, true); | ||
1686 | if (error) { | ||
1657 | /* Chip is not in appmode or bootloader mode */ | 1687 | /* Chip is not in appmode or bootloader mode */ |
1658 | return error; | 1688 | return error; |
1659 | } | 1689 | } |
1690 | } | ||
1660 | 1691 | ||
1661 | dev_info(&client->dev, "Trying alternate bootloader address\n"); | 1692 | /* OK, we are in bootloader, see if we can recover */ |
1662 | alt_bootloader_addr = true; | 1693 | if (++recovery_attempts > 1) { |
1663 | goto retry_bootloader; | 1694 | dev_err(&client->dev, "Could not recover from bootloader mode\n"); |
1664 | } else { | 1695 | /* |
1665 | if (retry) { | 1696 | * We can reflash from this state, so do not |
1666 | dev_err(&client->dev, "Could not recover from bootloader mode\n"); | 1697 | * abort initialization. |
1667 | /* | 1698 | */ |
1668 | * We can reflash from this state, so do not | 1699 | data->in_bootloader = true; |
1669 | * abort init | 1700 | return 0; |
1670 | */ | ||
1671 | data->in_bootloader = true; | ||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1675 | /* Attempt to exit bootloader into app mode */ | ||
1676 | mxt_send_bootloader_cmd(data, false); | ||
1677 | msleep(MXT_FW_RESET_TIME); | ||
1678 | retry = true; | ||
1679 | goto retry_info; | ||
1680 | } | 1701 | } |
1702 | |||
1703 | /* Attempt to exit bootloader into app mode */ | ||
1704 | mxt_send_bootloader_cmd(data, false); | ||
1705 | msleep(MXT_FW_RESET_TIME); | ||
1681 | } | 1706 | } |
1682 | 1707 | ||
1683 | /* Get object table information */ | 1708 | /* Get object table information */ |
@@ -1687,13 +1712,18 @@ retry_bootloader: | |||
1687 | return error; | 1712 | return error; |
1688 | } | 1713 | } |
1689 | 1714 | ||
1690 | mxt_acquire_irq(data); | 1715 | error = mxt_acquire_irq(data); |
1691 | if (error) | 1716 | if (error) |
1692 | goto err_free_object_table; | 1717 | goto err_free_object_table; |
1693 | 1718 | ||
1694 | request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, | 1719 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, |
1695 | &data->client->dev, GFP_KERNEL, data, | 1720 | &client->dev, GFP_KERNEL, data, |
1696 | mxt_config_cb); | 1721 | mxt_config_cb); |
1722 | if (error) { | ||
1723 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", | ||
1724 | error); | ||
1725 | goto err_free_object_table; | ||
1726 | } | ||
1697 | 1727 | ||
1698 | return 0; | 1728 | return 0; |
1699 | 1729 | ||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 5a6d50c004d7..8857d5b9be71 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -262,7 +262,6 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, | |||
262 | case M06: | 262 | case M06: |
263 | wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; | 263 | wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc; |
264 | wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; | 264 | wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; |
265 | wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f; | ||
266 | wrbuf[2] = value; | 265 | wrbuf[2] = value; |
267 | wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; | 266 | wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2]; |
268 | return edt_ft5x06_ts_readwrite(tsdata->client, 4, | 267 | return edt_ft5x06_ts_readwrite(tsdata->client, 4, |
diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 1b1dfa80d9ff..f583ff639776 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h | |||
@@ -105,6 +105,7 @@ void input_mt_report_slot_state(struct input_dev *dev, | |||
105 | 105 | ||
106 | void input_mt_report_finger_count(struct input_dev *dev, int count); | 106 | void input_mt_report_finger_count(struct input_dev *dev, int count); |
107 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); | 107 | void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); |
108 | void input_mt_drop_unused(struct input_dev *dev); | ||
108 | 109 | ||
109 | void input_mt_sync_frame(struct input_dev *dev); | 110 | void input_mt_sync_frame(struct input_dev *dev); |
110 | 111 | ||