aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Paulo Rechi Vita <jprvita@gmail.com>2017-07-24 17:22:25 -0400
committerJiri Kosina <jkosina@suse.cz>2017-08-03 05:20:17 -0400
commit957b8dffa4e3d191f0f1571d006d0e520790dcb9 (patch)
tree8d3c78de672685ec761c06c812214b5be5cee752
parent1fbf74efeca1bddbab5375a90217563060fd1904 (diff)
HID: multitouch: Support Asus T304UA media keys
The Asus T304UA convertible sports a magnetic detachable keyboard with touchpad, which is connected over USB. Most of the keyboard hotkeys are exposed through the same USB interface as the touchpad, defined in the report descriptor as follows: 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined 0xFF31) 0x09, 0x76, // Usage (0x76) 0xA1, 0x01, // Collection (Application) 0x05, 0xFF, // Usage Page (Reserved 0xFF) 0x85, 0x5A, // Report ID (90) 0x19, 0x00, // Usage Minimum (0x00) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x0F, // Report Count (15) 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0x05, 0xFF, // Usage Page (Reserved 0xFF) 0x85, 0x5A, // Report ID (90) 0x19, 0x00, // Usage Minimum (0x00) 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x02, // Report Count (2) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0xC0, // End Collection This UsagePage is declared as a variable, but we need to treat it as an array to be able to map each Usage we care about to its corresponding input key. Signed-off-by: João Paulo Rechi Vita <jprvita@endlessm.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-multitouch.c44
-rw-r--r--include/linux/hid.h2
3 files changed, 46 insertions, 1 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index c9ba4c6db74c..90fcf7457908 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -176,6 +176,7 @@
176#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 176#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726
177#define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b 177#define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b
178#define USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD 0x17e0 178#define USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD 0x17e0
179#define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a
179#define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585 180#define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585
180#define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101 181#define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD 0x0101
181#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854 182#define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 152d33120a55..6b3de7b01571 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -72,6 +72,7 @@ MODULE_LICENSE("GPL");
72#define MT_QUIRK_FIX_CONST_CONTACT_ID BIT(14) 72#define MT_QUIRK_FIX_CONST_CONTACT_ID BIT(14)
73#define MT_QUIRK_TOUCH_SIZE_SCALING BIT(15) 73#define MT_QUIRK_TOUCH_SIZE_SCALING BIT(15)
74#define MT_QUIRK_STICKY_FINGERS BIT(16) 74#define MT_QUIRK_STICKY_FINGERS BIT(16)
75#define MT_QUIRK_ASUS_CUSTOM_UP BIT(17)
75 76
76#define MT_INPUTMODE_TOUCHSCREEN 0x02 77#define MT_INPUTMODE_TOUCHSCREEN 0x02
77#define MT_INPUTMODE_TOUCHPAD 0x03 78#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -169,6 +170,7 @@ static void mt_post_parse(struct mt_device *td);
169#define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108 170#define MT_CLS_GENERALTOUCH_TWOFINGERS 0x0108
170#define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109 171#define MT_CLS_GENERALTOUCH_PWT_TENFINGERS 0x0109
171#define MT_CLS_LG 0x010a 172#define MT_CLS_LG 0x010a
173#define MT_CLS_ASUS 0x010b
172#define MT_CLS_VTL 0x0110 174#define MT_CLS_VTL 0x0110
173#define MT_CLS_GOOGLE 0x0111 175#define MT_CLS_GOOGLE 0x0111
174 176
@@ -290,6 +292,10 @@ static struct mt_class mt_classes[] = {
290 MT_QUIRK_IGNORE_DUPLICATES | 292 MT_QUIRK_IGNORE_DUPLICATES |
291 MT_QUIRK_HOVERING | 293 MT_QUIRK_HOVERING |
292 MT_QUIRK_CONTACT_CNT_ACCURATE }, 294 MT_QUIRK_CONTACT_CNT_ACCURATE },
295 { .name = MT_CLS_ASUS,
296 .quirks = MT_QUIRK_ALWAYS_VALID |
297 MT_QUIRK_CONTACT_CNT_ACCURATE |
298 MT_QUIRK_ASUS_CUSTOM_UP },
293 { .name = MT_CLS_VTL, 299 { .name = MT_CLS_VTL,
294 .quirks = MT_QUIRK_ALWAYS_VALID | 300 .quirks = MT_QUIRK_ALWAYS_VALID |
295 MT_QUIRK_CONTACT_CNT_ACCURATE | 301 MT_QUIRK_CONTACT_CNT_ACCURATE |
@@ -905,6 +911,8 @@ static int mt_touch_input_configured(struct hid_device *hdev,
905 return 0; 911 return 0;
906} 912}
907 913
914#define mt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, \
915 max, EV_KEY, (c))
908static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 916static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
909 struct hid_field *field, struct hid_usage *usage, 917 struct hid_field *field, struct hid_usage *usage,
910 unsigned long **bit, int *max) 918 unsigned long **bit, int *max)
@@ -923,10 +931,35 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
923 field->application != HID_DG_TOUCHPAD && 931 field->application != HID_DG_TOUCHPAD &&
924 field->application != HID_GD_KEYBOARD && 932 field->application != HID_GD_KEYBOARD &&
925 field->application != HID_CP_CONSUMER_CONTROL && 933 field->application != HID_CP_CONSUMER_CONTROL &&
926 field->application != HID_GD_WIRELESS_RADIO_CTLS) 934 field->application != HID_GD_WIRELESS_RADIO_CTLS &&
935 !(field->application == HID_VD_ASUS_CUSTOM_MEDIA_KEYS &&
936 td->mtclass.quirks & MT_QUIRK_ASUS_CUSTOM_UP))
927 return -1; 937 return -1;
928 938
929 /* 939 /*
940 * Some Asus keyboard+touchpad devices have the hotkeys defined in the
941 * touchpad report descriptor. We need to treat these as an array to
942 * map usages to input keys.
943 */
944 if (field->application == 0xff310076 &&
945 td->mtclass.quirks & MT_QUIRK_ASUS_CUSTOM_UP &&
946 (usage->hid & HID_USAGE_PAGE) == HID_UP_CUSTOM) {
947 set_bit(EV_REP, hi->input->evbit);
948 if (field->flags & HID_MAIN_ITEM_VARIABLE)
949 field->flags &= ~HID_MAIN_ITEM_VARIABLE;
950 switch (usage->hid & HID_USAGE) {
951 case 0x10: mt_map_key_clear(KEY_BRIGHTNESSDOWN); break;
952 case 0x20: mt_map_key_clear(KEY_BRIGHTNESSUP); break;
953 case 0x35: mt_map_key_clear(KEY_DISPLAY_OFF); break;
954 case 0x6b: mt_map_key_clear(KEY_F21); break;
955 case 0x6c: mt_map_key_clear(KEY_SLEEP); break;
956 default:
957 return -1;
958 }
959 return 1;
960 }
961
962 /*
930 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN" 963 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
931 * for the stylus. 964 * for the stylus.
932 * The check for mt_report_id ensures we don't process 965 * The check for mt_report_id ensures we don't process
@@ -1137,6 +1170,9 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
1137 case HID_GD_WIRELESS_RADIO_CTLS: 1170 case HID_GD_WIRELESS_RADIO_CTLS:
1138 suffix = "Wireless Radio Control"; 1171 suffix = "Wireless Radio Control";
1139 break; 1172 break;
1173 case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
1174 suffix = "Custom Media Keys";
1175 break;
1140 default: 1176 default:
1141 suffix = "UNKNOWN"; 1177 suffix = "UNKNOWN";
1142 break; 1178 break;
@@ -1388,6 +1424,12 @@ static const struct hid_device_id mt_devices[] = {
1388 MT_USB_DEVICE(USB_VENDOR_ID_ANTON, 1424 MT_USB_DEVICE(USB_VENDOR_ID_ANTON,
1389 USB_DEVICE_ID_ANTON_TOUCH_PAD) }, 1425 USB_DEVICE_ID_ANTON_TOUCH_PAD) },
1390 1426
1427 /* Asus T304UA */
1428 { .driver_data = MT_CLS_ASUS,
1429 HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
1430 USB_VENDOR_ID_ASUSTEK,
1431 USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD) },
1432
1391 /* Atmel panels */ 1433 /* Atmel panels */
1392 { .driver_data = MT_CLS_SERIAL, 1434 { .driver_data = MT_CLS_SERIAL,
1393 MT_USB_DEVICE(USB_VENDOR_ID_ATMEL, 1435 MT_USB_DEVICE(USB_VENDOR_ID_ATMEL,
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 5006f9b5d837..a08e6b15d98d 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -173,6 +173,7 @@ struct hid_item {
173#define HID_UP_LOGIVENDOR3 0xff430000 173#define HID_UP_LOGIVENDOR3 0xff430000
174#define HID_UP_LNVENDOR 0xffa00000 174#define HID_UP_LNVENDOR 0xffa00000
175#define HID_UP_SENSOR 0x00200000 175#define HID_UP_SENSOR 0x00200000
176#define HID_UP_ASUSVENDOR 0xff310000
176 177
177#define HID_USAGE 0x0000ffff 178#define HID_USAGE 0x0000ffff
178 179
@@ -292,6 +293,7 @@ struct hid_item {
292#define HID_DG_BARRELSWITCH2 0x000d005a 293#define HID_DG_BARRELSWITCH2 0x000d005a
293#define HID_DG_TOOLSERIALNUMBER 0x000d005b 294#define HID_DG_TOOLSERIALNUMBER 0x000d005b
294 295
296#define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076
295/* 297/*
296 * HID report types --- Ouch! HID spec says 1 2 3! 298 * HID report types --- Ouch! HID spec says 1 2 3!
297 */ 299 */