From 765031668fb2b064aebd9a568e5ad794cbe3413a Mon Sep 17 00:00:00 2001 From: Nestor Lopez Casado Date: Thu, 2 Feb 2012 10:54:14 +0100 Subject: HID: logitech: fix mask to enable DJ mode The user can only experience the bug if she pairs 6 devices to a Unifying receiver. The sixth paired device would not work. The value changed is actually a bitmask that enables reporting from each paired device. As the sixth bit was not set, the sixth device reports are ignored by the receiver and never get to the driver. Signed-off-by: Nestor Lopez Casado drivers/hid/hid-logitech-dj.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 38b12e4..2b56efc 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -445,7 +445,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, dj_report.report_id = REPORT_ID_DJ_SHORT; dj_report.device_index = 0xFF; dj_report.report_type = REPORT_TYPE_CMD_SWITCH; - dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x1F; + dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; return logi_dj_recv_send_report(djrcv_dev, &dj_report); } -- cgit v0.10.2 From 45d9c273b262cde84bb6bb3fc02c01d07da76936 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 7 Dec 2011 17:31:43 -0800 Subject: HID: hid-input/battery: set scope and powered device for HID battery Set the battery's power supply scope to "Device" and point the power supply to the powered device. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9333d69..af0200f 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -279,7 +279,8 @@ static enum power_supply_property hidinput_battery_props[] = { POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_CAPACITY, POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_STATUS + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_SCOPE, }; #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ @@ -344,6 +345,10 @@ static int hidinput_get_battery_property(struct power_supply *psy, val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; + case POWER_SUPPLY_PROP_SCOPE: + val->intval = POWER_SUPPLY_SCOPE_DEVICE; + break; + default: ret = -EINVAL; break; @@ -403,6 +408,8 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, battery->name = NULL; } + power_supply_powers(battery, &dev->dev); + out: return true; } -- cgit v0.10.2 From c2ef8f21ea8f7c34dfa0b569fdee431348205955 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sat, 4 Feb 2012 17:08:48 +0100 Subject: HID: multitouch: add support for trackpads * some multitouch trackpads present the touch usage. This needs to be filtered as it will conflict with mt-implementation. * trackpads send BTN_TOOL_* to notify how many fingers are present (this is used by xorg to use synaptics instead of generic evdev) * trackpads like Perixx 701 are not different from a hid point of view from a touchscreen, and we need to manually set them as touchpad. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 24fc442..4c69749 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1,9 +1,9 @@ /* * HID driver for multitouch panels * - * Copyright (c) 2010-2011 Stephane Chatty - * Copyright (c) 2010-2011 Benjamin Tissoires - * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France + * Copyright (c) 2010-2012 Stephane Chatty + * Copyright (c) 2010-2012 Benjamin Tissoires + * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France * * This code is partly based on hid-egalax.c: * @@ -67,6 +67,7 @@ struct mt_class { __s32 sn_height; /* Signal/noise ratio for height events */ __s32 sn_pressure; /* Signal/noise ratio for pressure events */ __u8 maxcontacts; + bool is_indirect; /* true for touchpads */ }; struct mt_device { @@ -265,17 +266,31 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, { struct mt_device *td = hid_get_drvdata(hdev); struct mt_class *cls = &td->mtclass; + int code; /* Only map fields from TouchScreen or TouchPad collections. * We need to ignore fields that belong to other collections * such as Mouse that might have the same GenericDesktop usages. */ if (field->application == HID_DG_TOUCHSCREEN) set_bit(INPUT_PROP_DIRECT, hi->input->propbit); - else if (field->application == HID_DG_TOUCHPAD) - set_bit(INPUT_PROP_POINTER, hi->input->propbit); - else + else if (field->application != HID_DG_TOUCHPAD) return 0; + /* In case of an indirect device (touchpad), we need to add + * specific BTN_TOOL_* to be handled by the synaptics xorg + * driver. + * We also consider that touchscreens providing buttons are touchpads. + */ + if (field->application == HID_DG_TOUCHPAD || + (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON || + cls->is_indirect) { + set_bit(INPUT_PROP_POINTER, hi->input->propbit); + set_bit(BTN_TOOL_FINGER, hi->input->keybit); + set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit); + set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit); + set_bit(BTN_TOOL_QUADTAP, hi->input->keybit); + } + /* eGalax devices provide a Digitizer.Stylus input which overrides * the correct Digitizers.Finger X/Y ranges. * Let's just ignore this input. */ @@ -389,9 +404,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->last_field_index = field->index; return -1; } + case HID_DG_TOUCH: + /* Legacy devices use TIPSWITCH and not TOUCH. + * Let's just ignore this field. */ + return -1; /* let hid-input decide for the others */ return 0; + case HID_UP_BUTTON: + code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE); + hid_map_usage(hi, usage, bit, max, EV_KEY, code); + input_set_capability(hi->input, EV_KEY, code); + return 1; + case 0xff000000: /* we do not want to map these: no input-oriented meaning */ return -1; @@ -538,6 +563,9 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, if (value) td->num_expected = value; break; + case HID_DG_TOUCH: + /* do nothing */ + break; default: /* fallback to the generic hidinput handling */ -- cgit v0.10.2 From 31ae9bddb935c74b51ead08d54948e5bea0f0344 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sat, 4 Feb 2012 17:08:49 +0100 Subject: HID: multitouch: add control of the feature "Maximum Contact Number" Some devices, like Perixx Peripad 701 do not work if the feature "Maximum Contact Number" is not set to the right value. This patch allows hid-multitouch to control this feature. If the programmer fills the field maxcontacts in the mt_class, then the driver will set the feature to this value. It is safe for current drivers as the feature is read/write in the HID norm and all devices should implement the norm. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 4c69749..d0fa6a7 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -77,6 +77,8 @@ struct mt_device { unsigned last_slot_field; /* the last field of a slot */ int last_mt_collection; /* last known mt-related collection */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ + __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, + -1 if non-existent */ __u8 num_received; /* how many contacts we received */ __u8 num_expected; /* expected last contact index */ __u8 maxcontacts; @@ -242,6 +244,7 @@ static void mt_feature_mapping(struct hid_device *hdev, td->inputmode = field->report->id; break; case HID_DG_CONTACTMAX: + td->maxcontact_report_id = field->report->id; td->maxcontacts = field->value[0]; if (td->mtclass.maxcontacts) /* check if the maxcontacts is given by the class */ @@ -606,6 +609,32 @@ static void mt_set_input_mode(struct hid_device *hdev) } } +static void mt_set_maxcontacts(struct hid_device *hdev) +{ + struct mt_device *td = hid_get_drvdata(hdev); + struct hid_report *r; + struct hid_report_enum *re; + int fieldmax, max; + + if (td->maxcontact_report_id < 0) + return; + + if (!td->mtclass.maxcontacts) + return; + + re = &hdev->report_enum[HID_FEATURE_REPORT]; + r = re->report_id_hash[td->maxcontact_report_id]; + if (r) { + max = td->mtclass.maxcontacts; + fieldmax = r->field[0]->logical_maximum; + max = min(fieldmax, max); + if (r->field[0]->value[0] != max) { + r->field[0]->value[0] = max; + usbhid_submit_report(hdev, r, USB_DIR_OUT); + } + } +} + static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret, i; @@ -631,6 +660,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) } td->mtclass = *mtclass; td->inputmode = -1; + td->maxcontact_report_id = -1; td->last_mt_collection = -1; hid_set_drvdata(hdev, td); @@ -653,6 +683,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); + mt_set_maxcontacts(hdev); mt_set_input_mode(hdev); return 0; @@ -665,6 +696,7 @@ fail: #ifdef CONFIG_PM static int mt_reset_resume(struct hid_device *hdev) { + mt_set_maxcontacts(hdev); mt_set_input_mode(hdev); return 0; } -- cgit v0.10.2 From 847672cd141c07db3d5fc1442b4c3e8a702488df Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sat, 4 Feb 2012 17:08:50 +0100 Subject: HID: multitouch: support Perixx PERIPAD 701 Perixx Peripad 701 is an hybrid device which presents a touchpad and a keyboard on the same surface. The switch between the two is controlled by a physical switch, and the firmware sends the events on the right interface (mouse, keyboard or multitouch). This patch enables the multitouch interface of this device to work. We need to manually set the device as a trackpad (we cannot infer it from the reports descriptors as the device works under Windows, a system that does not allow multitouch touchpad). We also need to set the hid feature MAX CONTACT NUMBER to 2 or the device stops sending events once it has been pressed by two touches. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a421abd..f7c43b6 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -355,6 +355,7 @@ config HID_MULTITOUCH - Lumio CrystalTouch panels - MosArt dual-touch panels - PenMount dual touch panels + - Perixx Peripad 701 touchpad - PixArt optical touch screen - Pixcir dual touch panels - Quanta panels diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cd..662a0b6 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -659,6 +659,7 @@ #define USB_VENDOR_ID_TOPSEED2 0x1784 #define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 +#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016 #define USB_VENDOR_ID_TOPMAX 0x0663 #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index d0fa6a7..387a72f 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -103,6 +103,7 @@ struct mt_device { #define MT_CLS_CYPRESS 0x0102 #define MT_CLS_EGALAX 0x0103 #define MT_CLS_EGALAX_SERIAL 0x0104 +#define MT_CLS_TOPSEED 0x0105 #define MT_DEFAULT_MAXCONTACT 10 @@ -192,6 +193,11 @@ static struct mt_class mt_classes[] = { .sn_move = 4096, .sn_pressure = 32, }, + { .name = MT_CLS_TOPSEED, + .quirks = MT_QUIRK_ALWAYS_VALID, + .is_indirect = true, + .maxcontacts = 2, + }, { } }; @@ -897,6 +903,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX)}, + /* TopSeed panels */ + { .driver_data = MT_CLS_TOPSEED, + HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, + USB_DEVICE_ID_TOPSEED2_PERIPAD_701) }, + /* Touch International panels */ { .driver_data = MT_CLS_DEFAULT, HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, -- cgit v0.10.2 From 2258e863b451be319d374f89688000ab858b13c3 Mon Sep 17 00:00:00 2001 From: Denis Kovalev Date: Tue, 14 Feb 2012 00:50:33 -0800 Subject: HID: multitouch: add support of Panasonic multitouch panels While at it, also fix some minor codingstyle issues. Signed-off-by: Denis Kovalev Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index f7c43b6..bfac1f7 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -354,6 +354,7 @@ config HID_MULTITOUCH - LG Display panels (Dell ST2220Tc) - Lumio CrystalTouch panels - MosArt dual-touch panels + - Panasonic multitouch panels - PenMount dual touch panels - Perixx Peripad 701 touchpad - PixArt optical touch screen diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7..bb710a6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1501,6 +1501,8 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) }, { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT780) }, + { HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, USB_DEVICE_ID_PANABOARD_UBT880) }, { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) }, { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 662a0b6..12b6c49 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -41,7 +41,7 @@ #define USB_VENDOR_ID_ACTIONSTAR 0x2101 #define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 -#define USB_VENDOR_ID_ADS_TECH 0x06e1 +#define USB_VENDOR_ID_ADS_TECH 0x06e1 #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 #define USB_VENDOR_ID_AFATECH 0x15a4 @@ -565,6 +565,10 @@ #define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 #define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 +#define USB_VENDOR_ID_PANASONIC 0x04da +#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 +#define USB_DEVICE_ID_PANABOARD_UBT880 0x104d + #define USB_VENDOR_ID_PANJIT 0x134c #define USB_VENDOR_ID_PANTHERLORD 0x0810 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 387a72f..09e42ef 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -104,6 +104,7 @@ struct mt_device { #define MT_CLS_EGALAX 0x0103 #define MT_CLS_EGALAX_SERIAL 0x0104 #define MT_CLS_TOPSEED 0x0105 +#define MT_CLS_PANASONIC 0x0106 #define MT_DEFAULT_MAXCONTACT 10 @@ -198,6 +199,9 @@ static struct mt_class mt_classes[] = { .is_indirect = true, .maxcontacts = 2, }, + { .name = MT_CLS_PANASONIC, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, + .maxcontacts = 4 }, { } }; @@ -278,8 +282,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, int code; /* Only map fields from TouchScreen or TouchPad collections. - * We need to ignore fields that belong to other collections - * such as Mouse that might have the same GenericDesktop usages. */ + * We need to ignore fields that belong to other collections + * such as Mouse that might have the same GenericDesktop usages. */ if (field->application == HID_DG_TOUCHSCREEN) set_bit(INPUT_PROP_DIRECT, hi->input->propbit); else if (field->application != HID_DG_TOUCHPAD) @@ -581,9 +585,8 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, return 0; } - if (usage->hid == td->last_slot_field) { + if (usage->hid == td->last_slot_field) mt_complete_slot(td); - } if (field->index == td->last_field_index && td->num_received >= td->num_expected) @@ -857,6 +860,14 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, + /* Panasonic panels */ + { .driver_data = MT_CLS_PANASONIC, + HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, + USB_DEVICE_ID_PANABOARD_UBT780) }, + { .driver_data = MT_CLS_PANASONIC, + HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC, + USB_DEVICE_ID_PANABOARD_UBT880) }, + /* PenMount panels */ { .driver_data = MT_CLS_CONFIDENCE, HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, -- cgit v0.10.2 From 841cb1570d2c9eed4496ac9ce53c4fd4ae66ebfc Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 10:53:45 +0100 Subject: HID: multitouch: add support for Atmel maXTouch 03eb:2118 Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 12b6c49..5cb1d63 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -149,6 +149,7 @@ #define USB_VENDOR_ID_ATMEL 0x03eb #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c +#define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 #define USB_VENDOR_ID_AVERMEDIA 0x07ca #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 09e42ef..03990a8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -743,6 +743,9 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_SERIAL, HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, USB_DEVICE_ID_ATMEL_MULTITOUCH) }, + { .driver_data = MT_CLS_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, + USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) }, /* Cando panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, -- cgit v0.10.2 From 71078b0deba8420e00b0c5e39ea359dbcaa11114 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 10:53:46 +0100 Subject: HID: multitouch: add new PID from Ideacom Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5cb1d63..10a9ca9 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -375,6 +375,7 @@ #define USB_VENDOR_ID_IDEACOM 0x1cb6 #define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 +#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 #define USB_VENDOR_ID_ILITEK 0x222a #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 03990a8..c7ee035 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -828,6 +828,9 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_SERIAL, HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) }, + { .driver_data = MT_CLS_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, + USB_DEVICE_ID_IDEACOM_IDC6651) }, /* Ilitek dual touch panel */ { .driver_data = MT_CLS_DEFAULT, -- cgit v0.10.2 From fd1d152583e6ce02b47cb7315295ab58014aa26d Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 10:53:47 +0100 Subject: HID: multitouch: add more eGalax devices This is a list of devices that should be handled by hid-multitouch. They all present the HID usage "Contact ID" and won't be handled by hid-input. Some of them have _not_ been tested (though I have their report descriptors), but I've been guaranted by eeti that they follow the same protocol. The tested ones are also blacklisted in hid-core.c. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bb710a6..4f4143c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1409,6 +1409,8 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 10a9ca9..e5e3286 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -238,11 +238,17 @@ #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 #define USB_VENDOR_ID_ELECOM 0x056e diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index c7ee035..0eda37f 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -788,12 +788,27 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) }, { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) }, { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, @@ -802,6 +817,9 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, { .driver_data = MT_CLS_EGALAX_SERIAL, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, /* Elo TouchSystems IntelliTouch Plus panel */ -- cgit v0.10.2 From 8d31321ca5367daf0415ed81f9cbd93adb16e8bc Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 10:53:48 +0100 Subject: HID: usbhid: add quirk no_get for quanta 3008 devices Some quanta devices do not like to be polled for reports descriptors, thus this quirk. Signed-off-by: Benjamin Tissoires Acked-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index c831af9..4d248d5 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -73,6 +73,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, -- cgit v0.10.2 From 2ce09df47b67f16367272f63f85f4cc991e6009a Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 17:57:02 +0100 Subject: HID: multitouch: add support for eGalax 0x722a Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e5e3286..e0bac4f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -241,6 +241,7 @@ #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A 0x722A #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 0eda37f..019de83 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -797,6 +797,9 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_EGALAX_SERIAL, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) }, + { .driver_data = MT_CLS_EGALAX_SERIAL, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) }, { .driver_data = MT_CLS_EGALAX, HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, -- cgit v0.10.2 From ed9d5c96147b3bed6178252e8e04b27b7d32edd0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 17:57:03 +0100 Subject: HID: multitouch: fix handling of buggy reports descriptors for Dell ST2220T LG multitouch panels, such as the one found in Dell ST2220T, has buggy reports descriptors. With the previous implementation, it was impossible to rely on the reports descriptors to determine how the different touches are emitted from the device. This patch changes the splitting of the different touches in the report in a more robust way. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 019de83..2088ab4 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -75,7 +75,6 @@ struct mt_device { struct mt_class mtclass; /* our mt device class */ unsigned last_field_index; /* last field index of the report */ unsigned last_slot_field; /* the last field of a slot */ - int last_mt_collection; /* last known mt-related collection */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, -1 if non-existent */ @@ -273,6 +272,13 @@ static void set_abs(struct input_dev *input, unsigned int code, input_set_abs_params(input, code, fmin, fmax, fuzz, 0); } +static void set_last_slot_field(struct hid_usage *usage, struct mt_device *td, + struct hid_input *hi) +{ + if (!test_bit(usage->hid, hi->input->absbit)) + td->last_slot_field = usage->hid; +} + static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) @@ -321,10 +327,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_X, field, cls->sn_move); - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_GD_Y: hid_map_usage(hi, usage, bit, max, @@ -333,10 +337,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, cls->sn_move); /* touchscreen emulation */ set_abs(hi->input, ABS_Y, field, cls->sn_move); - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; } return 0; @@ -344,24 +346,18 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_UP_DIGITIZER: switch (usage->hid) { case HID_DG_INRANGE: - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_DG_CONFIDENCE: - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_DG_TIPSWITCH: hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); input_set_capability(hi->input, EV_KEY, BTN_TOUCH); - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_DG_CONTACTID: if (!td->maxcontacts) @@ -369,17 +365,14 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; td->last_field_index = field->index; - td->last_mt_collection = usage->collection_index; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MAJOR); set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, cls->sn_width); - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, @@ -388,10 +381,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, cls->sn_height); input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 0, 1, 0, 0); - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_DG_TIPPRESSURE: hid_map_usage(hi, usage, bit, max, @@ -401,20 +392,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, /* touchscreen emulation */ set_abs(hi->input, ABS_PRESSURE, field, cls->sn_pressure); - if (td->last_mt_collection == usage->collection_index) { - td->last_slot_field = usage->hid; - td->last_field_index = field->index; - } + set_last_slot_field(usage, td, hi); + td->last_field_index = field->index; return 1; case HID_DG_CONTACTCOUNT: - if (td->last_mt_collection == usage->collection_index) - td->last_field_index = field->index; + td->last_field_index = field->index; return 1; case HID_DG_CONTACTMAX: /* we don't set td->last_slot_field as contactcount and * contact max are global to the report */ - if (td->last_mt_collection == usage->collection_index) - td->last_field_index = field->index; + td->last_field_index = field->index; return -1; } case HID_DG_TOUCH: @@ -670,7 +657,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) td->mtclass = *mtclass; td->inputmode = -1; td->maxcontact_report_id = -1; - td->last_mt_collection = -1; hid_set_drvdata(hdev, td); ret = hid_parse(hdev); -- cgit v0.10.2 From 8d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 17:57:04 +0100 Subject: HID: handle all multitouch devices through hid-multitouch When the quirk HID_QUIRK_MULTITOUCH is present and when hid-multitouch is loaded, let's pass the device to hid-multitouch even if it has not been registered in hid-multitouch. If any other driver wants to take precedence over hid-multitouch, the usual way of adding it to hid_have_special_driver will work as the quirk HID_QUIRK_MULTITOUCH won't be set by the generic hid layer. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 4f4143c..05a0c9a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1232,7 +1232,6 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) hdev->claimed |= HID_CLAIMED_INPUT; if (hdev->quirks & HID_QUIRK_MULTITOUCH) { /* this device should be handled by hid-multitouch, skip it */ - hdev->quirks &= ~HID_QUIRK_MULTITOUCH; return -ENODEV; } @@ -1667,6 +1666,10 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv) struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); struct hid_device *hdev = container_of(dev, struct hid_device, dev); + if ((hdev->quirks & HID_QUIRK_MULTITOUCH) && + !strncmp(hdrv->name, "hid-multitouch", 14)) + return 1; + if (!hid_match_device(hdev, hdrv)) return 0; @@ -1691,8 +1694,11 @@ static int hid_device_probe(struct device *dev) if (!hdev->driver) { id = hid_match_device(hdev, hdrv); if (id == NULL) { - ret = -ENODEV; - goto unlock; + if (!((hdev->quirks & HID_QUIRK_MULTITOUCH) && + !strncmp(hdrv->name, "hid-multitouch", 14))) { + ret = -ENODEV; + goto unlock; + } } hdev->driver = hdrv; diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 2088ab4..a61ba42 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -637,10 +637,12 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) struct mt_device *td; struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ - for (i = 0; mt_classes[i].name ; i++) { - if (id->driver_data == mt_classes[i].name) { - mtclass = &(mt_classes[i]); - break; + if (id) { + for (i = 0; mt_classes[i].name ; i++) { + if (id->driver_data == mt_classes[i].name) { + mtclass = &(mt_classes[i]); + break; + } } } @@ -648,6 +650,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) * that emit events over several HID messages. */ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; + hdev->quirks &= ~HID_QUIRK_MULTITOUCH; td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); if (!td) { -- cgit v0.10.2 From 9e87f22ac6353b50425c5da412fe2418a48e25a3 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 6 Mar 2012 17:57:06 +0100 Subject: HID: multitouch: detect serial protocol Microsoft's documentation about multitouch protocols tells that if a device presents one touch per report, then it should be treated as a serial protocol. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index a61ba42..6fb46d7 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -81,6 +81,9 @@ struct mt_device { __u8 num_received; /* how many contacts we received */ __u8 num_expected; /* expected last contact index */ __u8 maxcontacts; + __u8 touches_by_report; /* how many touches are present in one report: + * 1 means we should use a serial protocol + * > 1 means hybrid (multitouch) protocol */ bool curvalid; /* is the current contact valid? */ struct mt_slot *slots; }; @@ -365,6 +368,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; td->last_field_index = field->index; + td->touches_by_report++; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, @@ -670,6 +674,15 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto fail; + if (!id && td->touches_by_report == 1) { + /* the device has been sent by hid-generic */ + mtclass = &td->mtclass; + mtclass->quirks |= MT_QUIRK_ALWAYS_VALID; + mtclass->quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP; + mtclass->quirks &= ~MT_QUIRK_VALID_IS_INRANGE; + mtclass->quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE; + } + td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), GFP_KERNEL); if (!td->slots) { -- cgit v0.10.2