From 9498f954a4ec389806333041a1018909c6fe0518 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:52 +0100 Subject: HID: hid-multitouch: Auto detection of maxcontacts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enables support of autodetection of maxcontacts. When adding support for a new device, one is now able to let the device tell how many contacts it supports, or to manually set the value if the device happens to provide wrong information. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ee01e65..b9f9eec 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -60,8 +60,9 @@ struct mt_device { __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ __u8 num_received; /* how many contacts we received */ __u8 num_expected; /* expected last contact index */ + __u8 maxcontacts; bool curvalid; /* is the current contact valid? */ - struct mt_slot slots[0]; /* first slot */ + struct mt_slot *slots; }; struct mt_class { @@ -79,6 +80,8 @@ struct mt_class { #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 +#define MT_DEFAULT_MAXCONTACT 10 + /* * these device-dependent functions determine what slot corresponds * to a valid contact that was just read. @@ -95,12 +98,12 @@ static int cypress_compute_slot(struct mt_device *td) static int find_slot_from_contactid(struct mt_device *td) { int i; - for (i = 0; i < td->mtclass->maxcontacts; ++i) { + for (i = 0; i < td->maxcontacts; ++i) { if (td->slots[i].contactid == td->curdata.contactid && td->slots[i].touch_state) return i; } - for (i = 0; i < td->mtclass->maxcontacts; ++i) { + for (i = 0; i < td->maxcontacts; ++i) { if (!td->slots[i].seen_in_this_frame && !td->slots[i].touch_state) return i; @@ -113,8 +116,7 @@ static int find_slot_from_contactid(struct mt_device *td) struct mt_class mt_classes[] = { { .name = MT_CLS_DEFAULT, - .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP, - .maxcontacts = 10 }, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, { .name = MT_CLS_DUAL_INRANGE_CONTACTID, .quirks = MT_QUIRK_VALID_IS_INRANGE | MT_QUIRK_SLOT_IS_CONTACTID, @@ -142,9 +144,19 @@ struct mt_class mt_classes[] = { static void mt_feature_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { - if (usage->hid == HID_DG_INPUTMODE) { - struct mt_device *td = hid_get_drvdata(hdev); + struct mt_device *td = hid_get_drvdata(hdev); + + switch (usage->hid) { + case HID_DG_INPUTMODE: td->inputmode = field->report->id; + break; + case HID_DG_CONTACTMAX: + td->maxcontacts = field->value[0]; + if (td->mtclass->maxcontacts) + /* check if the maxcontacts is given by the class */ + td->maxcontacts = td->mtclass->maxcontacts; + + break; } } @@ -208,8 +220,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, td->last_slot_field = usage->hid; return 1; case HID_DG_CONTACTID: - input_mt_init_slots(hi->input, - td->mtclass->maxcontacts); + input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; return 1; case HID_DG_WIDTH: @@ -292,7 +303,7 @@ static void mt_complete_slot(struct mt_device *td) if (td->curvalid) { int slotnum = mt_compute_slot(td); - if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) + if (slotnum >= 0 && slotnum < td->maxcontacts) td->slots[slotnum] = td->curdata; } td->num_received++; @@ -307,7 +318,7 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) { int i; - for (i = 0; i < td->mtclass->maxcontacts; ++i) { + for (i = 0; i < td->maxcontacts; ++i) { struct mt_slot *s = &(td->slots[i]); if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && !s->seen_in_this_frame) { @@ -341,7 +352,7 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, struct mt_device *td = hid_get_drvdata(hid); __s32 quirks = td->mtclass->quirks; - if (hid->claimed & HID_CLAIMED_INPUT) { + if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { switch (usage->hid) { case HID_DG_INRANGE: if (quirks & MT_QUIRK_VALID_IS_INRANGE) @@ -442,9 +453,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) */ hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; - td = kzalloc(sizeof(struct mt_device) + - mtclass->maxcontacts * sizeof(struct mt_slot), - GFP_KERNEL); + td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); if (!td) { dev_err(&hdev->dev, "cannot allocate multitouch data\n"); return -ENOMEM; @@ -461,6 +470,18 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto fail; + if (!td->maxcontacts) + td->maxcontacts = MT_DEFAULT_MAXCONTACT; + + td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), + GFP_KERNEL); + if (!td->slots) { + dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); + hid_hw_stop(hdev); + ret = -ENOMEM; + goto fail; + } + mt_set_input_mode(hdev); return 0; @@ -482,6 +503,7 @@ static void mt_remove(struct hid_device *hdev) { struct mt_device *td = hid_get_drvdata(hdev); hid_hw_stop(hdev); + kfree(td->slots); kfree(td); hid_set_drvdata(hdev, NULL); } -- cgit v0.10.2 From 043b403aede4a528ed99ceaf050f567f1283a23e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:53 +0100 Subject: HID: hid-multitouch: migrate support for Stantum panels to the unified driver. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges hid-stantum to the generic multitouch driver. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b7ec405..3c72f16 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -327,6 +327,7 @@ config HID_MULTITOUCH - 'Sensing Win7-TwoFinger' panel by GeneralTouch - eGalax dual-touch panels, including the Joojoo and Wetab tablets + - Stantum multitouch panels If unsure, say N. @@ -493,12 +494,6 @@ config HID_SONY ---help--- Support for Sony PS3 controller. -config HID_STANTUM - tristate "Stantum multitouch panel" - depends on USB_HID - ---help--- - Support for Stantum multitouch panel. - config HID_SUNPLUS tristate "Sunplus wireless desktop" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 06c68ae..a13cb4e 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -66,7 +66,6 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o obj-$(CONFIG_HID_SONY) += hid-sony.o -obj-$(CONFIG_HID_STANTUM) += hid-stantum.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index b9f9eec..5983e55 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -79,6 +79,7 @@ struct mt_class { #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 +#define MT_CLS_STANTUM 6 #define MT_DEFAULT_MAXCONTACT 10 @@ -138,6 +139,9 @@ struct mt_class mt_classes[] = { .sn_move = 4096, .sn_pressure = 32, }, + { .name = MT_CLS_STANTUM, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { } }; @@ -552,6 +556,17 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, + /* Stantum panels */ + { .driver_data = MT_CLS_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + USB_DEVICE_ID_MTP)}, + { .driver_data = MT_CLS_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + USB_DEVICE_ID_MTP_STM)}, + { .driver_data = MT_CLS_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + USB_DEVICE_ID_MTP_SITRONIX)}, + { } }; MODULE_DEVICE_TABLE(hid, mt_devices); diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c deleted file mode 100644 index b2be1d1..0000000 --- a/drivers/hid/hid-stantum.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * HID driver for Stantum multitouch panels - * - * Copyright (c) 2009 Stephane Chatty - * - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("Stantum HID multitouch panels"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -struct stantum_data { - __s32 x, y, z, w, h; /* x, y, pressure, width, height */ - __u16 id; /* touch id */ - bool valid; /* valid finger data, or just placeholder? */ - bool first; /* first finger in the HID packet? */ - bool activity; /* at least one active finger so far? */ -}; - -static int stantum_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - case HID_DG_INRANGE: - case HID_DG_CONFIDENCE: - case HID_DG_INPUTMODE: - case HID_DG_DEVICEINDEX: - case HID_DG_CONTACTCOUNT: - case HID_DG_CONTACTMAX: - return -1; - - case HID_DG_TIPSWITCH: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - return 1; - - case HID_DG_WIDTH: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MAJOR); - return 1; - case HID_DG_HEIGHT: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MINOR); - input_set_abs_params(hi->input, ABS_MT_ORIENTATION, - 1, 1, 0, 0); - return 1; - case HID_DG_TIPPRESSURE: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_PRESSURE); - return 1; - - case HID_DG_CONTACTID: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TRACKING_ID); - return 1; - - } - return 0; - - case 0xff000000: - /* no input-oriented meaning */ - return -1; - } - - return 0; -} - -static int stantum_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if (usage->type == EV_KEY || usage->type == EV_ABS) - clear_bit(usage->code, *bit); - - return 0; -} - -/* - * this function is called when a whole finger has been parsed, - * so that it can decide what to send to the input layer. - */ -static void stantum_filter_event(struct stantum_data *sd, - struct input_dev *input) -{ - bool wide; - - if (!sd->valid) { - /* - * touchscreen emulation: if the first finger is not valid and - * there previously was finger activity, this is a release - */ - if (sd->first && sd->activity) { - input_event(input, EV_KEY, BTN_TOUCH, 0); - sd->activity = false; - } - return; - } - - input_event(input, EV_ABS, ABS_MT_TRACKING_ID, sd->id); - input_event(input, EV_ABS, ABS_MT_POSITION_X, sd->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, sd->y); - - wide = (sd->w > sd->h); - input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, wide ? sd->w : sd->h); - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, wide ? sd->h : sd->w); - - input_event(input, EV_ABS, ABS_MT_PRESSURE, sd->z); - - input_mt_sync(input); - sd->valid = false; - - /* touchscreen emulation */ - if (sd->first) { - if (!sd->activity) { - input_event(input, EV_KEY, BTN_TOUCH, 1); - sd->activity = true; - } - input_event(input, EV_ABS, ABS_X, sd->x); - input_event(input, EV_ABS, ABS_Y, sd->y); - } - sd->first = false; -} - - -static int stantum_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct stantum_data *sd = hid_get_drvdata(hid); - - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - - switch (usage->hid) { - case HID_DG_INRANGE: - /* this is the last field in a finger */ - stantum_filter_event(sd, input); - break; - case HID_DG_WIDTH: - sd->w = value; - break; - case HID_DG_HEIGHT: - sd->h = value; - break; - case HID_GD_X: - sd->x = value; - break; - case HID_GD_Y: - sd->y = value; - break; - case HID_DG_TIPPRESSURE: - sd->z = value; - break; - case HID_DG_CONTACTID: - sd->id = value; - break; - case HID_DG_CONFIDENCE: - sd->valid = !!value; - break; - case 0xff000002: - /* this comes only before the first finger */ - sd->first = true; - break; - - default: - /* ignore the others */ - return 1; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int stantum_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - struct stantum_data *sd; - - sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL); - if (!sd) { - hid_err(hdev, "cannot allocate Stantum data\n"); - return -ENOMEM; - } - sd->valid = false; - sd->first = false; - sd->activity = false; - hid_set_drvdata(hdev, sd); - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret) - kfree(sd); - - return ret; -} - -static void stantum_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id stantum_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, - { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, - { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, - { } -}; -MODULE_DEVICE_TABLE(hid, stantum_devices); - -static const struct hid_usage_id stantum_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver stantum_driver = { - .name = "stantum", - .id_table = stantum_devices, - .probe = stantum_probe, - .remove = stantum_remove, - .input_mapping = stantum_input_mapping, - .input_mapped = stantum_input_mapped, - .usage_table = stantum_grabbed_usages, - .event = stantum_event, -}; - -static int __init stantum_init(void) -{ - return hid_register_driver(&stantum_driver); -} - -static void __exit stantum_exit(void) -{ - hid_unregister_driver(&stantum_driver); -} - -module_init(stantum_init); -module_exit(stantum_exit); - -- cgit v0.10.2 From a841b62c5d5f75ce3676fde755696d30cc8de99a Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:54 +0100 Subject: HID: hid-multitouch: migrate Cando dual touch panels to hid-multitouch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges hid-cando into the unified multitouch driver. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3c72f16..1edb0bd 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -100,12 +100,6 @@ config HID_BELKIN ---help--- Support for Belkin Flip KVM and Wireless keyboard. -config HID_CANDO - tristate "Cando dual touch panel" - depends on USB_HID - ---help--- - Support for Cando dual touch panel. - config HID_CHERRY tristate "Cherry Cymotion keyboard" if EXPERT depends on USB_HID @@ -320,6 +314,7 @@ config HID_MULTITOUCH Generic support for HID multitouch panels. Say Y here if you have one of the following devices: + - Cando dual touch panel - Cypress TrueTouch panels - Hanvon dual touch panels - IrTouch Infrared USB panels diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index a13cb4e..f8b90e4 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_BELKIN) += hid-belkin.o -obj-$(CONFIG_HID_CANDO) += hid-cando.o obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CHICONY) += hid-chicony.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c deleted file mode 100644 index 1ea066c..0000000 --- a/drivers/hid/hid-cando.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * HID driver for Cando dual-touch panels - * - * Copyright (c) 2010 Stephane Chatty - * - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("Cando dual-touch panel"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -struct cando_data { - __u16 x, y; - __u8 id; - __s8 oldest; /* id of the oldest finger in previous frame */ - bool valid; /* valid finger data, or just placeholder? */ - bool first; /* is this the first finger in this frame? */ - __s8 firstid; /* id of the first finger in the frame */ - __u16 firstx, firsty; /* (x, y) of the first finger in the frame */ -}; - -static int cando_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - case HID_DG_TIPSWITCH: - case HID_DG_CONTACTMAX: - return -1; - case HID_DG_INRANGE: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - return 1; - case HID_DG_CONTACTID: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TRACKING_ID); - return 1; - } - return 0; - } - - return 0; -} - -static int cando_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if (usage->type == EV_KEY || usage->type == EV_ABS) - clear_bit(usage->code, *bit); - - return 0; -} - -/* - * this function is called when a whole finger has been parsed, - * so that it can decide what to send to the input layer. - */ -static void cando_filter_event(struct cando_data *td, struct input_dev *input) -{ - td->first = !td->first; /* touchscreen emulation */ - - if (!td->valid) { - /* - * touchscreen emulation: if this is the second finger and - * the first was valid, the first was the oldest; if the - * first was not valid and there was a valid finger in the - * previous frame, this is a release. - */ - if (td->first) { - td->firstid = -1; - } else if (td->firstid >= 0) { - input_event(input, EV_ABS, ABS_X, td->firstx); - input_event(input, EV_ABS, ABS_Y, td->firsty); - td->oldest = td->firstid; - } else if (td->oldest >= 0) { - input_event(input, EV_KEY, BTN_TOUCH, 0); - td->oldest = -1; - } - - return; - } - - input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); - input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); - - input_mt_sync(input); - - /* - * touchscreen emulation: if there was no touching finger previously, - * emit touch event - */ - if (td->oldest < 0) { - input_event(input, EV_KEY, BTN_TOUCH, 1); - td->oldest = td->id; - } - - /* - * touchscreen emulation: if this is the first finger, wait for the - * second; the oldest is then the second if it was the oldest already - * or if there was no first, the first otherwise. - */ - if (td->first) { - td->firstx = td->x; - td->firsty = td->y; - td->firstid = td->id; - } else { - int x, y, oldest; - if (td->id == td->oldest || td->firstid < 0) { - x = td->x; - y = td->y; - oldest = td->id; - } else { - x = td->firstx; - y = td->firsty; - oldest = td->firstid; - } - input_event(input, EV_ABS, ABS_X, x); - input_event(input, EV_ABS, ABS_Y, y); - td->oldest = oldest; - } -} - - -static int cando_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct cando_data *td = hid_get_drvdata(hid); - - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - - switch (usage->hid) { - case HID_DG_INRANGE: - td->valid = value; - break; - case HID_DG_CONTACTID: - td->id = value; - break; - case HID_GD_X: - td->x = value; - break; - case HID_GD_Y: - td->y = value; - cando_filter_event(td, input); - break; - case HID_DG_TIPSWITCH: - /* avoid interference from generic hidinput handling */ - break; - - default: - /* fallback to the generic hidinput handling */ - return 0; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - struct cando_data *td; - - td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); - if (!td) { - hid_err(hdev, "cannot allocate Cando Touch data\n"); - return -ENOMEM; - } - hid_set_drvdata(hdev, td); - td->first = false; - td->oldest = -1; - td->valid = false; - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret) - kfree(td); - - return ret; -} - -static void cando_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id cando_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, - { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, - USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, - { } -}; -MODULE_DEVICE_TABLE(hid, cando_devices); - -static const struct hid_usage_id cando_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver cando_driver = { - .name = "cando-touch", - .id_table = cando_devices, - .probe = cando_probe, - .remove = cando_remove, - .input_mapping = cando_input_mapping, - .input_mapped = cando_input_mapped, - .usage_table = cando_grabbed_usages, - .event = cando_event, -}; - -static int __init cando_init(void) -{ - return hid_register_driver(&cando_driver); -} - -static void __exit cando_exit(void) -{ - hid_unregister_driver(&cando_driver); -} - -module_init(cando_init); -module_exit(cando_exit); - diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 5983e55..e6e1ea2 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -514,6 +514,20 @@ static void mt_remove(struct hid_device *hdev) static const struct hid_device_id mt_devices[] = { + /* Cando panels */ + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, + { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, + HID_USB_DEVICE(USB_VENDOR_ID_CANDO, + USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, + /* Cypress panel */ { .driver_data = MT_CLS_CYPRESS, HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, -- cgit v0.10.2 From 1e648a13720ef5de51f132501acf3e443d1a36d4 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Mar 2011 14:27:55 +0100 Subject: HID: hid-multitouch: refactor initialization of ABS_MT_ORIENTATION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way the input_set_abs_params was called for the new composite field ABS_MT_ORIENTATION was not very clear at second reading. We can remove the non-necessary call to set_abs and use the simple call to input_set_abs_params. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e6e1ea2..d31301e 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -235,9 +235,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); - field->logical_maximum = 1; - field->logical_minimum = 0; - set_abs(hi->input, ABS_MT_ORIENTATION, field, 0); + input_set_abs_params(hi->input, + ABS_MT_ORIENTATION, 0, 1, 0, 0); td->last_slot_field = usage->hid; return 1; case HID_DG_TIPPRESSURE: -- cgit v0.10.2 From c54ea4918c2b7722d7242ea53271356501988a9b Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Sat, 19 Mar 2011 20:29:44 -0400 Subject: HID: Documentation for hidraw Documenation for the hidraw driver, with sample program. Signed-off-by: Alan Ott Signed-off-by: Jiri Kosina diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt new file mode 100644 index 0000000..029e6cb --- /dev/null +++ b/Documentation/hid/hidraw.txt @@ -0,0 +1,119 @@ + HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices + ================================================================== + +The hidraw driver provides a raw interface to USB and Bluetooth Human +Interface Devices (HIDs). It differs from hiddev in that reports sent and +received are not parsed by the HID parser, but are sent to and received from +the device unmodified. + +Hidraw should be used if the userspace application knows exactly how to +communicate with the hardware device, and is able to construct the HID +reports manually. This is often the case when making userspace drivers for +custom HID devices. + +Hidraw is also useful for communicating with non-conformant HID devices +which send and receive data in a way that is inconsistent with their report +descriptors. Because hiddev parses reports which are sent and received +through it, checking them against the device's report descriptor, such +communication with these non-conformant devices is impossible using hiddev. +Hidraw is the only alternative, short of writing a custom kernel driver, for +these non-conformant devices. + +A benefit of hidraw is that its use by userspace applications is independent +of the underlying hardware type. Currently, Hidraw is implemented for USB +and Bluetooth. In the future, as new hardware bus types are developed which +use the HID specification, hidraw will be expanded to add support for these +new bus types. + +Hidraw uses a dynamic major number, meaning that udev should be relied on to +create hidraw device nodes. Udev will typically create the device nodes +directly under /dev (eg: /dev/hidraw0). As this location is distribution- +and udev rule-dependent, applications should use libudev to locate hidraw +devices attached to the system. There is a tutorial on libudev with a +working example at: + http://www.signal11.us/oss/udev/ + +The HIDRAW API +--------------- + +read() +------- +read() will read a queued report received from the HID device. On USB +devices, the reports read using read() are the reports sent from the device +on the INTERRUPT IN endpoint. By default, read() will block until there is +a report available to be read. read() can be made non-blocking, by passing +the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using +fcntl(). + +On a device which uses numbered reports, the first byte of the returned data +will be the report number; the report data follows, beginning in the second +byte. For devices which do not use numbered reports, the report data +will begin at the first byte. + +write() +-------- +The write() function will write a report to the device. For USB devices, if +the device has an INTERRUPT OUT endpoint, the report will be sent on that +endpoint. If it does not, the report will be sent over the control endpoint, +using a SET_REPORT transfer. + +The first byte of the buffer passed to write() should be set to the report +number. If the device does not use numbered reports, the first byte should +be set to 0. The report data itself should begin at the second byte. + +ioctl() +-------- +Hidraw supports the following ioctls: + +HIDIOCGRDESCSIZE: Get Report Descriptor Size +This ioctl will get the size of the device's report descriptor. + +HIDIOCGRDESC: Get Report Descriptor +This ioctl returns the device's report descriptor using a +hidraw_report_descriptor struct. Make sure to set the size field of the +hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE. + +HIDIOCGRAWINFO: Get Raw Info +This ioctl will return a hidraw_devinfo struct containing the bus type, the +vendor ID (VID), and product ID (PID) of the device. The bus type can be one +of: + BUS_USB + BUS_HIL + BUS_BLUETOOTH + BUS_VIRTUAL +which are defined in linux/input.h. + +HIDIOCGRAWNAME(len): Get Raw Name +This ioctl returns a string containing the vendor and product strings of +the device. The returned string is Unicode, UTF-8 encoded. + +HIDIOCGRAWPHYS(len): Get Physical Address +This ioctl returns a string representing the physical address of the device. +For USB devices, the string contains the physical path to the device (the +USB controller, hubs, ports, etc). For Bluetooth devices, the string +contains the hardware (MAC) address of the device. + +HIDIOCSFEATURE(len): Send a Feature Report +This ioctl will send a feature report to the device. Per the HID +specification, feature reports are always sent using the control endpoint. +Set the first byte of the supplied buffer to the report number. For devices +which do not use numbered reports, set the first byte to 0. The report data +begins in the second byte. Make sure to set len accordingly, to one more +than the length of the report (to account for the report number). + +HIDIOCGFEATURE(len): Get a Feature Report +This ioctl will request a feature report from the device using the control +endpoint. The first byte of the supplied buffer should be set to the report +number of the requested report. For devices which do not use numbered +reports, set the first byte to 0. The report will be returned starting at +the first byte of the buffer (ie: the report number is not returned). + +Example +--------- +In samples/, find hid-example.c, which shows examples of read(), write(), +and all the ioctls for hidraw. The code may be used by anyone for any +purpose, and can serve as a starting point for developing applications using +hidraw. + +Document by: + Alan Ott , Signal 11 Software diff --git a/samples/Kconfig b/samples/Kconfig index e03cf0e..52f4264 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -61,4 +61,10 @@ config SAMPLE_KDB Build an example of how to dynamically add the hello command to the kdb shell. +config SAMPLE_HIDRAW + tristate "Build simple hidraw example" + depends on HIDRAW + help + Build an example of how to use hidraw from userspace. + endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index f26c095..6280817 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -1,4 +1,4 @@ # Makefile for Linux samples code obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ tracepoints/ trace_events/ \ - hw_breakpoint/ kfifo/ kdb/ + hw_breakpoint/ kfifo/ kdb/ hidraw/ diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile new file mode 100644 index 0000000..7811cb0 --- /dev/null +++ b/samples/hidraw/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := hid-example + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c new file mode 100644 index 0000000..40e3d62 --- /dev/null +++ b/samples/hidraw/hid-example.c @@ -0,0 +1,167 @@ +/* + * Hidraw Userspace Example + * + * Copyright (c) 2010 Alan Ott + * Copyright (c) 2010 Signal 11 Software + * + * The code may be used by anyone for any purpose, + * and can serve as a starting point for developing + * applications using hidraw. + */ + +/* Linux */ +#include +#include +#include + +/* Unix */ +#include +#include +#include +#include +#include + +/* C */ +#include +#include +#include +#include + +const char *bus_str(int bus); + +int main(int argc, char **argv) +{ + int fd; + int i, res, desc_size = 0; + char buf[256]; + struct hidraw_report_descriptor rpt_desc; + struct hidraw_devinfo info; + + /* Open the Device with non-blocking reads. In real life, + don't use a hard coded path; use libudev instead. */ + fd = open("/dev/hidraw0", O_RDWR|O_NONBLOCK); + + if (fd < 0) { + perror("Unable to open device"); + return 1; + } + + memset(&rpt_desc, 0x0, sizeof(rpt_desc)); + memset(&info, 0x0, sizeof(info)); + memset(buf, 0x0, sizeof(buf)); + + /* Get Report Descriptor Size */ + res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); + if (res < 0) + perror("HIDIOCGRDESCSIZE"); + else + printf("Report Descriptor Size: %d\n", desc_size); + + /* Get Report Descriptor */ + rpt_desc.size = desc_size; + res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); + if (res < 0) { + perror("HIDIOCGRDESC"); + } else { + printf("Report Descriptor:\n"); + for (i = 0; i < rpt_desc.size; i++) + printf("%hhx ", rpt_desc.value[i]); + puts("\n"); + } + + /* Get Raw Name */ + res = ioctl(fd, HIDIOCGRAWNAME(256), buf); + if (res < 0) + perror("HIDIOCGRAWNAME"); + else + printf("Raw Name: %s\n", buf); + + /* Get Physical Location */ + res = ioctl(fd, HIDIOCGRAWPHYS(256), buf); + if (res < 0) + perror("HIDIOCGRAWPHYS"); + else + printf("Raw Phys: %s\n", buf); + + /* Get Raw Info */ + res = ioctl(fd, HIDIOCGRAWINFO, &info); + if (res < 0) { + perror("HIDIOCGRAWINFO"); + } else { + printf("Raw Info:\n"); + printf("\tbustype: %d (%s)\n", + info.bustype, bus_str(info.bustype)); + printf("\tvendor: 0x%04hx\n", info.vendor); + printf("\tproduct: 0x%04hx\n", info.product); + } + + /* Set Feature */ + buf[0] = 0x9; /* Report Number */ + buf[1] = 0xff; + buf[2] = 0xff; + buf[3] = 0xff; + res = ioctl(fd, HIDIOCSFEATURE(4), buf); + if (res < 0) + perror("HIDIOCSFEATURE"); + else + printf("ioctl HIDIOCGFEATURE returned: %d\n", res); + + /* Get Feature */ + buf[0] = 0x9; /* Report Number */ + res = ioctl(fd, HIDIOCGFEATURE(256), buf); + if (res < 0) { + perror("HIDIOCGFEATURE"); + } else { + printf("ioctl HIDIOCGFEATURE returned: %d\n", res); + printf("Report data (not containing the report number):\n\t"); + for (i = 0; i < res; i++) + printf("%hhx ", buf[i]); + puts("\n"); + } + + /* Send a Report to the Device */ + buf[0] = 0x1; /* Report Number */ + buf[1] = 0x77; + res = write(fd, buf, 2); + if (res < 0) { + printf("Error: %d\n", errno); + perror("write"); + } else { + printf("write() wrote %d bytes\n", res); + } + + /* Get a report from the device */ + res = read(fd, buf, 16); + if (res < 0) { + perror("read"); + } else { + printf("read() read %d bytes:\n\t", res); + for (i = 0; i < res; i++) + printf("%hhx ", buf[i]); + puts("\n"); + } + close(fd); + return 0; +} + +const char * +bus_str(int bus) +{ + switch (bus) { + case BUS_USB: + return "USB"; + break; + case BUS_HIL: + return "HIL"; + break; + case BUS_BLUETOOTH: + return "Bluetooth"; + break; + case BUS_VIRTUAL: + return "Virtual"; + break; + default: + return "Other"; + break; + } +} -- cgit v0.10.2 From 1a978c50c6cff743c3516ffa6d2ce44382e7b70b Mon Sep 17 00:00:00 2001 From: Alan Ott Date: Sat, 19 Mar 2011 20:29:45 -0400 Subject: HID: Move hiddev.txt to the new Documentation/hid directory With the new Documentation/hid directory, it makes sense to have hiddev.txt here as well. Signed-off-by: Alan Ott Signed-off-by: Jiri Kosina diff --git a/Documentation/hid/hiddev.txt b/Documentation/hid/hiddev.txt new file mode 100644 index 0000000..6e8c9f1 --- /dev/null +++ b/Documentation/hid/hiddev.txt @@ -0,0 +1,205 @@ +Care and feeding of your Human Interface Devices + +INTRODUCTION + +In addition to the normal input type HID devices, USB also uses the +human interface device protocols for things that are not really human +interfaces, but have similar sorts of communication needs. The two big +examples for this are power devices (especially uninterruptable power +supplies) and monitor control on higher end monitors. + +To support these disparate requirements, the Linux USB system provides +HID events to two separate interfaces: +* the input subsystem, which converts HID events into normal input +device interfaces (such as keyboard, mouse and joystick) and a +normalised event interface - see Documentation/input/input.txt +* the hiddev interface, which provides fairly raw HID events + +The data flow for a HID event produced by a device is something like +the following : + + usb.c ---> hid-core.c ----> hid-input.c ----> [keyboard/mouse/joystick/event] + | + | + --> hiddev.c ----> POWER / MONITOR CONTROL + +In addition, other subsystems (apart from USB) can potentially feed +events into the input subsystem, but these have no effect on the hid +device interface. + +USING THE HID DEVICE INTERFACE + +The hiddev interface is a char interface using the normal USB major, +with the minor numbers starting at 96 and finishing at 111. Therefore, +you need the following commands: +mknod /dev/usb/hiddev0 c 180 96 +mknod /dev/usb/hiddev1 c 180 97 +mknod /dev/usb/hiddev2 c 180 98 +mknod /dev/usb/hiddev3 c 180 99 +mknod /dev/usb/hiddev4 c 180 100 +mknod /dev/usb/hiddev5 c 180 101 +mknod /dev/usb/hiddev6 c 180 102 +mknod /dev/usb/hiddev7 c 180 103 +mknod /dev/usb/hiddev8 c 180 104 +mknod /dev/usb/hiddev9 c 180 105 +mknod /dev/usb/hiddev10 c 180 106 +mknod /dev/usb/hiddev11 c 180 107 +mknod /dev/usb/hiddev12 c 180 108 +mknod /dev/usb/hiddev13 c 180 109 +mknod /dev/usb/hiddev14 c 180 110 +mknod /dev/usb/hiddev15 c 180 111 + +So you point your hiddev compliant user-space program at the correct +interface for your device, and it all just works. + +Assuming that you have a hiddev compliant user-space program, of +course. If you need to write one, read on. + + +THE HIDDEV API +This description should be read in conjunction with the HID +specification, freely available from http://www.usb.org, and +conveniently linked of http://www.linux-usb.org. + +The hiddev API uses a read() interface, and a set of ioctl() calls. + +HID devices exchange data with the host computer using data +bundles called "reports". Each report is divided into "fields", +each of which can have one or more "usages". In the hid-core, +each one of these usages has a single signed 32 bit value. + +read(): +This is the event interface. When the HID device's state changes, +it performs an interrupt transfer containing a report which contains +the changed value. The hid-core.c module parses the report, and +returns to hiddev.c the individual usages that have changed within +the report. In its basic mode, the hiddev will make these individual +usage changes available to the reader using a struct hiddev_event: + + struct hiddev_event { + unsigned hid; + signed int value; + }; + +containing the HID usage identifier for the status that changed, and +the value that it was changed to. Note that the structure is defined +within , along with some other useful #defines and +structures. The HID usage identifier is a composite of the HID usage +page shifted to the 16 high order bits ORed with the usage code. The +behavior of the read() function can be modified using the HIDIOCSFLAG +ioctl() described below. + + +ioctl(): +This is the control interface. There are a number of controls: + +HIDIOCGVERSION - int (read) +Gets the version code out of the hiddev driver. + +HIDIOCAPPLICATION - (none) +This ioctl call returns the HID application usage associated with the +hid device. The third argument to ioctl() specifies which application +index to get. This is useful when the device has more than one +application collection. If the index is invalid (greater or equal to +the number of application collections this device has) the ioctl +returns -1. You can find out beforehand how many application +collections the device has from the num_applications field from the +hiddev_devinfo structure. + +HIDIOCGCOLLECTIONINFO - struct hiddev_collection_info (read/write) +This returns a superset of the information above, providing not only +application collections, but all the collections the device has. It +also returns the level the collection lives in the hierarchy. +The user passes in a hiddev_collection_info struct with the index +field set to the index that should be returned. The ioctl fills in +the other fields. If the index is larger than the last collection +index, the ioctl returns -1 and sets errno to -EINVAL. + +HIDIOCGDEVINFO - struct hiddev_devinfo (read) +Gets a hiddev_devinfo structure which describes the device. + +HIDIOCGSTRING - struct hiddev_string_descriptor (read/write) +Gets a string descriptor from the device. The caller must fill in the +"index" field to indicate which descriptor should be returned. + +HIDIOCINITREPORT - (none) +Instructs the kernel to retrieve all input and feature report values +from the device. At this point, all the usage structures will contain +current values for the device, and will maintain it as the device +changes. Note that the use of this ioctl is unnecessary in general, +since later kernels automatically initialize the reports from the +device at attach time. + +HIDIOCGNAME - string (variable length) +Gets the device name + +HIDIOCGREPORT - struct hiddev_report_info (write) +Instructs the kernel to get a feature or input report from the device, +in order to selectively update the usage structures (in contrast to +INITREPORT). + +HIDIOCSREPORT - struct hiddev_report_info (write) +Instructs the kernel to send a report to the device. This report can +be filled in by the user through HIDIOCSUSAGE calls (below) to fill in +individual usage values in the report before sending the report in full +to the device. + +HIDIOCGREPORTINFO - struct hiddev_report_info (read/write) +Fills in a hiddev_report_info structure for the user. The report is +looked up by type (input, output or feature) and id, so these fields +must be filled in by the user. The ID can be absolute -- the actual +report id as reported by the device -- or relative -- +HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT | +report_id) for the next report after report_id. Without a-priori +information about report ids, the right way to use this ioctl is to +use the relative IDs above to enumerate the valid IDs. The ioctl +returns non-zero when there is no more next ID. The real report ID is +filled into the returned hiddev_report_info structure. + +HIDIOCGFIELDINFO - struct hiddev_field_info (read/write) +Returns the field information associated with a report in a +hiddev_field_info structure. The user must fill in report_id and +report_type in this structure, as above. The field_index should also +be filled in, which should be a number from 0 and maxfield-1, as +returned from a previous HIDIOCGREPORTINFO call. + +HIDIOCGUCODE - struct hiddev_usage_ref (read/write) +Returns the usage_code in a hiddev_usage_ref structure, given that +given its report type, report id, field index, and index within the +field have already been filled into the structure. + +HIDIOCGUSAGE - struct hiddev_usage_ref (read/write) +Returns the value of a usage in a hiddev_usage_ref structure. The +usage to be retrieved can be specified as above, or the user can +choose to fill in the report_type field and specify the report_id as +HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be +filled in with the report and field information associated with this +usage if it is found. + +HIDIOCSUSAGE - struct hiddev_usage_ref (write) +Sets the value of a usage in an output report. The user fills in +the hiddev_usage_ref structure as above, but additionally fills in +the value field. + +HIDIOGCOLLECTIONINDEX - struct hiddev_usage_ref (write) +Returns the collection index associated with this usage. This +indicates where in the collection hierarchy this usage sits. + +HIDIOCGFLAG - int (read) +HIDIOCSFLAG - int (write) +These operations respectively inspect and replace the mode flags +that influence the read() call above. The flags are as follows: + + HIDDEV_FLAG_UREF - read() calls will now return + struct hiddev_usage_ref instead of struct hiddev_event. + This is a larger structure, but in situations where the + device has more than one usage in its reports with the + same usage code, this mode serves to resolve such + ambiguity. + + HIDDEV_FLAG_REPORT - This flag can only be used in conjunction + with HIDDEV_FLAG_UREF. With this flag set, when the device + sends a report, a struct hiddev_usage_ref will be returned + to read() filled in with the report_type and report_id, but + with field_index set to FIELD_INDEX_NONE. This serves as + additional notification when the device has sent a report. diff --git a/Documentation/usb/hiddev.txt b/Documentation/usb/hiddev.txt deleted file mode 100644 index 6e8c9f1..0000000 --- a/Documentation/usb/hiddev.txt +++ /dev/null @@ -1,205 +0,0 @@ -Care and feeding of your Human Interface Devices - -INTRODUCTION - -In addition to the normal input type HID devices, USB also uses the -human interface device protocols for things that are not really human -interfaces, but have similar sorts of communication needs. The two big -examples for this are power devices (especially uninterruptable power -supplies) and monitor control on higher end monitors. - -To support these disparate requirements, the Linux USB system provides -HID events to two separate interfaces: -* the input subsystem, which converts HID events into normal input -device interfaces (such as keyboard, mouse and joystick) and a -normalised event interface - see Documentation/input/input.txt -* the hiddev interface, which provides fairly raw HID events - -The data flow for a HID event produced by a device is something like -the following : - - usb.c ---> hid-core.c ----> hid-input.c ----> [keyboard/mouse/joystick/event] - | - | - --> hiddev.c ----> POWER / MONITOR CONTROL - -In addition, other subsystems (apart from USB) can potentially feed -events into the input subsystem, but these have no effect on the hid -device interface. - -USING THE HID DEVICE INTERFACE - -The hiddev interface is a char interface using the normal USB major, -with the minor numbers starting at 96 and finishing at 111. Therefore, -you need the following commands: -mknod /dev/usb/hiddev0 c 180 96 -mknod /dev/usb/hiddev1 c 180 97 -mknod /dev/usb/hiddev2 c 180 98 -mknod /dev/usb/hiddev3 c 180 99 -mknod /dev/usb/hiddev4 c 180 100 -mknod /dev/usb/hiddev5 c 180 101 -mknod /dev/usb/hiddev6 c 180 102 -mknod /dev/usb/hiddev7 c 180 103 -mknod /dev/usb/hiddev8 c 180 104 -mknod /dev/usb/hiddev9 c 180 105 -mknod /dev/usb/hiddev10 c 180 106 -mknod /dev/usb/hiddev11 c 180 107 -mknod /dev/usb/hiddev12 c 180 108 -mknod /dev/usb/hiddev13 c 180 109 -mknod /dev/usb/hiddev14 c 180 110 -mknod /dev/usb/hiddev15 c 180 111 - -So you point your hiddev compliant user-space program at the correct -interface for your device, and it all just works. - -Assuming that you have a hiddev compliant user-space program, of -course. If you need to write one, read on. - - -THE HIDDEV API -This description should be read in conjunction with the HID -specification, freely available from http://www.usb.org, and -conveniently linked of http://www.linux-usb.org. - -The hiddev API uses a read() interface, and a set of ioctl() calls. - -HID devices exchange data with the host computer using data -bundles called "reports". Each report is divided into "fields", -each of which can have one or more "usages". In the hid-core, -each one of these usages has a single signed 32 bit value. - -read(): -This is the event interface. When the HID device's state changes, -it performs an interrupt transfer containing a report which contains -the changed value. The hid-core.c module parses the report, and -returns to hiddev.c the individual usages that have changed within -the report. In its basic mode, the hiddev will make these individual -usage changes available to the reader using a struct hiddev_event: - - struct hiddev_event { - unsigned hid; - signed int value; - }; - -containing the HID usage identifier for the status that changed, and -the value that it was changed to. Note that the structure is defined -within , along with some other useful #defines and -structures. The HID usage identifier is a composite of the HID usage -page shifted to the 16 high order bits ORed with the usage code. The -behavior of the read() function can be modified using the HIDIOCSFLAG -ioctl() described below. - - -ioctl(): -This is the control interface. There are a number of controls: - -HIDIOCGVERSION - int (read) -Gets the version code out of the hiddev driver. - -HIDIOCAPPLICATION - (none) -This ioctl call returns the HID application usage associated with the -hid device. The third argument to ioctl() specifies which application -index to get. This is useful when the device has more than one -application collection. If the index is invalid (greater or equal to -the number of application collections this device has) the ioctl -returns -1. You can find out beforehand how many application -collections the device has from the num_applications field from the -hiddev_devinfo structure. - -HIDIOCGCOLLECTIONINFO - struct hiddev_collection_info (read/write) -This returns a superset of the information above, providing not only -application collections, but all the collections the device has. It -also returns the level the collection lives in the hierarchy. -The user passes in a hiddev_collection_info struct with the index -field set to the index that should be returned. The ioctl fills in -the other fields. If the index is larger than the last collection -index, the ioctl returns -1 and sets errno to -EINVAL. - -HIDIOCGDEVINFO - struct hiddev_devinfo (read) -Gets a hiddev_devinfo structure which describes the device. - -HIDIOCGSTRING - struct hiddev_string_descriptor (read/write) -Gets a string descriptor from the device. The caller must fill in the -"index" field to indicate which descriptor should be returned. - -HIDIOCINITREPORT - (none) -Instructs the kernel to retrieve all input and feature report values -from the device. At this point, all the usage structures will contain -current values for the device, and will maintain it as the device -changes. Note that the use of this ioctl is unnecessary in general, -since later kernels automatically initialize the reports from the -device at attach time. - -HIDIOCGNAME - string (variable length) -Gets the device name - -HIDIOCGREPORT - struct hiddev_report_info (write) -Instructs the kernel to get a feature or input report from the device, -in order to selectively update the usage structures (in contrast to -INITREPORT). - -HIDIOCSREPORT - struct hiddev_report_info (write) -Instructs the kernel to send a report to the device. This report can -be filled in by the user through HIDIOCSUSAGE calls (below) to fill in -individual usage values in the report before sending the report in full -to the device. - -HIDIOCGREPORTINFO - struct hiddev_report_info (read/write) -Fills in a hiddev_report_info structure for the user. The report is -looked up by type (input, output or feature) and id, so these fields -must be filled in by the user. The ID can be absolute -- the actual -report id as reported by the device -- or relative -- -HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT | -report_id) for the next report after report_id. Without a-priori -information about report ids, the right way to use this ioctl is to -use the relative IDs above to enumerate the valid IDs. The ioctl -returns non-zero when there is no more next ID. The real report ID is -filled into the returned hiddev_report_info structure. - -HIDIOCGFIELDINFO - struct hiddev_field_info (read/write) -Returns the field information associated with a report in a -hiddev_field_info structure. The user must fill in report_id and -report_type in this structure, as above. The field_index should also -be filled in, which should be a number from 0 and maxfield-1, as -returned from a previous HIDIOCGREPORTINFO call. - -HIDIOCGUCODE - struct hiddev_usage_ref (read/write) -Returns the usage_code in a hiddev_usage_ref structure, given that -given its report type, report id, field index, and index within the -field have already been filled into the structure. - -HIDIOCGUSAGE - struct hiddev_usage_ref (read/write) -Returns the value of a usage in a hiddev_usage_ref structure. The -usage to be retrieved can be specified as above, or the user can -choose to fill in the report_type field and specify the report_id as -HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be -filled in with the report and field information associated with this -usage if it is found. - -HIDIOCSUSAGE - struct hiddev_usage_ref (write) -Sets the value of a usage in an output report. The user fills in -the hiddev_usage_ref structure as above, but additionally fills in -the value field. - -HIDIOGCOLLECTIONINDEX - struct hiddev_usage_ref (write) -Returns the collection index associated with this usage. This -indicates where in the collection hierarchy this usage sits. - -HIDIOCGFLAG - int (read) -HIDIOCSFLAG - int (write) -These operations respectively inspect and replace the mode flags -that influence the read() call above. The flags are as follows: - - HIDDEV_FLAG_UREF - read() calls will now return - struct hiddev_usage_ref instead of struct hiddev_event. - This is a larger structure, but in situations where the - device has more than one usage in its reports with the - same usage code, this mode serves to resolve such - ambiguity. - - HIDDEV_FLAG_REPORT - This flag can only be used in conjunction - with HIDDEV_FLAG_UREF. With this flag set, when the device - sends a report, a struct hiddev_usage_ref will be returned - to read() filled in with the report_type and report_id, but - with field_index set to FIELD_INDEX_NONE. This serves as - additional notification when the device has sent a report. -- cgit v0.10.2 From f786bba4499cf3de20da345ce090457ebcef03b0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 22 Mar 2011 17:34:01 +0100 Subject: HID: hid-multitouch: migrate 3M PCT touch screens to hid-multitouch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch merges the hid-3m-pct driver into hid-multitouch. To keep devices working the same way they used to with hid-3m-pct, we need to add two signal/noise ratios for width and height. We also need to work on width/height to send proper ABS_MT_ORIENTATION flag. Importing 3M into hid-multitouch also solved the bug in which devices handling width and height in their report descriptors did not show ABS_MT_TOUCH_MAJOR and ABS_MT_TOUCH_MINOR. Signed-off-by: Benjamin Tissoires Reviewed-by: Stéphane Chatty Reviewed-and-tested-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1edb0bd..996ae3a 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -55,12 +55,6 @@ source "drivers/hid/usbhid/Kconfig" menu "Special HID drivers" depends on HID -config HID_3M_PCT - tristate "3M PCT touchscreen" - depends on USB_HID - ---help--- - Support for 3M PCT touch screens. - config HID_A4TECH tristate "A4 tech mice" if EXPERT depends on USB_HID @@ -314,6 +308,7 @@ config HID_MULTITOUCH Generic support for HID multitouch panels. Say Y here if you have one of the following devices: + - 3M PCT touch screens - Cando dual touch panel - Cypress TrueTouch panels - Hanvon dual touch panels diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index f8b90e4..11c9f0b 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -25,7 +25,6 @@ ifdef CONFIG_LOGIWII_FF hid-logitech-y += hid-lg4ff.o endif -obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c deleted file mode 100644 index 5243ae2..0000000 --- a/drivers/hid/hid-3m-pct.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * HID driver for 3M PCT multitouch panels - * - * Copyright (c) 2009-2010 Stephane Chatty - * Copyright (c) 2010 Henrik Rydberg - * Copyright (c) 2010 Canonical, Ltd. - * - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("3M PCT multitouch panels"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -#define MAX_SLOTS 60 - -/* estimated signal-to-noise ratios */ -#define SN_MOVE 2048 -#define SN_WIDTH 128 - -struct mmm_finger { - __s32 x, y, w, h; - bool touch, valid; -}; - -struct mmm_data { - struct mmm_finger f[MAX_SLOTS]; - __u8 curid; - __u8 nexp, nreal; - bool touch, valid; -}; - -static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - int f1 = field->logical_minimum; - int f2 = field->logical_maximum; - int df = f2 - f1; - - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_BUTTON: - return -1; - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - input_set_abs_params(hi->input, ABS_MT_POSITION_X, - f1, f2, df / SN_MOVE, 0); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - f1, f2, df / SN_MOVE, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - input_set_abs_params(hi->input, ABS_MT_POSITION_Y, - f1, f2, df / SN_MOVE, 0); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - f1, f2, df / SN_MOVE, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - /* we do not want to map these: no input-oriented meaning */ - case 0x14: - case 0x23: - case HID_DG_INPUTMODE: - case HID_DG_DEVICEINDEX: - case HID_DG_CONTACTCOUNT: - case HID_DG_CONTACTMAX: - case HID_DG_INRANGE: - case HID_DG_CONFIDENCE: - return -1; - case HID_DG_TIPSWITCH: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - input_set_capability(hi->input, EV_KEY, BTN_TOUCH); - return 1; - case HID_DG_WIDTH: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MAJOR); - input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, - f1, f2, df / SN_WIDTH, 0); - return 1; - case HID_DG_HEIGHT: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TOUCH_MINOR); - input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, - f1, f2, df / SN_WIDTH, 0); - input_set_abs_params(hi->input, ABS_MT_ORIENTATION, - 0, 1, 0, 0); - return 1; - case HID_DG_CONTACTID: - input_mt_init_slots(hi->input, MAX_SLOTS); - return 1; - } - /* let hid-input decide for the others */ - return 0; - - case 0xff000000: - /* we do not want to map these: no input-oriented meaning */ - return -1; - } - - return 0; -} - -static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - /* tell hid-input to skip setup of these event types */ - if (usage->type == EV_KEY || usage->type == EV_ABS) - set_bit(usage->type, hi->input->evbit); - return -1; -} - -/* - * this function is called when a whole packet has been received and processed, - * so that it can decide what to send to the input layer. - */ -static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) -{ - int i; - for (i = 0; i < MAX_SLOTS; ++i) { - struct mmm_finger *f = &md->f[i]; - if (!f->valid) { - /* this finger is just placeholder data, ignore */ - continue; - } - input_mt_slot(input, i); - input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch); - if (f->touch) { - /* this finger is on the screen */ - int wide = (f->w > f->h); - /* divided by two to match visual scale of touch */ - int major = max(f->w, f->h) >> 1; - int minor = min(f->w, f->h) >> 1; - - input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); - input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); - } - f->valid = 0; - } - - input_mt_report_pointer_emulation(input, true); - input_sync(input); -} - -/* - * this function is called upon all reports - * so that we can accumulate contact point information, - * and call input_mt_sync after each point. - */ -static int mmm_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct mmm_data *md = hid_get_drvdata(hid); - /* - * strangely, this function can be called before - * field->hidinput is initialized! - */ - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - switch (usage->hid) { - case HID_DG_TIPSWITCH: - md->touch = value; - break; - case HID_DG_CONFIDENCE: - md->valid = value; - break; - case HID_DG_WIDTH: - if (md->valid) - md->f[md->curid].w = value; - break; - case HID_DG_HEIGHT: - if (md->valid) - md->f[md->curid].h = value; - break; - case HID_DG_CONTACTID: - value = clamp_val(value, 0, MAX_SLOTS - 1); - if (md->valid) { - md->curid = value; - md->f[value].touch = md->touch; - md->f[value].valid = 1; - md->nreal++; - } - break; - case HID_GD_X: - if (md->valid) - md->f[md->curid].x = value; - break; - case HID_GD_Y: - if (md->valid) - md->f[md->curid].y = value; - break; - case HID_DG_CONTACTCOUNT: - if (value) - md->nexp = value; - if (md->nreal >= md->nexp) { - mmm_filter_event(md, input); - md->nreal = 0; - } - break; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - struct mmm_data *md; - - hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; - - md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); - if (!md) { - hid_err(hdev, "cannot allocate 3M data\n"); - return -ENOMEM; - } - hid_set_drvdata(hdev, md); - - ret = hid_parse(hdev); - if (!ret) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret) - kfree(md); - return ret; -} - -static void mmm_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id mmm_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, - { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, - { } -}; -MODULE_DEVICE_TABLE(hid, mmm_devices); - -static const struct hid_usage_id mmm_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver mmm_driver = { - .name = "3m-pct", - .id_table = mmm_devices, - .probe = mmm_probe, - .remove = mmm_remove, - .input_mapping = mmm_input_mapping, - .input_mapped = mmm_input_mapped, - .usage_table = mmm_grabbed_usages, - .event = mmm_event, -}; - -static int __init mmm_init(void) -{ - return hid_register_driver(&mmm_driver); -} - -static void __exit mmm_exit(void) -{ - hid_unregister_driver(&mmm_driver); -} - -module_init(mmm_init); -module_exit(mmm_exit); - diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index d31301e..0175f85 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -11,6 +11,12 @@ * Copyright (c) 2010 Henrik Rydberg * Copyright (c) 2010 Canonical, Ltd. * + * This code is partly based on hid-3m-pct.c: + * + * Copyright (c) 2009-2010 Stephane Chatty + * Copyright (c) 2010 Henrik Rydberg + * Copyright (c) 2010 Canonical, Ltd. + * */ /* @@ -69,6 +75,8 @@ struct mt_class { __s32 name; /* MT_CLS */ __s32 quirks; __s32 sn_move; /* Signal/noise ratio for move events */ + __s32 sn_width; /* Signal/noise ratio for width events */ + __s32 sn_height; /* Signal/noise ratio for height events */ __s32 sn_pressure; /* Signal/noise ratio for pressure events */ __u8 maxcontacts; }; @@ -80,6 +88,7 @@ struct mt_class { #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 #define MT_CLS_STANTUM 6 +#define MT_CLS_3M 7 #define MT_DEFAULT_MAXCONTACT 10 @@ -141,6 +150,12 @@ struct mt_class mt_classes[] = { }, { .name = MT_CLS_STANTUM, .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { .name = MT_CLS_3M, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | + MT_QUIRK_SLOT_IS_CONTACTID, + .sn_move = 2048, + .sn_width = 128, + .sn_height = 128 }, { } }; @@ -230,11 +245,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 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); td->last_slot_field = usage->hid; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, EV_ABS, ABS_MT_TOUCH_MINOR); + set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, + cls->sn_height); input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 0, 1, 0, 0); td->last_slot_field = usage->hid; @@ -332,11 +351,18 @@ static void mt_emit_event(struct mt_device *td, struct input_dev *input) input_mt_report_slot_state(input, MT_TOOL_FINGER, s->touch_state); if (s->touch_state) { + /* this finger is on the screen */ + int wide = (s->w > s->h); + /* divided by two to match visual scale of touch */ + int major = max(s->w, s->h) >> 1; + int minor = min(s->w, s->h) >> 1; + input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); + input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); - input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w); - input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h); + input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); + input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); } s->seen_in_this_frame = false; @@ -398,6 +424,15 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, break; default: + if (td->last_field_index + && field->index == td->last_field_index) + /* we reach here when the last field in the + * report is not related to multitouch. + * This is not good. As a temporary solution, + * we trigger our mt event completion and + * ignore the field. + */ + break; /* fallback to the generic hidinput handling */ return 0; } @@ -513,6 +548,14 @@ static void mt_remove(struct hid_device *hdev) static const struct hid_device_id mt_devices[] = { + /* 3M panels */ + { .driver_data = MT_CLS_3M, + HID_USB_DEVICE(USB_VENDOR_ID_3M, + USB_DEVICE_ID_3M1968) }, + { .driver_data = MT_CLS_3M, + HID_USB_DEVICE(USB_VENDOR_ID_3M, + USB_DEVICE_ID_3M2256) }, + /* Cando panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, HID_USB_DEVICE(USB_VENDOR_ID_CANDO, -- cgit v0.10.2 From ac065bf214bb6a7fb7536f2dde686d4694342801 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 26 Mar 2011 04:47:35 +0300 Subject: HID: hiddev: fix brace indent There was an extra tab so the close curly brace didn't match up with the right if statement. Signed-off-by: Dan Carpenter Signed-off-by: Jiri Kosina diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index af0a7c1..5270031 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -509,7 +509,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, (uref_multi->num_values > HID_MAX_MULTI_USAGES || uref->usage_index + uref_multi->num_values > field->report_count)) goto inval; - } + } switch (cmd) { case HIDIOCGUSAGE: -- cgit v0.10.2 From d2a1cfebe38edc0bbac8f5cfbce062fe3d146d7a Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Sun, 27 Mar 2011 20:29:02 +0200 Subject: HID: hidraw: fix comments Adjust the comments a little bit. Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 54409cb..93c72e5 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -101,8 +101,8 @@ out: return ret; } -/* the first byte is expected to be a report number */ -/* This function is to be called with the minors_lock mutex held */ +/* The first byte is expected to be a report number. + * This function is to be called with the minors_lock mutex held */ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type) { unsigned int minor = iminor(file->f_path.dentry->d_inode); @@ -166,11 +166,11 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t /* This function performs a Get_Report transfer over the control endpoint - per section 7.2.1 of the HID specification, version 1.1. The first byte - of buffer is the report number to request, or 0x0 if the defice does not - use numbered reports. The report_type parameter can be HID_FEATURE_REPORT - or HID_INPUT_REPORT. This function is to be called with the minors_lock - mutex held. */ + * per section 7.2.1 of the HID specification, version 1.1. The first byte + * of buffer is the report number to request, or 0x0 if the defice does not + * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT + * or HID_INPUT_REPORT. This function is to be called with the minors_lock + * mutex held. */ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type) { unsigned int minor = iminor(file->f_path.dentry->d_inode); @@ -207,7 +207,7 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t } /* Read the first byte from the user. This is the report number, - which is passed to dev->hid_get_raw_report(). */ + * which is passed to dev->hid_get_raw_report(). */ if (copy_from_user(&report_number, buffer, 1)) { ret = -EFAULT; goto out_free; -- cgit v0.10.2 From cb3e85fe19575cce8af82bc62a070c72e8f781b8 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Sat, 9 Apr 2011 01:43:18 +0200 Subject: HID: hidraw: fix samples miscompilation On systems where userspace doesn't have new hidraw.h populated to /usr/include, the hidraw sample won't compile as it's missing the new ioctl defitions. Introduce temporary ugly workaround to define the ioctls "manually" in such cases, just to avoid miscompilation in allmodconfig cases. Reported-by: Stephen Rothwell Signed-off-by: Jiri Kosina diff --git a/samples/hidraw/hid-example.c b/samples/hidraw/hid-example.c index 40e3d62..816e2dc 100644 --- a/samples/hidraw/hid-example.c +++ b/samples/hidraw/hid-example.c @@ -14,6 +14,17 @@ #include #include +/* + * Ugly hack to work around failing compilation on systems that don't + * yet populate new version of hidraw.h to userspace. + * + * If you need this, please have your distro update the kernel headers. + */ +#ifndef HIDIOCSFEATURE +#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) +#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) +#endif + /* Unix */ #include #include -- cgit v0.10.2 From d431b2e33cd54e4334019a95979ae93aea4735e8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 21 Apr 2011 11:10:42 +0200 Subject: HID: hid-example: fix some build issues samples/hid-example.o needs some Kconfig and Makefile additions in order to build. It should use headers from the build tree, so use HEADERS_CHECK to require that those header files be present. Change the kconfig symbol from tristate to bool since userspace cannot be built as loadable modules. However, I don't understand why the userspace header files are not present as reported in Andrew's build log, since it builds OK on x86_64 without any of these changes. Signed-off-by: Randy Dunlap Cc: Alan Ott Cc: Jiri Kosina Signed-off-by: Andrew Morton Signed-off-by: Jiri Kosina diff --git a/samples/Kconfig b/samples/Kconfig index 52f4264..9779803 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -62,8 +62,8 @@ config SAMPLE_KDB command to the kdb shell. config SAMPLE_HIDRAW - tristate "Build simple hidraw example" - depends on HIDRAW + bool "Build simple hidraw example" + depends on HIDRAW && HEADERS_CHECK help Build an example of how to use hidraw from userspace. diff --git a/samples/hidraw/Makefile b/samples/hidraw/Makefile index 7811cb0..382eeae 100644 --- a/samples/hidraw/Makefile +++ b/samples/hidraw/Makefile @@ -6,3 +6,5 @@ hostprogs-y := hid-example # Tell kbuild to always build the programs always := $(hostprogs-y) + +HOSTCFLAGS_hid-example.o += -I$(objtree)/usr/include -- cgit v0.10.2 From 6d67c110ab204bc4c2f4f3e368b8d7cf1f38a4f8 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 6 Apr 2011 10:43:23 +0200 Subject: HID: bt: hidp.h: do not use a tab after a #define Signed-off-by: Antonio Ospite Signed-off-by: Jiri Kosina diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index 13de5fa..c9be803 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h @@ -80,7 +80,7 @@ #define HIDP_VIRTUAL_CABLE_UNPLUG 0 #define HIDP_BOOT_PROTOCOL_MODE 1 #define HIDP_BLUETOOTH_VENDOR_ID 9 -#define HIDP_WAITING_FOR_RETURN 10 +#define HIDP_WAITING_FOR_RETURN 10 #define HIDP_WAITING_FOR_SEND_ACK 11 struct hidp_connadd_req { -- cgit v0.10.2 From 2955caed8b9865c1f04fcde6bd7103d5d5ec9415 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 21 Apr 2011 14:15:59 +0200 Subject: HID: hid-multitouch: refactor last_field_index the current implementation requires the devices to report HID_DG_CONTACTCOUNT to set the last_field_index value. However, devices reporting in serial mode (DWAV and PenMount) do not send this field. Other devices (3M) add other fields in the reports descriptor that are not multitouch related at the end, thus the need to add a special case in the default case when handling events. A first work around has been set up but with PenMount devices, we have reached the limit. The idea is to calculate the last_field_index by relying only on multitouch fields the device send. This allows us to remove the handling of non-multitouch events in hid-multitouch, and guarantee that the function mt_emit_event is always called. Signed-off-by: Benjamin Tissoires Reviewed-and-tested-by: Henrik Rydberg Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 0175f85..6005e78 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -210,6 +210,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, /* touchscreen emulation */ set_abs(hi->input, ABS_X, field, cls->sn_move); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_GD_Y: if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) @@ -221,6 +222,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, /* touchscreen emulation */ set_abs(hi->input, ABS_Y, field, cls->sn_move); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; } return 0; @@ -229,18 +231,22 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, switch (usage->hid) { case HID_DG_INRANGE: td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_DG_CONFIDENCE: td->last_slot_field = usage->hid; + 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); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_DG_CONTACTID: input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_DG_WIDTH: hid_map_usage(hi, usage, bit, max, @@ -248,6 +254,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, cls->sn_width); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_DG_HEIGHT: hid_map_usage(hi, usage, bit, max, @@ -257,6 +264,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, input_set_abs_params(hi->input, ABS_MT_ORIENTATION, 0, 1, 0, 0); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_DG_TIPPRESSURE: if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) @@ -269,13 +277,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, set_abs(hi->input, ABS_PRESSURE, field, cls->sn_pressure); td->last_slot_field = usage->hid; + td->last_field_index = field->index; return 1; case HID_DG_CONTACTCOUNT: - td->last_field_index = field->report->maxfield - 1; + 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 */ + td->last_field_index = field->index; return -1; } /* let hid-input decide for the others */ @@ -424,23 +434,12 @@ static int mt_event(struct hid_device *hid, struct hid_field *field, break; default: - if (td->last_field_index - && field->index == td->last_field_index) - /* we reach here when the last field in the - * report is not related to multitouch. - * This is not good. As a temporary solution, - * we trigger our mt event completion and - * ignore the field. - */ - break; /* fallback to the generic hidinput handling */ return 0; } if (usage->hid == td->last_slot_field) { mt_complete_slot(td); - if (!td->last_field_index) - mt_emit_event(td, field->hidinput->input); } if (field->index == td->last_field_index -- cgit v0.10.2 From 6ab3a9a63fc16b04f7de48eb0190d516dd7574df Mon Sep 17 00:00:00 2001 From: John Sung Date: Thu, 21 Apr 2011 16:21:52 +0200 Subject: HID: hid-multitouch: add support for PenMount dual-touch panel This patch adds PenMount support to hid-multitouch. A new class MT_CLS_CONFIDENCE is defined for PenMount, since it uses HID_DG_CONFIDENCE as the valid flag. Signed-off-by: John Sung [benjamin.tissoires@enac.fr: rebased on top of last_index_field changes] 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 996ae3a..8058cf1 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -313,6 +313,7 @@ config HID_MULTITOUCH - Cypress TrueTouch panels - Hanvon dual touch panels - IrTouch Infrared USB panels + - PenMount dual touch panels - Pixcir dual touch panels - 'Sensing Win7-TwoFinger' panel by GeneralTouch - eGalax dual-touch panels, including the diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c3d6626..6e31b9f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1438,6 +1438,7 @@ 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_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_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index d485894..252aeba 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -484,6 +484,9 @@ #define USB_VENDOR_ID_PANTHERLORD 0x0810 #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 +#define USB_VENDOR_ID_PENMOUNT 0x14e1 +#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 + #define USB_VENDOR_ID_PETALYNX 0x18b1 #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 6005e78..51b5d27 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -89,6 +89,7 @@ struct mt_class { #define MT_CLS_EGALAX 5 #define MT_CLS_STANTUM 6 #define MT_CLS_3M 7 +#define MT_CLS_CONFIDENCE 8 #define MT_DEFAULT_MAXCONTACT 10 @@ -156,6 +157,8 @@ struct mt_class mt_classes[] = { .sn_move = 2048, .sn_width = 128, .sn_height = 128 }, + { .name = MT_CLS_CONFIDENCE, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, { } }; @@ -584,6 +587,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + /* PenMount panels */ + { .driver_data = MT_CLS_CONFIDENCE, + HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, + USB_DEVICE_ID_PENMOUNT_PCI) }, + /* PixCir-based panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, HID_USB_DEVICE(USB_VENDOR_ID_HANVON, -- cgit v0.10.2 From 4a6ee685fbcba4a440cf86f41557752ba81e2ccf Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 22 Apr 2011 11:51:48 +0200 Subject: HID: hid-multitouch: merge hid-mosart into hid-multitouch This patch include MosArt devices into hid-multitouch. MosArt devices now support mt-protocol B. We also need to introduce a new quirk for mosart devices to support their contactID. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8058cf1..d2d4e5f 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -288,12 +288,6 @@ config HID_MICROSOFT ---help--- Support for Microsoft devices that are not fully compliant with HID standard. -config HID_MOSART - tristate "MosArt dual-touch panels" - depends on USB_HID - ---help--- - Support for MosArt dual-touch panels. - config HID_MONTEREY tristate "Monterey Genius KB29E keyboard" if EXPERT depends on USB_HID @@ -313,6 +307,7 @@ config HID_MULTITOUCH - Cypress TrueTouch panels - Hanvon dual touch panels - IrTouch Infrared USB panels + - MosArt dual-touch panels - PenMount dual touch panels - Pixcir dual touch panels - 'Sensing Win7-TwoFinger' panel by GeneralTouch diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 11c9f0b..f8cc4ea 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o -obj-$(CONFIG_HID_MOSART) += hid-mosart.o obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o obj-$(CONFIG_HID_ORTEK) += hid-ortek.o diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c deleted file mode 100644 index aed7ffe..0000000 --- a/drivers/hid/hid-mosart.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * HID driver for the multitouch panel on the ASUS EeePC T91MT - * - * Copyright (c) 2009-2010 Stephane Chatty - * Copyright (c) 2010 Teemu Tuominen - * - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - */ - -#include -#include -#include -#include -#include -#include "usbhid/usbhid.h" - -MODULE_AUTHOR("Stephane Chatty "); -MODULE_DESCRIPTION("MosArt dual-touch panel"); -MODULE_LICENSE("GPL"); - -#include "hid-ids.h" - -struct mosart_data { - __u16 x, y; - __u8 id; - bool valid; /* valid finger data, or just placeholder? */ - bool first; /* is this the first finger in this frame? */ - bool activity_now; /* at least one active finger in this frame? */ - bool activity; /* at least one active finger previously? */ -}; - -static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - switch (usage->hid & HID_USAGE_PAGE) { - - case HID_UP_GENDESK: - switch (usage->hid) { - case HID_GD_X: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_X); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_X, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - case HID_GD_Y: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_POSITION_Y); - /* touchscreen emulation */ - input_set_abs_params(hi->input, ABS_Y, - field->logical_minimum, - field->logical_maximum, 0, 0); - return 1; - } - return 0; - - case HID_UP_DIGITIZER: - switch (usage->hid) { - case HID_DG_CONFIDENCE: - case HID_DG_TIPSWITCH: - case HID_DG_INPUTMODE: - case HID_DG_DEVICEINDEX: - case HID_DG_CONTACTCOUNT: - case HID_DG_CONTACTMAX: - case HID_DG_TIPPRESSURE: - case HID_DG_WIDTH: - case HID_DG_HEIGHT: - return -1; - case HID_DG_INRANGE: - /* touchscreen emulation */ - hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); - return 1; - - case HID_DG_CONTACTID: - hid_map_usage(hi, usage, bit, max, - EV_ABS, ABS_MT_TRACKING_ID); - return 1; - - } - return 0; - - case 0xff000000: - /* ignore HID features */ - return -1; - - case HID_UP_BUTTON: - /* ignore buttons */ - return -1; - } - - return 0; -} - -static int mosart_input_mapped(struct hid_device *hdev, struct hid_input *hi, - struct hid_field *field, struct hid_usage *usage, - unsigned long **bit, int *max) -{ - if (usage->type == EV_KEY || usage->type == EV_ABS) - clear_bit(usage->code, *bit); - - return 0; -} - -/* - * this function is called when a whole finger has been parsed, - * so that it can decide what to send to the input layer. - */ -static void mosart_filter_event(struct mosart_data *td, struct input_dev *input) -{ - td->first = !td->first; /* touchscreen emulation */ - - if (!td->valid) { - /* - * touchscreen emulation: if no finger in this frame is valid - * and there previously was finger activity, this is a release - */ - if (!td->first && !td->activity_now && td->activity) { - input_event(input, EV_KEY, BTN_TOUCH, 0); - td->activity = false; - } - return; - } - - input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); - input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); - input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); - - input_mt_sync(input); - td->valid = false; - - /* touchscreen emulation: if first active finger in this frame... */ - if (!td->activity_now) { - /* if there was no previous activity, emit touch event */ - if (!td->activity) { - input_event(input, EV_KEY, BTN_TOUCH, 1); - td->activity = true; - } - td->activity_now = true; - /* and in any case this is our preferred finger */ - input_event(input, EV_ABS, ABS_X, td->x); - input_event(input, EV_ABS, ABS_Y, td->y); - } -} - - -static int mosart_event(struct hid_device *hid, struct hid_field *field, - struct hid_usage *usage, __s32 value) -{ - struct mosart_data *td = hid_get_drvdata(hid); - - if (hid->claimed & HID_CLAIMED_INPUT) { - struct input_dev *input = field->hidinput->input; - switch (usage->hid) { - case HID_DG_INRANGE: - td->valid = !!value; - break; - case HID_GD_X: - td->x = value; - break; - case HID_GD_Y: - td->y = value; - mosart_filter_event(td, input); - break; - case HID_DG_CONTACTID: - td->id = value; - break; - case HID_DG_CONTACTCOUNT: - /* touch emulation: this is the last field in a frame */ - td->first = false; - td->activity_now = false; - break; - case HID_DG_CONFIDENCE: - case HID_DG_TIPSWITCH: - /* avoid interference from generic hidinput handling */ - break; - - default: - /* fallback to the generic hidinput handling */ - return 0; - } - } - - /* we have handled the hidinput part, now remains hiddev */ - if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) - hid->hiddev_hid_event(hid, field, usage, value); - - return 1; -} - -static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - struct mosart_data *td; - - - td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL); - if (!td) { - hid_err(hdev, "cannot allocate MosArt data\n"); - return -ENOMEM; - } - td->valid = false; - td->activity = false; - td->activity_now = false; - td->first = false; - hid_set_drvdata(hdev, td); - - /* currently, it's better to have one evdev device only */ -#if 0 - hdev->quirks |= HID_QUIRK_MULTI_INPUT; -#endif - - ret = hid_parse(hdev); - if (ret == 0) - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - - if (ret == 0) { - struct hid_report_enum *re = hdev->report_enum - + HID_FEATURE_REPORT; - struct hid_report *r = re->report_id_hash[7]; - - r->field[0]->value[0] = 0x02; - usbhid_submit_report(hdev, r, USB_DIR_OUT); - } else - kfree(td); - - return ret; -} - -#ifdef CONFIG_PM -static int mosart_reset_resume(struct hid_device *hdev) -{ - struct hid_report_enum *re = hdev->report_enum - + HID_FEATURE_REPORT; - struct hid_report *r = re->report_id_hash[7]; - - r->field[0]->value[0] = 0x02; - usbhid_submit_report(hdev, r, USB_DIR_OUT); - return 0; -} -#endif - -static void mosart_remove(struct hid_device *hdev) -{ - hid_hw_stop(hdev); - kfree(hid_get_drvdata(hdev)); - hid_set_drvdata(hdev, NULL); -} - -static const struct hid_device_id mosart_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, - { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, - { } -}; -MODULE_DEVICE_TABLE(hid, mosart_devices); - -static const struct hid_usage_id mosart_grabbed_usages[] = { - { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, - { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} -}; - -static struct hid_driver mosart_driver = { - .name = "mosart", - .id_table = mosart_devices, - .probe = mosart_probe, - .remove = mosart_remove, - .input_mapping = mosart_input_mapping, - .input_mapped = mosart_input_mapped, - .usage_table = mosart_grabbed_usages, - .event = mosart_event, -#ifdef CONFIG_PM - .reset_resume = mosart_reset_resume, -#endif -}; - -static int __init mosart_init(void) -{ - return hid_register_driver(&mosart_driver); -} - -static void __exit mosart_exit(void) -{ - hid_unregister_driver(&mosart_driver); -} - -module_init(mosart_init); -module_exit(mosart_exit); - diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 51b5d27..bf46804 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -50,6 +50,7 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_VALID_IS_INRANGE (1 << 4) #define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) #define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6) +#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 7) struct mt_slot { __s32 x, y, p, w, h; @@ -90,6 +91,7 @@ struct mt_class { #define MT_CLS_STANTUM 6 #define MT_CLS_3M 7 #define MT_CLS_CONFIDENCE 8 +#define MT_CLS_CONFIDENCE_MINUS_ONE 9 #define MT_DEFAULT_MAXCONTACT 10 @@ -140,7 +142,9 @@ struct mt_class mt_classes[] = { .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | MT_QUIRK_CYPRESS, .maxcontacts = 10 }, - + { .name = MT_CLS_CONFIDENCE_MINUS_ONE, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | + MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, { .name = MT_CLS_EGALAX, .quirks = MT_QUIRK_SLOT_IS_CONTACTID | MT_QUIRK_VALID_IS_INRANGE | @@ -325,6 +329,9 @@ static int mt_compute_slot(struct mt_device *td) if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) return td->num_received; + if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) + return td->curdata.contactid - 1; + return find_slot_from_contactid(td); } @@ -587,6 +594,17 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + /* MosArt panels */ + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + HID_USB_DEVICE(USB_VENDOR_ID_ASUS, + USB_DEVICE_ID_ASUS_T91MT)}, + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + HID_USB_DEVICE(USB_VENDOR_ID_ASUS, + USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, + USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, + /* PenMount panels */ { .driver_data = MT_CLS_CONFIDENCE, HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, -- cgit v0.10.2 From 4b5730fafb6287bdeed6af914fe90ed9e114d9a6 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 26 Apr 2011 10:51:28 +0200 Subject: HID: add support for barcode scanners from Symbol Technologies Barcode handheld scanners produced by Symbol Technologies (0x05e0/0x0800 and 0x05e0/0x1300) need HID_QUIRK_NOGET, otherwise their firmware exposes trouble during enumeration/initialization. Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index d485894..be5cf24 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -544,6 +544,10 @@ #define USB_VENDOR_ID_SUNPLUS 0x04fc #define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 +#define USB_VENDOR_ID_SYMBOL 0x05e0 +#define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 +#define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 + #define USB_VENDOR_ID_THRUSTMASTER 0x044f #define USB_VENDOR_ID_TOPSEED 0x0766 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 9a94b64..c09fa0c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -67,6 +67,8 @@ static const struct hid_blacklist { { 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_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 }, { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, -- cgit v0.10.2 From 35dca5b4a67a93bbb75c2753d6dc432dc8f82e5d Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 28 Apr 2011 15:43:13 +0200 Subject: HID: add support for Sony Navigation Controller Sony Navigation Controller needs a special report to be sent to it before it is able to operate, the same way as other Sony controllers do. Tested-by: Jacek Lukas Wotka Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c3d6626..b1986b95 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1449,6 +1449,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index be5cf24..087a5a4 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -524,6 +524,7 @@ #define USB_VENDOR_ID_SONY 0x054c #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 +#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f #define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 93819a0..936c911 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -178,6 +178,8 @@ static void sony_remove(struct hid_device *hdev) static const struct hid_device_id sony_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_USB }, + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), + .driver_data = SIXAXIS_CONTROLLER_USB }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_BT }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), -- cgit v0.10.2 From 06268b2a384ece73618c1ad7649d19905ab79806 Mon Sep 17 00:00:00 2001 From: Peter Waechtler Date: Thu, 28 Apr 2011 20:53:58 +0200 Subject: HID: hiddev: fix error path in hiddev_read when interrupted hiddev_read: in case mutex_lock_interruptible will be interrupted remove the task from the wait queue. Signed-off-by: Peter Waechtler Signed-off-by: Jiri Kosina diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index af0a7c1..891ff53 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -367,8 +367,10 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun /* let O_NONBLOCK tasks run */ mutex_unlock(&list->thread_lock); schedule(); - if (mutex_lock_interruptible(&list->thread_lock)) + if (mutex_lock_interruptible(&list->thread_lock)) { + finish_wait(&list->hiddev->wait, &wait); return -EINTR; + } set_current_state(TASK_INTERRUPTIBLE); } finish_wait(&list->hiddev->wait, &wait); -- cgit v0.10.2 From fdc6807fcd09416c5537f479e1dcd624118e234c Mon Sep 17 00:00:00 2001 From: Peter Gundermann Date: Tue, 3 May 2011 10:15:03 +0200 Subject: HID: add support for Logitech G27 wheel Gere's a small patch to add support for the Logitech G27 wheel, since the prior patch only added FF support for the Driving Force Pro and G25. The patch contains the changes from the G25 and DFP, too. I tested the changes with wine/LFS and got full support for all axes and buttons. Signed-off: Peter Gundermann Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b1986b95..852989f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1405,6 +1405,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 087a5a4..e41d32a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -394,6 +394,7 @@ #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 +#define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a #define USB_DEVICE_ID_S510_RECEIVER 0xc50c diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 3da9040..21f205f 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -377,6 +377,8 @@ static const struct hid_device_id lg_devices[] = { .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), .driver_data = LG_FF }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), + .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c index 90d0ef2..f901349 100644 --- a/drivers/hid/hid-lgff.c +++ b/drivers/hid/hid-lgff.c @@ -72,6 +72,9 @@ static const struct dev_type devices[] = { { 0x046d, 0xc287, ff_joystick_ac }, { 0x046d, 0xc293, ff_joystick }, { 0x046d, 0xc294, ff_wheel }, + { 0x046d, 0xc298, ff_wheel }, + { 0x046d, 0xc299, ff_wheel }, + { 0x046d, 0xc29b, ff_wheel }, { 0x046d, 0xc295, ff_joystick }, { 0x046d, 0xca03, ff_wheel }, }; -- cgit v0.10.2 From 8c4e708d01424f88afde64a96ffd05146c9978b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= Date: Wed, 4 May 2011 21:08:42 +0200 Subject: HID: picolcd: Avoid compile warning/error triggered by copy_from_user() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y compilation of PicoLCD driver fails on copy_from_user(), without it a warning is generated: CC [M] drivers/hid/hid-picolcd.o In file included from /usr/src/linux-2.6/arch/x86/include/asm/uaccess.h:571, from /usr/src/linux-2.6/arch/x86/include/asm/sections.h:5, from /usr/src/linux-2.6/arch/x86/include/asm/hw_irq.h:26, from /usr/src/linux-2.6/include/linux/irq.h:359, from /usr/src/linux-2.6/arch/x86/include/asm/hardirq.h:5, from /usr/src/linux-2.6/include/linux/hardirq.h:7, from /usr/src/linux-2.6/include/linux/interrupt.h:12, from /usr/src/linux-2.6/include/linux/usb.h:15, from /usr/src/linux-2.6/drivers/hid/hid-picolcd.c:25: In function 'copy_from_user', inlined from 'picolcd_debug_eeprom_write' at drivers/hid/hid-picolcd.c:1592: arch/x86/include/asm/uaccess_32.h:212: error: call to 'copy_from_user_overflow' declared with attribute error: copy_from_user() buffer size is not provably correct gcc-4.4.5 is not able to track size calculation when it is stored into a variable, thus tell copy_from_user() maximum size via min(*max-size*, *effective-size*) explicitly and inline how much to copy at most. Signed-off-by: Bruno Prémont Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index de9cf21b..6f0642e 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -1584,11 +1584,11 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, memset(raw_data, 0, sizeof(raw_data)); raw_data[0] = *off & 0xff; raw_data[1] = (*off >> 8) & 0xff; - raw_data[2] = s < 20 ? s : 20; + raw_data[2] = min((size_t)20, s); if (*off + raw_data[2] > 0xff) raw_data[2] = 0x100 - *off; - if (copy_from_user(raw_data+3, u, raw_data[2])) + if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2]))) return -EFAULT; resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data, sizeof(raw_data)); -- cgit v0.10.2 From 4e61f0d75aa86c9e59451f6bcffcdceb355b4fc4 Mon Sep 17 00:00:00 2001 From: Austin Zhang Date: Mon, 9 May 2011 23:54:14 +0800 Subject: HID: hid-multitouch: add support for Ilitek dual-touch panel Added ILITEK hid dual touch panel support into hid-multitouch. Signed-off-by: Austin Zhang Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index d2d4e5f..d9635d6 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -306,6 +306,7 @@ config HID_MULTITOUCH - Cando dual touch panel - Cypress TrueTouch panels - Hanvon dual touch panels + - Ilitek dual touch panel - IrTouch Infrared USB panels - MosArt dual-touch panels - PenMount dual touch panels diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6e31b9f..c0ea857 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1377,6 +1377,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 252aeba..0f29b3f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -330,6 +330,9 @@ #define USB_DEVICE_ID_UGCI_FLYING 0x0020 #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 +#define USB_VENDOR_ID_ILITEK 0x222a +#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 + #define USB_VENDOR_ID_IMATION 0x0718 #define USB_DEVICE_ID_DISC_STAKKA 0xd000 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index bf46804..b21251b 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -589,6 +589,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, + /* Ilitek dual touch panel */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, + USB_DEVICE_ID_ILITEK_MULTITOUCH) }, + /* IRTOUCH panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, -- cgit v0.10.2 From dd2ed487fdd78b50549b2ca8418875c0d9f4a30e Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 15 May 2011 18:07:42 +0200 Subject: HID: 'name' and 'phys' in 'struct hid_device' can never be NULL As they are static members of fix size, there is no need to NULL-check them. Signed-off-by: Daniel Mack Cc: Dmitry Torokhov Cc: Jiri Kosina Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 93c72e5..c79578b 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -395,12 +395,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) { - int len; - if (!hid->name) { - ret = 0; - break; - } - len = strlen(hid->name) + 1; + int len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); ret = copy_to_user(user_arg, hid->name, len) ? @@ -409,12 +404,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) { - int len; - if (!hid->phys) { - ret = 0; - break; - } - len = strlen(hid->phys) + 1; + int len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); ret = copy_to_user(user_arg, hid->phys, len) ? diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 5270031..2baa71e 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -801,14 +801,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { - int len; - - if (!hid->name) { - r = 0; - break; - } - - len = strlen(hid->name) + 1; + int len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); r = copy_to_user(user_arg, hid->name, len) ? @@ -817,14 +810,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { - int len; - - if (!hid->phys) { - r = 0; - break; - } - - len = strlen(hid->phys) + 1; + int len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); r = copy_to_user(user_arg, hid->phys, len) ? -- cgit v0.10.2 From df167c4a0d68a9dbde044a39a77f255ac666f93e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Wed, 18 May 2011 15:27:24 +0200 Subject: HID: hid-multitouch: Add support for Lumio panels This patch enables support for Lumio optical devices. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index d9635d6..5a54b13 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -308,6 +308,7 @@ config HID_MULTITOUCH - Hanvon dual touch panels - Ilitek dual touch panel - IrTouch Infrared USB panels + - Lumio CrystalTouch panels - MosArt dual-touch panels - PenMount dual touch panels - Pixcir dual touch panels diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c0ea857..3dad069 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1410,6 +1410,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 0f29b3f..bfbc0d2 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -410,6 +410,9 @@ #define USB_DEVICE_ID_DINOVO_MINI 0xc71f #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 +#define USB_VENDOR_ID_LUMIO 0x202e +#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 + #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index b21251b..ef33e2d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -599,6 +599,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, + /* Lumio panels */ + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, + USB_DEVICE_ID_CRYSTALTOUCH) }, + /* MosArt panels */ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, HID_USB_DEVICE(USB_VENDOR_ID_ASUS, -- cgit v0.10.2 From b50f315cbb865079a16a12fd9ae6083f98fd592c Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Wed, 13 Apr 2011 17:17:52 +0200 Subject: HID: roccat: fix actual/startup profile sysfs attribute in koneplus startup_profile and actual_profile didn't work as expected. Also as the actual profile is persistent, the distinction between the two was ambiguous, so both use the same code now and startup_profile has been deprecated. Also the event is now propagated through chardev. The userland tool has been updated to support this change. Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina diff --git a/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus new file mode 100644 index 0000000..c2a270b --- /dev/null +++ b/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus @@ -0,0 +1,10 @@ +What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/startup_profile +Date: October 2010 +Contact: Stefan Achatz +Description: The integer value of this attribute ranges from 0-4. + When read, this attribute returns the number of the actual + profile. This value is persistent, so its equivalent to the + profile that's active when the mouse is powered on next time. + When written, this file sets the number of the startup profile + and the mouse activates this profile immediately. + Please use actual_profile, it does the same thing. diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus index 00efced..e5311a08 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus @@ -1,9 +1,12 @@ What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/actual_profile Date: October 2010 Contact: Stefan Achatz -Description: When read, this file returns the number of the actual profile in - range 0-4. - This file is readonly. +Description: The integer value of this attribute ranges from 0-4. + When read, this attribute returns the number of the actual + profile. This value is persistent, so its equivalent to the + profile that's active when the mouse is powered on next time. + When written, this file sets the number of the startup profile + and the mouse activates this profile immediately. Users: http://roccat.sourceforge.net What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/firmware_version @@ -89,16 +92,6 @@ Description: The mouse has a tracking- and a distance-control-unit. These This file is writeonly. Users: http://roccat.sourceforge.net -What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/startup_profile -Date: October 2010 -Contact: Stefan Achatz -Description: The integer value of this attribute ranges from 0-4. - When read, this attribute returns the number of the profile - that's active when the mouse is powered on. - When written, this file sets the number of the startup profile - and the mouse activates this profile immediately. -Users: http://roccat.sourceforge.net - What: /sys/bus/usb/devices/-:./::./koneplus/roccatkoneplus/tcu Date: October 2010 Contact: Stefan Achatz diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 33eec74..5b640a7 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -167,28 +167,28 @@ static int koneplus_set_profile_buttons(struct usb_device *usb_dev, } /* retval is 0-4 on success, < 0 on error */ -static int koneplus_get_startup_profile(struct usb_device *usb_dev) +static int koneplus_get_actual_profile(struct usb_device *usb_dev) { - struct koneplus_startup_profile buf; + struct koneplus_actual_profile buf; int retval; - retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, - &buf, sizeof(struct koneplus_startup_profile)); + retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE, + &buf, sizeof(struct koneplus_actual_profile)); - return retval ? retval : buf.startup_profile; + return retval ? retval : buf.actual_profile; } -static int koneplus_set_startup_profile(struct usb_device *usb_dev, - int startup_profile) +static int koneplus_set_actual_profile(struct usb_device *usb_dev, + int new_profile) { - struct koneplus_startup_profile buf; + struct koneplus_actual_profile buf; - buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE; - buf.size = sizeof(struct koneplus_startup_profile); - buf.startup_profile = startup_profile; + buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE; + buf.size = sizeof(struct koneplus_actual_profile); + buf.actual_profile = new_profile; - return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, - &buf, sizeof(struct koneplus_profile_buttons)); + return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE, + &buf, sizeof(struct koneplus_actual_profile)); } static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, @@ -398,21 +398,22 @@ static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, return sizeof(struct koneplus_profile_buttons); } -static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev, +static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, struct device_attribute *attr, char *buf) { struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); - return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile); + return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); } -static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, +static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev, struct device_attribute *attr, char const *buf, size_t size) { struct koneplus_device *koneplus; struct usb_device *usb_dev; unsigned long profile; int retval; + struct koneplus_roccat_report roccat_report; dev = dev->parent->parent; koneplus = hid_get_drvdata(dev_get_drvdata(dev)); @@ -423,20 +424,25 @@ static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, return retval; mutex_lock(&koneplus->koneplus_lock); - retval = koneplus_set_startup_profile(usb_dev, profile); - mutex_unlock(&koneplus->koneplus_lock); - if (retval) + + retval = koneplus_set_actual_profile(usb_dev, profile); + if (retval) { + mutex_unlock(&koneplus->koneplus_lock); return retval; + } - return size; -} + koneplus->actual_profile = profile; -static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct koneplus_device *koneplus = - hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); - return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); + roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE; + roccat_report.data1 = profile + 1; + roccat_report.data2 = 0; + roccat_report.profile = profile + 1; + roccat_report_event(koneplus->chrdev_minor, + (uint8_t const *)&roccat_report); + + mutex_unlock(&koneplus->koneplus_lock); + + return size; } static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, @@ -448,11 +454,12 @@ static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, } static struct device_attribute koneplus_attributes[] = { + __ATTR(actual_profile, 0660, + koneplus_sysfs_show_actual_profile, + koneplus_sysfs_set_actual_profile), __ATTR(startup_profile, 0660, - koneplus_sysfs_show_startup_profile, - koneplus_sysfs_set_startup_profile), - __ATTR(actual_profile, 0440, - koneplus_sysfs_show_actual_profile, NULL), + koneplus_sysfs_show_actual_profile, + koneplus_sysfs_set_actual_profile), __ATTR(firmware_version, 0440, koneplus_sysfs_show_firmware_version, NULL), __ATTR_NULL @@ -557,15 +564,10 @@ static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, struct koneplus_device *koneplus) { int retval, i; - static uint wait = 100; /* device will freeze with just 60 */ + static uint wait = 200; mutex_init(&koneplus->koneplus_lock); - koneplus->startup_profile = koneplus_get_startup_profile(usb_dev); - if (koneplus->startup_profile < 0) - return koneplus->startup_profile; - - msleep(wait); retval = koneplus_get_info(usb_dev, &koneplus->info); if (retval) return retval; @@ -584,7 +586,11 @@ static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, return retval; } - koneplus_profile_activated(koneplus, koneplus->startup_profile); + msleep(wait); + retval = koneplus_get_actual_profile(usb_dev); + if (retval < 0) + return retval; + koneplus_profile_activated(koneplus, retval); return 0; } diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h index 57a5c1a..c57a376 100644 --- a/drivers/hid/hid-roccat-koneplus.h +++ b/drivers/hid/hid-roccat-koneplus.h @@ -40,10 +40,10 @@ enum koneplus_control_values { KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, }; -struct koneplus_startup_profile { - uint8_t command; /* KONEPLUS_COMMAND_STARTUP_PROFILE */ +struct koneplus_actual_profile { + uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ uint8_t size; /* always 3 */ - uint8_t startup_profile; /* Range 0-4! */ + uint8_t actual_profile; /* Range 0-4! */ } __attribute__ ((__packed__)); struct koneplus_profile_settings { @@ -132,7 +132,7 @@ struct koneplus_tcu_image { enum koneplus_commands { KONEPLUS_COMMAND_CONTROL = 0x4, - KONEPLUS_COMMAND_STARTUP_PROFILE = 0x5, + KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, KONEPLUS_COMMAND_MACRO = 0x8, @@ -145,7 +145,7 @@ enum koneplus_commands { enum koneplus_usb_commands { KONEPLUS_USB_COMMAND_CONTROL = 0x304, - KONEPLUS_USB_COMMAND_STARTUP_PROFILE = 0x305, + KONEPLUS_USB_COMMAND_ACTUAL_PROFILE = 0x305, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307, KONEPLUS_USB_COMMAND_MACRO = 0x308, @@ -215,7 +215,6 @@ struct koneplus_device { struct mutex koneplus_lock; - int startup_profile; struct koneplus_info info; struct koneplus_profile_settings profile_settings[5]; struct koneplus_profile_buttons profile_buttons[5]; -- cgit v0.10.2 From 437f3b199c437e2a9ac01b9ab733c78e5fc7c720 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Tue, 19 Apr 2011 15:28:30 -0400 Subject: HID: assorted usage updates from hut 1.12 I've got a Tivo Slide bluetooth remote/dongle, which uses a fair number of hid usages that aren't currently mapped in hid-input.c. I'd initially written additions to hid-input.c with just this device in mind, including some bits that were specific to the device. This go around, I'm looking at adding/correcting as many generic HID usages from the HID Usage Tables, version 1.12, as I can -- which also serves to enable all but four of the buttons on the Tivo Slide remote[*]. Outside of fixing the obviously incorrect mapping of 0xc 0x45 from KEY_RADIO to KEY_RIGHT, and making use of the new KEY_IMAGES (just added in 2.6.39-rc4) for AL Image Browser instead of KEY_MEDIA, these are purely additions, and thus should have no negative impact on any already functional HID devices. Most of the added mappings seemed to be perfectly logical to me, but there were a few that were mapped on more of an "I think this makes the most sense" basis. [*] I'll handle the last four tivo buttons via an hid-tivo.c follow-up. CC: Dmitry Torokhov CC: Jiri Kosina Signed-off-by: Jarod Wilson Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 33dde87..6559e2e 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -44,11 +44,11 @@ static const unsigned char hid_keyboard[256] = { 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, - 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, + 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk, unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk, unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, - unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, + unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk, 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk }; @@ -357,6 +357,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x1: map_key_clear(KEY_POWER); break; case 0x2: map_key_clear(KEY_SLEEP); break; case 0x3: map_key_clear(KEY_WAKEUP); break; + case 0x4: map_key_clear(KEY_CONTEXT_MENU); break; + case 0x5: map_key_clear(KEY_MENU); break; + case 0x6: map_key_clear(KEY_PROG1); break; + case 0x7: map_key_clear(KEY_HELP); break; + case 0x8: map_key_clear(KEY_EXIT); break; + case 0x9: map_key_clear(KEY_SELECT); break; + case 0xa: map_key_clear(KEY_RIGHT); break; + case 0xb: map_key_clear(KEY_LEFT); break; + case 0xc: map_key_clear(KEY_UP); break; + case 0xd: map_key_clear(KEY_DOWN); break; + case 0xe: map_key_clear(KEY_POWER2); break; + case 0xf: map_key_clear(KEY_RESTART); break; default: goto unknown; } break; @@ -466,16 +478,39 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } break; - case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ + case HID_UP_CONSUMER: /* USB HUT v1.12, pages 75-84 */ switch (usage->hid & HID_USAGE) { case 0x000: goto ignore; + case 0x030: map_key_clear(KEY_POWER); break; + case 0x031: map_key_clear(KEY_RESTART); break; + case 0x032: map_key_clear(KEY_SLEEP); break; case 0x034: map_key_clear(KEY_SLEEP); break; + case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE); break; case 0x036: map_key_clear(BTN_MISC); break; - case 0x040: map_key_clear(KEY_MENU); break; - case 0x045: map_key_clear(KEY_RADIO); break; - + case 0x040: map_key_clear(KEY_MENU); break; /* Menu */ + case 0x041: map_key_clear(KEY_SELECT); break; /* Menu Pick */ + case 0x042: map_key_clear(KEY_UP); break; /* Menu Up */ + case 0x043: map_key_clear(KEY_DOWN); break; /* Menu Down */ + case 0x044: map_key_clear(KEY_LEFT); break; /* Menu Left */ + case 0x045: map_key_clear(KEY_RIGHT); break; /* Menu Right */ + case 0x046: map_key_clear(KEY_ESC); break; /* Menu Escape */ + case 0x047: map_key_clear(KEY_KPPLUS); break; /* Menu Value Increase */ + case 0x048: map_key_clear(KEY_KPMINUS); break; /* Menu Value Decrease */ + + case 0x060: map_key_clear(KEY_INFO); break; /* Data On Screen */ + case 0x061: map_key_clear(KEY_SUBTITLE); break; /* Closed Caption */ + case 0x063: map_key_clear(KEY_VCR); break; /* VCR/TV */ + case 0x065: map_key_clear(KEY_CAMERA); break; /* Snapshot */ + case 0x069: map_key_clear(KEY_RED); break; + case 0x06a: map_key_clear(KEY_GREEN); break; + case 0x06b: map_key_clear(KEY_BLUE); break; + case 0x06c: map_key_clear(KEY_YELLOW); break; + case 0x06d: map_key_clear(KEY_ZOOM); break; + + case 0x082: map_key_clear(KEY_VIDEO_NEXT); break; case 0x083: map_key_clear(KEY_LAST); break; + case 0x084: map_key_clear(KEY_ENTER); break; case 0x088: map_key_clear(KEY_PC); break; case 0x089: map_key_clear(KEY_TV); break; case 0x08a: map_key_clear(KEY_WWW); break; @@ -509,6 +544,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x0b7: map_key_clear(KEY_STOPCD); break; case 0x0b8: map_key_clear(KEY_EJECTCD); break; case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break; + case 0x0b9: map_key_clear(KEY_SHUFFLE); break; + case 0x0bf: map_key_clear(KEY_SLOW); break; case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; case 0x0e0: map_abs_clear(ABS_VOLUME); break; @@ -516,6 +553,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x0e5: map_key_clear(KEY_BASSBOOST); break; case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; + case 0x0f5: map_key_clear(KEY_SLOW); break; case 0x182: map_key_clear(KEY_BOOKMARKS); break; case 0x183: map_key_clear(KEY_CONFIG); break; @@ -532,6 +570,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x18e: map_key_clear(KEY_CALENDAR); break; case 0x191: map_key_clear(KEY_FINANCE); break; case 0x192: map_key_clear(KEY_CALC); break; + case 0x193: map_key_clear(KEY_PLAYER); break; case 0x194: map_key_clear(KEY_FILE); break; case 0x196: map_key_clear(KEY_WWW); break; case 0x199: map_key_clear(KEY_CHAT); break; @@ -540,8 +579,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x1a6: map_key_clear(KEY_HELP); break; case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; case 0x1ab: map_key_clear(KEY_SPELLCHECK); break; - case 0x1b6: map_key_clear(KEY_MEDIA); break; - case 0x1b7: map_key_clear(KEY_SOUND); break; + case 0x1ae: map_key_clear(KEY_KEYBOARD); break; + case 0x1b6: map_key_clear(KEY_IMAGES); break; + case 0x1b7: map_key_clear(KEY_AUDIO); break; + case 0x1b8: map_key_clear(KEY_VIDEO); break; case 0x1bc: map_key_clear(KEY_MESSENGER); break; case 0x1bd: map_key_clear(KEY_INFO); break; case 0x201: map_key_clear(KEY_NEW); break; @@ -570,7 +611,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x233: map_key_clear(KEY_SCROLLUP); break; case 0x234: map_key_clear(KEY_SCROLLDOWN); break; case 0x238: map_rel(REL_HWHEEL); break; + case 0x23d: map_key_clear(KEY_EDIT); break; case 0x25f: map_key_clear(KEY_CANCEL); break; + case 0x269: map_key_clear(KEY_INSERT); break; + case 0x26a: map_key_clear(KEY_DELETE); break; case 0x279: map_key_clear(KEY_REDO); break; case 0x289: map_key_clear(KEY_REPLY); break; -- cgit v0.10.2 From c04abeeff9d76a703cac1e6d312853b0fc8136f5 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 11:37:29 +0200 Subject: HID: hid-multitouch: add support for Elo TouchSystems 2515 IntelliTouch Plus This patch adds support for Elo TouchSystems 2515 IntelliTouch Plus that can be found in Lenovo A700 all-in-one. Signed-off-by: Benjamin Tissoires Tested-by: Bastien Nocera Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 5a54b13..1572ff1 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -305,6 +305,7 @@ config HID_MULTITOUCH - 3M PCT touch screens - Cando dual touch panel - Cypress TrueTouch panels + - Elo TouchSystems IntelliTouch Plus panels - Hanvon dual touch panels - Ilitek dual touch panel - IrTouch Infrared USB panels diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3dad069..053fc08 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1366,6 +1366,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) }, { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index bfbc0d2..6c19d1a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -216,6 +216,7 @@ #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 #define USB_VENDOR_ID_ELO 0x04E7 +#define USB_DEVICE_ID_ELO_TS2515 0x0022 #define USB_DEVICE_ID_ELO_TS2700 0x0020 #define USB_VENDOR_ID_EMS 0x2006 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index ef33e2d..3bc8de6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -92,6 +92,7 @@ struct mt_class { #define MT_CLS_3M 7 #define MT_CLS_CONFIDENCE 8 #define MT_CLS_CONFIDENCE_MINUS_ONE 9 +#define MT_CLS_DUAL_NSMU_CONTACTID 10 #define MT_DEFAULT_MAXCONTACT 10 @@ -163,6 +164,10 @@ struct mt_class mt_classes[] = { .sn_height = 128 }, { .name = MT_CLS_CONFIDENCE, .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { .name = MT_CLS_DUAL_NSMU_CONTACTID, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | + MT_QUIRK_SLOT_IS_CONTACTID, + .maxcontacts = 2 }, { } }; @@ -584,6 +589,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, + /* Elo TouchSystems IntelliTouch Plus panel */ + { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, + HID_USB_DEVICE(USB_VENDOR_ID_ELO, + USB_DEVICE_ID_ELO_TS2515) }, + /* GeneralTouch panel */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, -- cgit v0.10.2 From 966922f26c7fb5eddbe3c506b66bb5659f57b76f Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Thu, 19 May 2011 21:41:22 +0200 Subject: HID: fix a crash in hid_report_raw_event() function. I'm using a Data Modul EasyTouch USB multitouch controller, which is issuing a hid report with a size equals to 0. The rsize value gets set to 536870912 and Linux is crashing in the memset because the value is too big. Signed-off-by: Armando Visconti Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 852989f..84df80e 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1045,6 +1045,9 @@ void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, rsize = ((report->size - 1) >> 3) + 1; + if (rsize > HID_MAX_BUFFER_SIZE) + rsize = HID_MAX_BUFFER_SIZE; + if (csize < rsize) { dbg_hid("report %d is too short, (%d < %d)\n", report->id, csize, rsize); -- cgit v0.10.2 From 23746a66d7d9e73402c68ef00d708796b97ebd72 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 19 May 2011 17:58:07 +0200 Subject: HID: magicmouse: ignore 'ivalid report id' while switching modes The device reponds with 'invalid report id' when feature report switching it into multitouch mode is sent to it. This has been silently ignored before 0825411ade ("HID: bt: Wait for ACK on Sent Reports"), but since this commit, it propagates -EIO from the _raw callback . So let the driver ignore -EIO as response to 0xd7,0x01 report, as that's how the device reacts in normal mode. Sad, but following reality. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=35022 Tested-by: Chase Douglas Signed-off-by: Jiri Kosina diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 318cc40..82f0c3d 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -499,9 +499,17 @@ static int magicmouse_probe(struct hid_device *hdev, } report->size = 6; + /* + * The device reponds with 'invalid report id' when feature + * report switching it into multitouch mode is sent to it. + * + * This results in -EIO from the _raw low-level transport callback, + * but there seems to be no other way of switching the mode. + * Thus the super-ugly hacky success check below. + */ ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), HID_FEATURE_REPORT); - if (ret != sizeof(feature)) { + if (ret != -EIO) { hid_err(hdev, "unable to request touch data (%d)\n", ret); goto err_stop_hw; } -- cgit v0.10.2 From 6cb4b040795c555c7ab4b1ba29b0dba2b5a42beb Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Fri, 20 May 2011 10:50:13 +0200 Subject: HID: hiddev: fix race between hiddev_disconnect and hiddev_release When hiddev_disconnect() runs with chardev open, it will proceed with usbhid_close(). When userspace in parallel runs the hiddev_release(), it sees !hiddev->exists (as it has been already set so by hiddev_disconnect()) and kfrees hiddev while hiddev_disconnect() hasn't finished yet. Serialize the access to hiddev->exists and hiddev->open by existancelock. Reported-by: mike-@cinci.rr.com Signed-off-by: Jiri Kosina diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 2baa71e..f4c67a5 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -242,6 +242,7 @@ static int hiddev_release(struct inode * inode, struct file * file) list_del(&list->node); spin_unlock_irqrestore(&list->hiddev->list_lock, flags); + mutex_lock(&list->hiddev->existancelock); if (!--list->hiddev->open) { if (list->hiddev->exist) { usbhid_close(list->hiddev->hid); @@ -252,6 +253,7 @@ static int hiddev_release(struct inode * inode, struct file * file) } kfree(list); + mutex_unlock(&list->hiddev->existancelock); return 0; } @@ -300,17 +302,21 @@ static int hiddev_open(struct inode *inode, struct file *file) list_add_tail(&list->node, &hiddev->list); spin_unlock_irq(&list->hiddev->list_lock); + mutex_lock(&hiddev->existancelock); if (!list->hiddev->open++) if (list->hiddev->exist) { struct hid_device *hid = hiddev->hid; res = usbhid_get_power(hid); if (res < 0) { res = -EIO; - goto bail; + goto bail_unlock; } usbhid_open(hid); } + mutex_unlock(&hiddev->existancelock); return 0; +bail_unlock: + mutex_unlock(&hiddev->existancelock); bail: file->private_data = NULL; kfree(list); @@ -911,7 +917,6 @@ void hiddev_disconnect(struct hid_device *hid) mutex_lock(&hiddev->existancelock); hiddev->exist = 0; - mutex_unlock(&hiddev->existancelock); usb_deregister_dev(usbhid->intf, &hiddev_class); @@ -921,4 +926,5 @@ void hiddev_disconnect(struct hid_device *hid) } else { kfree(hiddev); } + mutex_unlock(&hiddev->existancelock); } -- cgit v0.10.2 From e6aac3427ef03f61e7478514d0648b58359d05d1 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 14:18:13 +0200 Subject: HID: hid-multitouch: add support for ActionStar panels This patch introduce support for ActionStar panels. This device has not been optimized in term of kernel processing operations (default class), but it will work. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1572ff1..605b69b 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -303,6 +303,7 @@ config HID_MULTITOUCH Say Y here if you have one of the following devices: - 3M PCT touch screens + - ActionStar dual touch panels - Cando dual touch panel - Cypress TrueTouch panels - Elo TouchSystems IntelliTouch Plus panels diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 053fc08..c2382b6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1290,6 +1290,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, USB_DEVICE_ID_ACTIONSTAR_1011) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6c19d1a..0ebb7fa 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -37,6 +37,9 @@ #define USB_VENDOR_ID_ACRUX 0x1a34 +#define USB_VENDOR_ID_ACTIONSTAR 0x2101 +#define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 + #define USB_VENDOR_ID_ADS_TECH 0x06e1 #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3bc8de6..10a8c76 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -570,6 +570,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, + /* ActionStar panels */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, + USB_DEVICE_ID_ACTIONSTAR_1011) }, + /* Cando panels */ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, HID_USB_DEVICE(USB_VENDOR_ID_CANDO, -- cgit v0.10.2 From 79603dc9a8223856cf3194dcabad32b9828c7be9 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 14:18:14 +0200 Subject: HID: hid-multitouch: add support for CVTouch panels This patch introduce support for CVTouch panels. This device has not been optimized in term of kernel processing operations (default class), but it will work. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 605b69b..3e14815 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -305,6 +305,7 @@ config HID_MULTITOUCH - 3M PCT touch screens - ActionStar dual touch panels - Cando dual touch panel + - CVTouch panels - Cypress TrueTouch panels - Elo TouchSystems IntelliTouch Plus panels - Hanvon dual touch panels diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c2382b6..cc52faa 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1354,6 +1354,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, { 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) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 0ebb7fa..e9b8004 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -181,6 +181,9 @@ #define USB_VENDOR_ID_CREATIVELABS 0x041e #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 +#define USB_VENDOR_ID_CVTOUCH 0x1ff7 +#define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013 + #define USB_VENDOR_ID_CYGNAL 0x10c4 #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 10a8c76..af8789a 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -589,6 +589,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, + /* CVTouch panels */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, + USB_DEVICE_ID_CVTOUCH_SCREEN) }, + /* Cypress panel */ { .driver_data = MT_CLS_CYPRESS, HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, -- cgit v0.10.2 From ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 14:18:15 +0200 Subject: HID: hid-multitouch: add support for GoodTouch panels This patch introduce support for GoodTouch panels. This device has not been optimized in term of kernel processing operations (default class), but it will work. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3e14815..9a8ecc0 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -308,6 +308,7 @@ config HID_MULTITOUCH - CVTouch panels - Cypress TrueTouch panels - Elo TouchSystems IntelliTouch Plus panels + - GoodTouch panels - Hanvon dual touch panels - Ilitek dual touch panel - IrTouch Infrared USB panels diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index cc52faa..5ba23fb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1374,6 +1374,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, USB_DEVICE_ID_GOODTOUCH_000f) }, { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) }, { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index e9b8004..5ad8235 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -258,6 +258,9 @@ #define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 #define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 +#define USB_VENDOR_ID_GOODTOUCH 0x1aad +#define USB_DEVICE_ID_GOODTOUCH_000f 0x000f + #define USB_VENDOR_ID_GOTOP 0x08f2 #define USB_DEVICE_ID_SUPER_Q2 0x007f #define USB_DEVICE_ID_GOGOPEN 0x00ce diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index af8789a..76ef60d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -609,6 +609,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, + /* GoodTouch panels */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, + USB_DEVICE_ID_GOODTOUCH_000f) }, + /* Ilitek dual touch panel */ { .driver_data = MT_CLS_DEFAULT, HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, -- cgit v0.10.2 From 5e74e56da03f581482c104628951eeb1455848ea Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 14:18:16 +0200 Subject: HID: hid-multitouch: add support for Touch International panels This patch introduce support for Touch International panels. This device has not been optimized in term of kernel processing operations (default class), but it will work. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 9a8ecc0..34ba931 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -320,6 +320,7 @@ config HID_MULTITOUCH - eGalax dual-touch panels, including the Joojoo and Wetab tablets - Stantum multitouch panels + - Touch International Panels If unsure, say N. diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5ba23fb..697ee3f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1472,6 +1472,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5ad8235..84871eb 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -574,6 +574,9 @@ #define USB_VENDOR_ID_TOPMAX 0x0663 #define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 +#define USB_VENDOR_ID_TOUCH_INTL 0x1e5e +#define USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH 0x0313 + #define USB_VENDOR_ID_TOUCHPACK 0x1bfd #define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 76ef60d..bc57615 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -683,6 +683,11 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP_SITRONIX)}, + /* Touch International panels */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, + USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, + { } }; MODULE_DEVICE_TABLE(hid, mt_devices); -- cgit v0.10.2 From 617b64f97708be26a061e6c8178ad46b4c49d031 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 14:18:17 +0200 Subject: HID: hid-multitouch: add support for Unitec panels This patch introduce support for Unitec panels. This device has not been optimized in term of kernel processing operations (default class), but it will work. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 34ba931..88e6b2b 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -321,6 +321,7 @@ config HID_MULTITOUCH Joojoo and Wetab tablets - Stantum multitouch panels - Touch International Panels + - Unitec Panels If unsure, say N. diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 697ee3f..9f15c92 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1479,6 +1479,8 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, + { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, + { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 84871eb..b8299ef 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -594,6 +594,10 @@ #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 +#define USB_VENDOR_ID_UNITEC 0x227d +#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 +#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19 + #define USB_VENDOR_ID_VERNIER 0x08f7 #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index bc57615..feeb0b7 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -688,6 +688,14 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, + /* Unitec panels */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, + USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, + USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, + { } }; MODULE_DEVICE_TABLE(hid, mt_devices); -- cgit v0.10.2 From bf5af9b5bba2453ff46f241e8f2e139ca79302e7 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Thu, 19 May 2011 14:18:18 +0200 Subject: HID: hid-multitouch: class MT_CLS_STANTUM is redundant with MT_CLS_CONFIDENCE Stantum devices used to work with MT_CLS_STANTUM but MT_CLS_CONFIDENCE is exactly the same. This patch switches them to this generic class, and remove the unused MT_CLS_STANTUM. 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 feeb0b7..65b92d2 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -88,7 +88,6 @@ struct mt_class { #define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 #define MT_CLS_CYPRESS 4 #define MT_CLS_EGALAX 5 -#define MT_CLS_STANTUM 6 #define MT_CLS_3M 7 #define MT_CLS_CONFIDENCE 8 #define MT_CLS_CONFIDENCE_MINUS_ONE 9 @@ -154,8 +153,6 @@ struct mt_class mt_classes[] = { .sn_move = 4096, .sn_pressure = 32, }, - { .name = MT_CLS_STANTUM, - .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, { .name = MT_CLS_3M, .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | MT_QUIRK_SLOT_IS_CONTACTID, @@ -673,13 +670,13 @@ static const struct hid_device_id mt_devices[] = { USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, /* Stantum panels */ - { .driver_data = MT_CLS_STANTUM, + { .driver_data = MT_CLS_CONFIDENCE, HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP)}, - { .driver_data = MT_CLS_STANTUM, + { .driver_data = MT_CLS_CONFIDENCE, HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP_STM)}, - { .driver_data = MT_CLS_STANTUM, + { .driver_data = MT_CLS_CONFIDENCE, HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP_SITRONIX)}, -- cgit v0.10.2 From 22408283bca57780bdd53da5a6e4474b71b94430 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 20 May 2011 15:59:34 +0200 Subject: HID: hid-multitouch: cosmetic changes, sort classes and devices This patch sorts the defs for the MT_CLS. I choose to split generic classes and device specific ones to be able to add more generic classes in the future. It also put eGalax devices at their right place (alphabetically) in mt_devices. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 88e6b2b..d588a5e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -304,21 +304,20 @@ config HID_MULTITOUCH Say Y here if you have one of the following devices: - 3M PCT touch screens - ActionStar dual touch panels - - Cando dual touch panel + - Cando dual touch panels - CVTouch panels - Cypress TrueTouch panels - Elo TouchSystems IntelliTouch Plus panels + - GeneralTouch 'Sensing Win7-TwoFinger' panels - GoodTouch panels - Hanvon dual touch panels - - Ilitek dual touch panel + - Ilitek dual touch panels - IrTouch Infrared USB panels - Lumio CrystalTouch panels - MosArt dual-touch panels - PenMount dual touch panels - Pixcir dual touch panels - - 'Sensing Win7-TwoFinger' panel by GeneralTouch - - eGalax dual-touch panels, including the - Joojoo and Wetab tablets + - eGalax dual-touch panels, including the Joojoo and Wetab tablets - Stantum multitouch panels - Touch International Panels - Unitec Panels diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 65b92d2..ecd4d2d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -83,15 +83,18 @@ struct mt_class { }; /* classes of device behavior */ -#define MT_CLS_DEFAULT 1 -#define MT_CLS_DUAL_INRANGE_CONTACTID 2 -#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3 -#define MT_CLS_CYPRESS 4 -#define MT_CLS_EGALAX 5 -#define MT_CLS_3M 7 -#define MT_CLS_CONFIDENCE 8 -#define MT_CLS_CONFIDENCE_MINUS_ONE 9 -#define MT_CLS_DUAL_NSMU_CONTACTID 10 +#define MT_CLS_DEFAULT 0x0001 + +#define MT_CLS_CONFIDENCE 0x0002 +#define MT_CLS_CONFIDENCE_MINUS_ONE 0x0003 +#define MT_CLS_DUAL_INRANGE_CONTACTID 0x0004 +#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0005 +#define MT_CLS_DUAL_NSMU_CONTACTID 0x0006 + +/* vendor specific classes */ +#define MT_CLS_3M 0x0101 +#define MT_CLS_CYPRESS 0x0102 +#define MT_CLS_EGALAX 0x0103 #define MT_DEFAULT_MAXCONTACT 10 @@ -130,6 +133,11 @@ static int find_slot_from_contactid(struct mt_device *td) struct mt_class mt_classes[] = { { .name = MT_CLS_DEFAULT, .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, + { .name = MT_CLS_CONFIDENCE, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, + { .name = MT_CLS_CONFIDENCE_MINUS_ONE, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | + MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, { .name = MT_CLS_DUAL_INRANGE_CONTACTID, .quirks = MT_QUIRK_VALID_IS_INRANGE | MT_QUIRK_SLOT_IS_CONTACTID, @@ -138,13 +146,24 @@ struct mt_class mt_classes[] = { .quirks = MT_QUIRK_VALID_IS_INRANGE | MT_QUIRK_SLOT_IS_CONTACTNUMBER, .maxcontacts = 2 }, + { .name = MT_CLS_DUAL_NSMU_CONTACTID, + .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | + MT_QUIRK_SLOT_IS_CONTACTID, + .maxcontacts = 2 }, + + /* + * vendor specific classes + */ + { .name = MT_CLS_3M, + .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | + MT_QUIRK_SLOT_IS_CONTACTID, + .sn_move = 2048, + .sn_width = 128, + .sn_height = 128 }, { .name = MT_CLS_CYPRESS, .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | MT_QUIRK_CYPRESS, .maxcontacts = 10 }, - { .name = MT_CLS_CONFIDENCE_MINUS_ONE, - .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | - MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, { .name = MT_CLS_EGALAX, .quirks = MT_QUIRK_SLOT_IS_CONTACTID | MT_QUIRK_VALID_IS_INRANGE | @@ -153,18 +172,6 @@ struct mt_class mt_classes[] = { .sn_move = 4096, .sn_pressure = 32, }, - { .name = MT_CLS_3M, - .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | - MT_QUIRK_SLOT_IS_CONTACTID, - .sn_move = 2048, - .sn_width = 128, - .sn_height = 128 }, - { .name = MT_CLS_CONFIDENCE, - .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, - { .name = MT_CLS_DUAL_NSMU_CONTACTID, - .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | - MT_QUIRK_SLOT_IS_CONTACTID, - .maxcontacts = 2 }, { } }; @@ -596,6 +603,25 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, + /* eGalax devices (resistive) */ + { .driver_data = MT_CLS_EGALAX, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, + { .driver_data = MT_CLS_EGALAX, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, + + /* eGalax devices (capacitive) */ + { .driver_data = MT_CLS_EGALAX, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, + { .driver_data = MT_CLS_EGALAX, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, + { .driver_data = MT_CLS_EGALAX, + HID_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, + /* Elo TouchSystems IntelliTouch Plus panel */ { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, HID_USB_DEVICE(USB_VENDOR_ID_ELO, @@ -650,25 +676,6 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, - /* Resistive eGalax devices */ - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) }, - - /* Capacitive eGalax devices */ - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) }, - { .driver_data = MT_CLS_EGALAX, - HID_USB_DEVICE(USB_VENDOR_ID_DWAV, - USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) }, - /* Stantum panels */ { .driver_data = MT_CLS_CONFIDENCE, HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, -- cgit v0.10.2