HID: add support for 3M multitouch 22" display
authorStephane Chatty <chatty@lii-enac.fr>
Sun, 11 Apr 2010 12:51:24 +0000 (14:51 +0200)
committerJiri Kosina <jkosina@suse.cz>
Sun, 11 Apr 2010 18:34:50 +0000 (20:34 +0200)
Now support the 22" display and its updated firmware, including touch
width and height.

The number of touches can now go up to 60, and our single touch emulation
will fail when there are more than 6-7 touches; further work is needed on
this.

Signed-off-by: Stephane Chatty <chatty@enac.fr>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/hid-3m-pct.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h

index 2370aefc86b2f6371bfca1355b2f474b2a7e00e1..883fd1af3c4c036bdfe6589749ac42be571c9a72 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  HID driver for 3M PCT multitouch panels
  *
- *  Copyright (c) 2009 Stephane Chatty <chatty@enac.fr>
+ *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
  *
  */
 
@@ -24,7 +24,7 @@ MODULE_LICENSE("GPL");
 #include "hid-ids.h"
 
 struct mmm_finger {
-       __s32 x, y;
+       __s32 x, y, w, h;
        __u8 rank;
        bool touch, valid;
 };
@@ -81,7 +81,18 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi,
                        /* 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_CONTACTID:
+                       field->logical_maximum = 59;
                        hid_map_usage(hi, usage, bit, max,
                                        EV_ABS, ABS_MT_TRACKING_ID);
                        return 1;
@@ -127,9 +138,15 @@ static void mmm_filter_event(struct mmm_data *md, struct input_dev *input)
                        /* this finger is just placeholder data, ignore */
                } else if (f->touch) {
                        /* this finger is on the screen */
+                       int wide = (f->w > f->h);
                        input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i);
                        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,
+                                               wide ? f->w : f->h);
+                       input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR,
+                                               wide ? f->h : f->w);
                        input_mt_sync(input);
                        /*
                         * touchscreen emulation: maintain the age rank
@@ -196,6 +213,14 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field,
                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:
                        if (md->valid) {
                                md->curid = value;
@@ -254,6 +279,7 @@ static void mmm_remove(struct hid_device *hdev)
 
 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);
@@ -286,5 +312,4 @@ static void __exit mmm_exit(void)
 
 module_init(mmm_init);
 module_exit(mmm_exit);
-MODULE_LICENSE("GPL");
 
index 7396f47c79db2c1f235ff68e3776e28eb093140d..9f92f629d44803ad69e78ea0f578a8d3f8b2a9c9 100644 (file)
@@ -1251,6 +1251,7 @@ EXPORT_SYMBOL_GPL(hid_disconnect);
 /* a list of devices for which there is a specialized driver on HID bus */
 static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
index 72c05f90553c7ec84351a34acf2ff6fc3ca10dbc..e1b4ce4eeb6e8f3dd647f8ae11d5580df7dd3cc7 100644 (file)
@@ -20,6 +20,7 @@
 
 #define USB_VENDOR_ID_3M               0x0596
 #define USB_DEVICE_ID_3M1968           0x0500
+#define USB_DEVICE_ID_3M2256           0x0502
 
 #define USB_VENDOR_ID_A4TECH           0x09da
 #define USB_DEVICE_ID_A4TECH_WCP32PU   0x0006