2257 lines
67 KiB
Diff
2257 lines
67 KiB
Diff
commit 9498f954a4ec389806333041a1018909c6fe0518
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Fri Mar 18 14:27:52 2011 +0100
|
|
|
|
HID: hid-multitouch: Auto detection of maxcontacts
|
|
|
|
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 <benjamin.tissoires@enac.fr>
|
|
Reviewed-by: Stéphane Chatty <chatty@enac.fr>
|
|
Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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);
|
|
}
|
|
commit 043b403aede4a528ed99ceaf050f567f1283a23e
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Fri Mar 18 14:27:53 2011 +0100
|
|
|
|
HID: hid-multitouch: migrate support for Stantum panels to the unified driver.
|
|
|
|
This patch merges hid-stantum to the generic multitouch driver.
|
|
|
|
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Reviewed-by: Stéphane Chatty <chatty@enac.fr>
|
|
Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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 <chatty@enac.fr>
|
|
- *
|
|
- */
|
|
-
|
|
-/*
|
|
- * 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 <linux/device.h>
|
|
-#include <linux/hid.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/slab.h>
|
|
-
|
|
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
|
|
-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);
|
|
-
|
|
commit a841b62c5d5f75ce3676fde755696d30cc8de99a
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Fri Mar 18 14:27:54 2011 +0100
|
|
|
|
HID: hid-multitouch: migrate Cando dual touch panels to hid-multitouch
|
|
|
|
This patch merges hid-cando into the unified multitouch driver.
|
|
|
|
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Reviewed-by: Stéphane Chatty <chatty@enac.fr>
|
|
Reviewed-by: Henrik Rydberg <rydberg@euromail.se>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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 <chatty@enac.fr>
|
|
- *
|
|
- */
|
|
-
|
|
-/*
|
|
- * 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 <linux/device.h>
|
|
-#include <linux/hid.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/slab.h>
|
|
-
|
|
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
|
|
-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,
|
|
commit 1e648a13720ef5de51f132501acf3e443d1a36d4
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Fri Mar 18 14:27:55 2011 +0100
|
|
|
|
HID: hid-multitouch: refactor initialization of ABS_MT_ORIENTATION
|
|
|
|
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 <benjamin.tissoires@enac.fr>
|
|
Reviewed-by: Stéphane Chatty <chatty@enac.fr>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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:
|
|
commit f786bba4499cf3de20da345ce090457ebcef03b0
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Tue Mar 22 17:34:01 2011 +0100
|
|
|
|
HID: hid-multitouch: migrate 3M PCT touch screens to hid-multitouch
|
|
|
|
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 <benjamin.tissoires@enac.fr>
|
|
Reviewed-by: Stéphane Chatty <chatty@enac.fr>
|
|
Reviewed-and-tested-by: Henrik Rydberg <rydberg@euromail.se>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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 <chatty@enac.fr>
|
|
- * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
|
|
- * 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 <linux/device.h>
|
|
-#include <linux/hid.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/slab.h>
|
|
-#include <linux/usb.h>
|
|
-#include <linux/input/mt.h>
|
|
-
|
|
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
|
|
-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 <rydberg@euromail.se>
|
|
* Copyright (c) 2010 Canonical, Ltd.
|
|
*
|
|
+ * This code is partly based on hid-3m-pct.c:
|
|
+ *
|
|
+ * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
|
|
+ * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
|
|
+ * 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,
|
|
commit 2955caed8b9865c1f04fcde6bd7103d5d5ec9415
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Thu Apr 21 14:15:59 2011 +0200
|
|
|
|
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 <benjamin.tissoires@enac.fr>
|
|
Reviewed-and-tested-by: Henrik Rydberg <rydberg@euromail.se>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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
|
|
commit 6ab3a9a63fc16b04f7de48eb0190d516dd7574df
|
|
Author: John Sung <penmount.touch@gmail.com>
|
|
Date: Thu Apr 21 16:21:52 2011 +0200
|
|
|
|
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 <penmount.touch@gmail.com>
|
|
[benjamin.tissoires@enac.fr: rebased on top of last_index_field changes]
|
|
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Acked-by: Henrik Rydberg <rydberg@euromail.se>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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,
|
|
commit 4a6ee685fbcba4a440cf86f41557752ba81e2ccf
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Fri Apr 22 11:51:48 2011 +0200
|
|
|
|
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 <benjamin.tissoires@enac.fr>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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 <chatty@enac.fr>
|
|
- * Copyright (c) 2010 Teemu Tuominen <teemu.tuominen@cybercom.com>
|
|
- *
|
|
- */
|
|
-
|
|
-/*
|
|
- * 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 <linux/device.h>
|
|
-#include <linux/hid.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/slab.h>
|
|
-#include <linux/usb.h>
|
|
-#include "usbhid/usbhid.h"
|
|
-
|
|
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
|
|
-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,
|
|
commit 4e61f0d75aa86c9e59451f6bcffcdceb355b4fc4
|
|
Author: Austin Zhang <zhang.austin@gmail.com>
|
|
Date: Mon May 9 23:54:14 2011 +0800
|
|
|
|
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 <zhang.austin@gmail.com>
|
|
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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,
|
|
commit df167c4a0d68a9dbde044a39a77f255ac666f93e
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Wed May 18 15:27:24 2011 +0200
|
|
|
|
HID: hid-multitouch: Add support for Lumio panels
|
|
|
|
This patch enables support for Lumio optical devices.
|
|
|
|
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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,
|
|
commit c04abeeff9d76a703cac1e6d312853b0fc8136f5
|
|
Author: Benjamin Tissoires <benjamin.tissoires@enac.fr>
|
|
Date: Thu May 19 11:37:29 2011 +0200
|
|
|
|
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 <benjamin.tissoires@enac.fr>
|
|
Tested-by: Bastien Nocera <hadess@hadess.net>
|
|
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
|
|
|
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,
|