[Sony Ericsson XPERIA X10 Mini] owain94:
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 9f1ab80..1dcb4b0 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1299,6 +1299,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ 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) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 70dd0fd..d8b0b3f 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -181,6 +181,7 @@
#define USB_DEVICE_ID_CYPRESS_BARCODE_1	0xde61
#define USB_DEVICE_ID_CYPRESS_BARCODE_2	0xde64
#define USB_DEVICE_ID_CYPRESS_BARCODE_3	0xbca1
+#define USB_DEVICE_ID_CYPRESS_TRUETOUCH	0xc001

#define USB_VENDOR_ID_DEALEXTREAME	0x10c5
#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701	0x819a
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 9edbf5d..f9d537e 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -65,6 +65,7 @@ struct mt_class {
#define MT_CLS_DEFAULT 0
#define MT_CLS_DUAL1 1
#define MT_CLS_DUAL2 2
+#define MT_CLS_CYPRESS 3

/*
* these device-dependent functions determine what slot corresponds
@@ -81,6 +82,14 @@ static int slot_is_contactnumber(struct mt_device *td)
return td->num_received;
}

+static int cypress_compute_slot(struct mt_device *td)
+{
+	if (td->curdata.contactid != 0 || td->num_received == 0)
+	return td->curdata.contactid;
+	else
+	return -1;
+}
+
static int find_slot_from_contactid(struct mt_device *td)
{
int i;
@@ -100,6 +109,7 @@ struct mt_class mt_classes[] = {
{ find_slot_from_contactid, 10 }, /* MT_CLS_DEFAULT */
{ slot_is_contactid, 2 }, /* MT_CLS_DUAL1 */
{ slot_is_contactnumber, 2 }, /* MT_CLS_DUAL2 */
+	{ cypress_compute_slot, 10 }, /* MT_CLS_CYPRESS */
};

static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -414,6 +424,11 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },

+	/* Cypress panel */
+	{ .driver_data = MT_CLS_CYPRESS,
+	HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
+	USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
+
{ }
};
MODULE_DEVICE_TABLE(hid, mt_devices);

or this one

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 95ee5fe..12e24ef 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -291,10 +291,16 @@ config HID_MULTITOUCH
Generic support for HID multitouch panels.

Say Y here if you have one of the following devices:
- - PixCir touchscreen
- - Cypress TrueTouch
+ - Cypress TrueTouch panels
+ - Hanvon dual touch panels
+ - Pixcir dual touch panels
- 'Sensing Win7-TwoFinger' panel by GeneralTouch

+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hid-multitouch.
+
config HID_NTRIG
tristate "N-Trig touch screen"
depends on USB_HID
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 3442ed5..07d3183 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -32,8 +32,10 @@ MODULE_LICENSE("GPL");
/* quirks to control the device */
#define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0)
#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1)
-#define MT_QUIRK_CYPRESS (1 << 2)
+#define MT_QUIRK_CYPRESS (1 << 2)
#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
+#define MT_QUIRK_VALID_IS_INRANGE (1 << 4)
+#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5)

struct mt_slot {
__s32 x, y, p, w, h;
@@ -55,6 +57,7 @@ struct mt_device {
};

struct mt_class {
+ __s32 name; /* MT_CLS */
__s32 quirks;
__s32 sn_move; /* Signal/noise ratio for move events */
__s32 sn_pressure; /* Signal/noise ratio for pressure events */
@@ -62,26 +65,16 @@ struct mt_class {
};

/* classes of device behavior */
-#define MT_CLS_DEFAULT 0
-#define MT_CLS_DUAL1 1
-#define MT_CLS_DUAL2 2
-#define MT_CLS_CYPRESS 3
+#define MT_CLS_DEFAULT 1
+#define MT_CLS_DUAL1 2
+#define MT_CLS_DUAL2 3
+#define MT_CLS_CYPRESS 4

/*
* these device-dependent functions determine what slot corresponds
* to a valid contact that was just read.
*/

-static int slot_is_contactid(struct mt_device *td)
-{
- return td->curdata.contactid;
-}
-
-static int slot_is_contactnumber(struct mt_device *td)
-{
- return td->num_received;
-}
-
static int cypress_compute_slot(struct mt_device *td)
{
if (td->curdata.contactid != 0 || td->num_received == 0)
@@ -103,17 +96,30 @@ static int find_slot_from_contactid(struct mt_device *td)
!td->slots[i].touch_state)
return i;
}
- return -1;
/* should not occurs. If this happens that means
* that the device sent more touches that it says
* in the report descriptor. It is ignored then. */
+ return -1;
}

struct mt_class mt_classes[] = {
- { 0, 0, 0, 10 }, /* MT_CLS_DEFAULT */
- { MT_QUIRK_SLOT_IS_CONTACTID, 0, 0, 2 }, /* MT_CLS_DUAL1 */
- { MT_QUIRK_SLOT_IS_CONTACTNUMBER, 0, 0, 10 }, /* MT_CLS_DUAL2 */
- { MT_QUIRK_CYPRESS | MT_QUIRK_NOT_SEEN_MEANS_UP, 0, 0, 10 }, /*
MT_CLS_CYPRESS */
+ { .name = MT_CLS_DEFAULT,
+ .quirks = MT_QUIRK_VALID_IS_INRANGE,
+ .maxcontacts = 10 },
+ { .name = MT_CLS_DUAL1,
+ .quirks = MT_QUIRK_VALID_IS_INRANGE |
+ MT_QUIRK_SLOT_IS_CONTACTID,
+ .maxcontacts = 2 },
+ { .name = MT_CLS_DUAL2,
+ .quirks = MT_QUIRK_VALID_IS_INRANGE |
+ MT_QUIRK_SLOT_IS_CONTACTNUMBER,
+ .maxcontacts = 2 },
+ { .name = MT_CLS_CYPRESS,
+ .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
+ MT_QUIRK_CYPRESS,
+ .maxcontacts = 10 },
+
+ { }
};

static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -192,7 +198,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct
hid_input *hi,
hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_TOUCH_MINOR);
field->logical_maximum = 1;
- field->logical_minimum = 1;
+ field->logical_minimum = 0;
set_abs(hi->input, ABS_MT_ORIENTATION, field, 0);
td->last_slot_field = usage->hid;
return 1;
@@ -237,16 +243,16 @@ static int mt_input_mapped(struct hid_device *hdev,
struct hid_input *hi,

static int mt_compute_slot(struct mt_device *td)
{
- struct mt_class *cls = td->mtclass;
+ __s32 quirks = td->mtclass->quirks;

- if (cls->quirks & MT_QUIRK_SLOT_IS_CONTACTID)
- return slot_is_contactid(td);
+ if (quirks & MT_QUIRK_SLOT_IS_CONTACTID)
+ return td->curdata.contactid;

- if (cls->quirks & MT_QUIRK_CYPRESS)
+ if (quirks & MT_QUIRK_CYPRESS)
return cypress_compute_slot(td);

- if (cls->quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
- return slot_is_contactnumber(td);
+ if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
+ return td->num_received;

return find_slot_from_contactid(td);
}
@@ -257,16 +263,12 @@ static int mt_compute_slot(struct mt_device *td)
*/
static void mt_complete_slot(struct mt_device *td)
{
+ td->curdata.seen_in_this_frame = true;
if (td->curvalid) {
- struct mt_slot *slot;
int slotnum = mt_compute_slot(td);

- if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts) {
- slot = td->slots + slotnum;
-
- memcpy(slot, &(td->curdata), sizeof(struct mt_slot));
- slot->seen_in_this_frame = true;
- }
+ if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts)
+ td->slots[slotnum] = td->curdata;
}
td->num_received++;
}
@@ -284,21 +286,19 @@ static void mt_emit_event(struct mt_device *td, struct
input_dev *input)
struct mt_slot *s = &(td->slots[i]);
if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
!s->seen_in_this_frame) {
- /*
- * this slot does not contain useful data,
- * notify its closure
- */
s->touch_state = false;
}

input_mt_slot(input, i);
input_mt_report_slot_state(input, MT_TOOL_FINGER,
s->touch_state);
- 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_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);
+ if (s->touch_state) {
+ 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_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);
+ }
s->seen_in_this_frame = false;

}
@@ -314,16 +314,22 @@ static int mt_event(struct hid_device *hid, struct
hid_field *field,
struct hid_usage *usage, __s32 value)
{
struct mt_device *td = hid_get_drvdata(hid);
+ __s32 quirks = td->mtclass->quirks;

if (hid->claimed & HID_CLAIMED_INPUT) {
switch (usage->hid) {
case HID_DG_INRANGE:
+ if (quirks & MT_QUIRK_VALID_IS_INRANGE)
+ td->curvalid = value;
break;
case HID_DG_TIPSWITCH:
- td->curvalid = value;
+ if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
+ td->curvalid = value;
td->curdata.touch_state = value;
break;
case HID_DG_CONFIDENCE:
+ if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
+ td->curvalid = value;
break;
case HID_DG_CONTACTID:
td->curdata.contactid = value;
@@ -345,26 +351,26 @@ static int mt_event(struct hid_device *hid, struct
hid_field *field,
break;
case HID_DG_CONTACTCOUNT:
/*
- * We must not overwrite the previous value (some
- * devices send one sequence splitted over several
- * messages)
+ * Includes multi-packet support where subsequent
+ * packets are sent with zero contactcount.
*/
if (value)
- td->num_expected = value - 1;
+ td->num_expected = value;
break;

default:
/* fallback to the generic hidinput handling */
return 0;
}
- }

- if (usage->hid == td->last_slot_field)
- mt_complete_slot(td);
+ if (usage->hid == td->last_slot_field)
+ mt_complete_slot(td);
+
+ if (field->index == td->last_field_index
+ && td->num_received >= td->num_expected)
+ mt_emit_event(td, field->hidinput->input);

- if (field->index == td->last_field_index
- && td->num_received > td->num_expected)
- mt_emit_event(td, field->hidinput->input);
+ }

/* we have handled the hidinput part, now remains hiddev */
if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
@@ -392,9 +398,16 @@ static void mt_set_input_mode(struct hid_device *hdev)

static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
- int ret;
+ int ret, i;
struct mt_device *td;
- struct mt_class *mtclass = mt_classes + id->driver_data;
+ struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
+
+ for (i = 0; mt_classes[i].name ; i++) {
+ if (id->driver_data == mt_classes[i].name) {
+ mtclass = &(mt_classes[i]);
+ break;
+ }
+ }

/* This allows the driver to correctly support devices
* that emit events over several HID messages.
@@ -417,7 +430,7 @@ static int mt_probe(struct hid_device *hdev, const struct
hid_device_id *id)
goto fail;

ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
- if (ret != 0)
+ if (ret)
goto fail;

mt_set_input_mode(hdev);

or the older version of the above module

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index d9f133a..bdb4532 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -292,6 +292,7 @@ config HID_MULTITOUCH

Say Y here if you have one of the following devices:
- PixCir touchscreen
+ - Cypress TrueTouch

config HID_NTRIG
tristate "N-Trig touch screen"
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4acd540..a94acb4 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1299,6 +1299,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ 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) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 0dd4bac..e4b1815 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -181,6 +181,7 @@
#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
#define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1
+#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001

#define USB_VENDOR_ID_DEALEXTREAME 0x10c5
#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 3b05dfe..7af9f71 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -32,6 +32,7 @@ MODULE_LICENSE("GPL");
/* quirks to control the device */
#define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0)
#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1)
+#define MT_QUIRK_CYPRESS (1 << 2)

struct mt_slot {
__s32 x, y, p, w, h;
@@ -62,6 +63,7 @@ struct mt_class {
/* classes of device behavior */
#define MT_CLS_DEFAULT 0
#define MT_CLS_DUAL1 1
+#define MT_CLS_CYPRESS 2

/*
* these device-dependent functions determine what slot corresponds
@@ -73,6 +75,14 @@ static int slot_is_contactid(struct mt_device *td)
return td->curdata.contactid;
}

+static int cypress_compute_slot(struct mt_device *td)
+{
+ if (td->curdata.contactid != 0 || td->num_received == 0)
+ return td->curdata.contactid;
+ else
+ return -1;
+}
+
static int find_slot_from_contactid(struct mt_device *td)
{
int i;
@@ -95,6 +105,7 @@ static int find_slot_from_contactid(struct mt_device *td)
struct mt_class mt_classes[] = {
{ 0, 0, 0, 10 }, /* MT_CLS_DEFAULT */
{ MT_QUIRK_SLOT_IS_CONTACTID, 0, 0, 2 }, /* MT_CLS_DUAL1 */
+ { MT_QUIRK_CYPRESS | MT_QUIRK_NOT_SEEN_MEANS_UP, 0, 0, 10 }, /*
MT_CLS_CYPRESS */
};

static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -223,6 +234,9 @@ static int mt_compute_slot(struct mt_device *td)
if (cls->quirks & MT_QUIRK_SLOT_IS_CONTACTID)
return slot_is_contactid(td);

+ if (cls->quirks & MT_QUIRK_CYPRESS)
+ return cypress_compute_slot(td);
+
return find_slot_from_contactid(td);
}

@@ -422,6 +436,11 @@ static void mt_remove(struct hid_device *hdev)

static const struct hid_device_id mt_devices[] = {

+ /* Cypress panel */
+ { .driver_data = MT_CLS_CYPRESS,
+ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
+ USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
+
/* PixCir-based panels */
{ .driver_data = MT_CLS_DUAL1,
HID_USB_DEVICE(USB_VENDOR_ID_HANVON,

anything usefull?