From 6549981bc54777c37eccf987e227aff47022ab7c Mon Sep 17 00:00:00 2001 From: Stephane Chatty Date: Tue, 6 Apr 2010 22:22:58 +0200 Subject: [PATCH 01/10] HID: fix N-trig touch panel with recent firmware Added an init message that avoids device freeze with recent firmware. Signed-off-by: Stephane Chatty Tested-by: Rafi Rubin Signed-off-by: Jiri Kosina --- drivers/hid/hid-ntrig.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 9b24fc510712..513db0a47c4a 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -1,8 +1,8 @@ /* * HID driver for N-Trig touchscreens * - * Copyright (c) 2008 Rafi Rubin - * Copyright (c) 2009 Stephane Chatty + * Copyright (c) 2008-2010 Rafi Rubin + * Copyright (c) 2009-2010 Stephane Chatty * */ @@ -15,6 +15,8 @@ #include #include +#include +#include "usbhid/usbhid.h" #include #include @@ -286,6 +288,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) struct ntrig_data *nd; struct hid_input *hidinput; struct input_dev *input; + struct hid_report *report; if (id->driver_data) hdev->quirks |= HID_QUIRK_MULTI_INPUT; @@ -349,6 +352,11 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) } } + report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; + if (report) + usbhid_submit_report(hdev, report, USB_DIR_OUT); + + return 0; err_free: kfree(nd); From c0858552c088616c18879c347d9e0daa98cf2b15 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 7 Apr 2010 12:10:29 +0200 Subject: [PATCH 02/10] HID: ntrig: explain firmware quirk Commit 6549981bc54777c ("HID: fix N-trig touch panel with recent firmware") adds a quirk that is needed for devices with more recent firmware so that they become operational. As it's not directly obvious from the code why is it needed, a comment is worthwile. Signed-off-by: Jiri Kosina --- drivers/hid/hid-ntrig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 513db0a47c4a..a418f9e19ce7 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -352,7 +352,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) } } - report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; + /* This is needed for devices with more recent firmware versions */ + report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; if (report) usbhid_submit_report(hdev, report, USB_DIR_OUT); From 1ce31b255cf8b06470dfbd469055b6fd8d2274bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Doursenaud?= Date: Thu, 8 Apr 2010 13:40:52 +0200 Subject: [PATCH 03/10] HID: add support for cymotion master solar keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support the solar version of the Cherry's cymotion keyboard line using existing cherry driver. Signed-off-by: Raphaël Doursenaud Signed-off-by: Jiri Kosina --- drivers/hid/hid-cherry.c | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + 3 files changed, 3 insertions(+) diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index 7e597d7f770f..24663a8717b1 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c @@ -59,6 +59,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id ch_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { } }; MODULE_DEVICE_TABLE(hid, ch_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 2e2aa759d230..d25152baf5f8 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1296,6 +1296,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 797e06470356..09d27649a0f7 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -131,6 +131,7 @@ #define USB_VENDOR_ID_CHERRY 0x046a #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 +#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027 #define USB_VENDOR_ID_CHIC 0x05fe #define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 From 2170c5a8ae4b952e517e7b0565528914ddc11320 Mon Sep 17 00:00:00 2001 From: Rafi Rubin Date: Fri, 9 Apr 2010 17:58:25 -0400 Subject: [PATCH 04/10] HID: ntrig: Emit TOUCH with DOUBLETAP for single touch I squelched TipSwitch in a recent patch which resulted in the loss of Touch events for single touch firmwares. This patch just puts Touch back in for single touch, and bundles it with DoubleTap (like the multitouch code). The two events are used to convey the same message to different drivers. Signed-off-by: Rafi Rubin Signed-off-by: Jiri Kosina --- drivers/hid/hid-ntrig.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index a418f9e19ce7..58ba0d3d8aa5 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -173,6 +173,8 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, if (!nd->reading_mt) { input_report_key(input, BTN_TOOL_DOUBLETAP, (nd->confidence != 0)); + input_report_key(input, BTN_TOUCH, + (nd->confidence != 0)); input_event(input, EV_ABS, ABS_X, nd->x); input_event(input, EV_ABS, ABS_Y, nd->y); } From c85b86a6dc7b5b4607c3a14fdbda78df06b5c79f Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 21 Apr 2010 17:08:24 -0400 Subject: [PATCH 05/10] HID: wacom: remove annoying non-error printk This is the only line printed on my "quiet" boot and seems completely unnecessary. Signed-off-by: Cory Fields Signed-off-by: Bastien Nocera Signed-off-by: Jiri Kosina --- drivers/hid/hid-wacom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index f7700cf49721..f947d8337e21 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c @@ -277,7 +277,6 @@ static int __init wacom_init(void) ret = hid_register_driver(&wacom_driver); if (ret) printk(KERN_ERR "can't register wacom driver\n"); - printk(KERN_ERR "wacom driver registered\n"); return ret; } From 5a38f2c7c4dd53d5be097930902c108e362584a3 Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Mon, 26 Apr 2010 18:34:46 -0400 Subject: [PATCH 06/10] HID: hidraw: fix numbered reports Make hidraw not stick an extra byte on the beginning of an IN transfer when a HID device contains multiple reports. Signed-off-by: Alan Ott Acked-by: Jiri Slaby Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index d25152baf5f8..143e788b729b 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1043,13 +1043,8 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) hid->hiddev_report_event(hid, report); - if (hid->claimed & HID_CLAIMED_HIDRAW) { - /* numbered reports need to be passed with the report num */ - if (report_enum->numbered) - hidraw_report_event(hid, data - 1, size + 1); - else - hidraw_report_event(hid, data, size); - } + if (hid->claimed & HID_CLAIMED_HIDRAW) + hidraw_report_event(hid, data, size); for (a = 0; a < report->maxfield; a++) hid_input_field(hid, report->field[a], cdata, interrupt); From 250d377522fd81459a4ea2350a794b453f37ce7d Mon Sep 17 00:00:00 2001 From: Rafi Rubin Date: Mon, 3 May 2010 05:08:29 -0400 Subject: [PATCH 07/10] HID: ntrig: TipSwitch for single touch mode touch. Include TipSwitch in the touch detection decision for some single touch firmwares. Confidence and InRange are high for all finger events including those used to indicate the finger is no longer in contact with the sensor. Signed-off-by: Rafi Rubin Signed-off-by: Jiri Kosina --- drivers/hid/hid-ntrig.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 58ba0d3d8aa5..10b08d6ab37c 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -31,10 +31,12 @@ struct ntrig_data { /* Incoming raw values for a single contact */ __u16 x, y, w, h; __u16 id; - __u8 confidence; + + bool tipswitch; + bool confidence; + bool first_contact_touch; bool reading_mt; - __u8 first_contact_confidence; __u8 mt_footer[4]; __u8 mt_foot_count; @@ -141,9 +143,10 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, case 0xff000001: /* Tag indicating the start of a multitouch group */ nd->reading_mt = 1; - nd->first_contact_confidence = 0; + nd->first_contact_touch = 0; break; case HID_DG_TIPSWITCH: + nd->tipswitch = value; /* Prevent emission of touch until validated */ return 1; case HID_DG_CONFIDENCE: @@ -171,10 +174,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, * to emit a normal (X, Y) position */ if (!nd->reading_mt) { - input_report_key(input, BTN_TOOL_DOUBLETAP, - (nd->confidence != 0)); + /* + * TipSwitch indicates the presence of a + * finger in single touch mode. + */ input_report_key(input, BTN_TOUCH, - (nd->confidence != 0)); + nd->tipswitch); + input_report_key(input, BTN_TOOL_DOUBLETAP, + nd->tipswitch); input_event(input, EV_ABS, ABS_X, nd->x); input_event(input, EV_ABS, ABS_Y, nd->y); } @@ -213,7 +220,13 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, /* emit a normal (X, Y) for the first point only */ if (nd->id == 0) { - nd->first_contact_confidence = nd->confidence; + /* + * TipSwitch is superfluous in multitouch + * mode. The footer events tell us + * if there is a finger on the screen or + * not. + */ + nd->first_contact_touch = nd->confidence; input_event(input, EV_ABS, ABS_X, nd->x); input_event(input, EV_ABS, ABS_Y, nd->y); } @@ -243,7 +256,7 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, nd->reading_mt = 0; - if (nd->first_contact_confidence) { + if (nd->first_contact_touch) { switch (value) { case 0: /* for single touch devices */ case 1: From ed7e2ca24bfff5c7a09de8a05c536f68560b34fb Mon Sep 17 00:00:00 2001 From: Rafi Rubin Date: Mon, 3 May 2010 05:08:30 -0400 Subject: [PATCH 08/10] HID: ntrig: Remove unused macro, TripleTap and QuadTap Removing the higher number taps. Their usage was incorrect and even if correct they should not be used for a touch screen. _MT_ events should be used to communicate multiple fingers. Signed-off-by: Rafi Rubin Signed-off-by: Jiri Kosina --- drivers/hid/hid-ntrig.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 10b08d6ab37c..4777bbfa1cc2 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -24,9 +24,6 @@ #define NTRIG_DUPLICATE_USAGES 0x001 -#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ - EV_KEY, (c)) - struct ntrig_data { /* Incoming raw values for a single contact */ __u16 x, y, w, h; @@ -257,29 +254,10 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field, nd->reading_mt = 0; if (nd->first_contact_touch) { - switch (value) { - case 0: /* for single touch devices */ - case 1: - input_report_key(input, - BTN_TOOL_DOUBLETAP, 1); - break; - case 2: - input_report_key(input, - BTN_TOOL_TRIPLETAP, 1); - break; - case 3: - default: - input_report_key(input, - BTN_TOOL_QUADTAP, 1); - } + input_report_key(input, BTN_TOOL_DOUBLETAP, 1); input_report_key(input, BTN_TOUCH, 1); } else { - input_report_key(input, - BTN_TOOL_DOUBLETAP, 0); - input_report_key(input, - BTN_TOOL_TRIPLETAP, 0); - input_report_key(input, - BTN_TOOL_QUADTAP, 0); + input_report_key(input, BTN_TOOL_DOUBLETAP, 0); input_report_key(input, BTN_TOUCH, 0); } break; @@ -345,13 +323,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) __clear_bit(BTN_TOOL_PEN, input->keybit); __clear_bit(BTN_TOOL_FINGER, input->keybit); __clear_bit(BTN_0, input->keybit); - /* - * A little something special to enable - * two and three finger taps. - */ __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); - __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); - __set_bit(BTN_TOOL_QUADTAP, input->keybit); /* * The physical touchscreen (single touch) * input has a value for physical, whereas From fddb33f2e8872fa4857dd29f0b71a523c9ed5577 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 3 May 2010 17:19:03 +0200 Subject: [PATCH 09/10] HID: sony: fix sony_set_operational_bt Don't send the report type as part of the data, this prevents the controller from going into the operational state at all. This is completely equivalent to what the code originally meant to accomplish: as per in net/bluetooth/hidp/core.c::hidp_output_raw_report(), by using HID_FEATURE_REPORT here, what will be actually sent is (HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE) which is exactly 0x53. Signed-off-by: Antonio Ospite Signed-off-by: Bastien Nocera Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 7502a4b2fa86..402d5574b574 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -76,7 +76,7 @@ static int sony_set_operational_usb(struct hid_device *hdev) static int sony_set_operational_bt(struct hid_device *hdev) { - unsigned char buf[] = { 0x53, 0xf4, 0x42, 0x03, 0x00, 0x00 }; + unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); } From fde4e2f73208b8f34f123791e39c0cb6bc74b32a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 7 May 2010 10:41:10 -0400 Subject: [PATCH 10/10] HID: fix suspend crash by moving initializations earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although the usbhid driver allocates its usbhid structure in the probe routine, several critical fields in that structure don't get initialized until usbhid_start(). However if report descriptor parsing fails then usbhid_start() is never called. This leads to problems during system suspend -- the system will freeze. This patch (as1378) fixes the bug by moving the initialization statements up into usbhid_probe(). Signed-off-by: Alan Stern Reported-by: Bruno Prémont Tested-By: Bruno Prémont Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 56d06cd8075b..7b85b696fdab 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -999,13 +999,6 @@ static int usbhid_start(struct hid_device *hid) } } - init_waitqueue_head(&usbhid->wait); - INIT_WORK(&usbhid->reset_work, hid_reset); - INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); - setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); - - spin_lock_init(&usbhid->lock); - usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); if (!usbhid->urbctrl) { ret = -ENOMEM; @@ -1179,6 +1172,12 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * usbhid->intf = intf; usbhid->ifnum = interface->desc.bInterfaceNumber; + init_waitqueue_head(&usbhid->wait); + INIT_WORK(&usbhid->reset_work, hid_reset); + INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); + setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); + spin_lock_init(&usbhid->lock); + ret = hid_add_device(hid); if (ret) { if (ret != -ENODEV)