diff options
| author | Brendan McGrath <redmcg@redmandi.dyndns.org> | 2016-11-29 02:59:25 -0500 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2016-11-29 10:14:32 -0500 |
| commit | 9ce12d8be12c94334634dd57050444910415e45f (patch) | |
| tree | 565ba7196031833b8d7e4b657b8f42fcd0e3ab74 | |
| parent | e2b6535d47ce223e327de053b804d2e572a98bbc (diff) | |
HID: asus: Add i2c touchpad support
Update the hid-asus module to add multitouch support for the Asus i2c touchpad.
This patch aims to resolve the issue raised here:
https://bugzilla.kernel.org/show_bug.cgi?id=120181
The issue is in relation to an Asus touchpad device which currently does not
have multitouch support.
The device currently falls through to the hid-generic driver which
treats the device as a mouse.
This patch aims to add the multitouch support.
[jkosina@suse.cz: move most of the 'patch comment' into actual changelog]
[jkosina@suse.cz: drop hunk that changes ->name of the driver]
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Brendan McGrath <redmcg@redmandi.dyndns.org>
Signed-off-by: Victor Vlasenko <victor.vlasenko@sysgears.com>
Signed-off-by: Frederik Wenigwieser <frederik.wenigwieser@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
| -rw-r--r-- | drivers/hid/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-asus.c | 299 | ||||
| -rw-r--r-- | drivers/hid/hid-core.c | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-ids.h | 1 |
4 files changed, 296 insertions, 7 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index cd4599c0523b..f8f251c20e2d 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
| @@ -138,7 +138,7 @@ config HID_ASUS | |||
| 138 | tristate "Asus" | 138 | tristate "Asus" |
| 139 | depends on I2C_HID | 139 | depends on I2C_HID |
| 140 | ---help--- | 140 | ---help--- |
| 141 | Support for Asus notebook built-in keyboard via i2c. | 141 | Support for Asus notebook built-in keyboard and touchpad via i2c. |
| 142 | 142 | ||
| 143 | Supported devices: | 143 | Supported devices: |
| 144 | - EeeBook X205TA | 144 | - EeeBook X205TA |
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 7a811ec4f2e1..d40ed9fdf68d 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c | |||
| @@ -11,6 +11,12 @@ | |||
| 11 | * This module based on hid-ortek by | 11 | * This module based on hid-ortek by |
| 12 | * Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com> | 12 | * Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com> |
| 13 | * Copyright (c) 2011 Jiri Kosina | 13 | * Copyright (c) 2011 Jiri Kosina |
| 14 | * | ||
| 15 | * This module has been updated to add support for Asus i2c touchpad. | ||
| 16 | * | ||
| 17 | * Copyright (c) 2016 Brendan McGrath <redmcg@redmandi.dyndns.org> | ||
| 18 | * Copyright (c) 2016 Victor Vlasenko <victor.vlasenko@sysgears.com> | ||
| 19 | * Copyright (c) 2016 Frederik Wenigwieser <frederik.wenigwieser@gmail.com> | ||
| 14 | */ | 20 | */ |
| 15 | 21 | ||
| 16 | /* | 22 | /* |
| @@ -20,16 +26,287 @@ | |||
| 20 | * any later version. | 26 | * any later version. |
| 21 | */ | 27 | */ |
| 22 | 28 | ||
| 23 | #include <linux/device.h> | ||
| 24 | #include <linux/hid.h> | 29 | #include <linux/hid.h> |
| 25 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/input/mt.h> | ||
| 26 | 32 | ||
| 27 | #include "hid-ids.h" | 33 | #include "hid-ids.h" |
| 28 | 34 | ||
| 35 | MODULE_AUTHOR("Yusuke Fujimaki <usk.fujimaki@gmail.com>"); | ||
| 36 | MODULE_AUTHOR("Brendan McGrath <redmcg@redmandi.dyndns.org>"); | ||
| 37 | MODULE_AUTHOR("Victor Vlasenko <victor.vlasenko@sysgears.com>"); | ||
| 38 | MODULE_AUTHOR("Frederik Wenigwieser <frederik.wenigwieser@gmail.com>"); | ||
| 39 | MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); | ||
| 40 | |||
| 41 | #define FEATURE_REPORT_ID 0x0d | ||
| 42 | #define INPUT_REPORT_ID 0x5d | ||
| 43 | |||
| 44 | #define INPUT_REPORT_SIZE 28 | ||
| 45 | |||
| 46 | #define MAX_CONTACTS 5 | ||
| 47 | |||
| 48 | #define MAX_X 2794 | ||
| 49 | #define MAX_Y 1758 | ||
| 50 | #define MAX_TOUCH_MAJOR 8 | ||
| 51 | #define MAX_PRESSURE 128 | ||
| 52 | |||
| 53 | #define CONTACT_DATA_SIZE 5 | ||
| 54 | |||
| 55 | #define BTN_LEFT_MASK 0x01 | ||
| 56 | #define CONTACT_TOOL_TYPE_MASK 0x80 | ||
| 57 | #define CONTACT_X_MSB_MASK 0xf0 | ||
| 58 | #define CONTACT_Y_MSB_MASK 0x0f | ||
| 59 | #define CONTACT_TOUCH_MAJOR_MASK 0x07 | ||
| 60 | #define CONTACT_PRESSURE_MASK 0x7f | ||
| 61 | |||
| 62 | #define QUIRK_FIX_NOTEBOOK_REPORT BIT(0) | ||
| 63 | #define QUIRK_NO_INIT_REPORTS BIT(1) | ||
| 64 | #define QUIRK_SKIP_INPUT_MAPPING BIT(2) | ||
| 65 | #define QUIRK_IS_MULTITOUCH BIT(3) | ||
| 66 | |||
| 67 | #define NOTEBOOK_QUIRKS QUIRK_FIX_NOTEBOOK_REPORT | ||
| 68 | #define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \ | ||
| 69 | QUIRK_SKIP_INPUT_MAPPING | \ | ||
| 70 | QUIRK_IS_MULTITOUCH) | ||
| 71 | |||
| 72 | #define TRKID_SGN ((TRKID_MAX + 1) >> 1) | ||
| 73 | |||
| 74 | struct asus_drvdata { | ||
| 75 | unsigned long quirks; | ||
| 76 | struct input_dev *input; | ||
| 77 | }; | ||
| 78 | |||
| 79 | static void asus_report_contact_down(struct input_dev *input, | ||
| 80 | int toolType, u8 *data) | ||
| 81 | { | ||
| 82 | int touch_major, pressure; | ||
| 83 | int x = (data[0] & CONTACT_X_MSB_MASK) << 4 | data[1]; | ||
| 84 | int y = MAX_Y - ((data[0] & CONTACT_Y_MSB_MASK) << 8 | data[2]); | ||
| 85 | |||
| 86 | if (toolType == MT_TOOL_PALM) { | ||
| 87 | touch_major = MAX_TOUCH_MAJOR; | ||
| 88 | pressure = MAX_PRESSURE; | ||
| 89 | } else { | ||
| 90 | touch_major = (data[3] >> 4) & CONTACT_TOUCH_MAJOR_MASK; | ||
| 91 | pressure = data[4] & CONTACT_PRESSURE_MASK; | ||
| 92 | } | ||
| 93 | |||
| 94 | input_report_abs(input, ABS_MT_POSITION_X, x); | ||
| 95 | input_report_abs(input, ABS_MT_POSITION_Y, y); | ||
| 96 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major); | ||
| 97 | input_report_abs(input, ABS_MT_PRESSURE, pressure); | ||
| 98 | } | ||
| 99 | |||
| 100 | /* Required for Synaptics Palm Detection */ | ||
| 101 | static void asus_report_tool_width(struct input_dev *input) | ||
| 102 | { | ||
| 103 | struct input_mt *mt = input->mt; | ||
| 104 | struct input_mt_slot *oldest; | ||
| 105 | int oldid, count, i; | ||
| 106 | |||
| 107 | oldest = NULL; | ||
| 108 | oldid = mt->trkid; | ||
| 109 | count = 0; | ||
| 110 | |||
| 111 | for (i = 0; i < mt->num_slots; ++i) { | ||
| 112 | struct input_mt_slot *ps = &mt->slots[i]; | ||
| 113 | int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID); | ||
| 114 | |||
| 115 | if (id < 0) | ||
| 116 | continue; | ||
| 117 | if ((id - oldid) & TRKID_SGN) { | ||
| 118 | oldest = ps; | ||
| 119 | oldid = id; | ||
| 120 | } | ||
| 121 | count++; | ||
| 122 | } | ||
| 123 | |||
| 124 | if (oldest) { | ||
| 125 | input_report_abs(input, ABS_TOOL_WIDTH, | ||
| 126 | input_mt_get_value(oldest, ABS_MT_TOUCH_MAJOR)); | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | static void asus_report_input(struct input_dev *input, u8 *data) | ||
| 131 | { | ||
| 132 | int i; | ||
| 133 | u8 *contactData = data + 2; | ||
| 134 | |||
| 135 | for (i = 0; i < MAX_CONTACTS; i++) { | ||
| 136 | bool down = !!(data[1] & BIT(i+3)); | ||
| 137 | int toolType = contactData[3] & CONTACT_TOOL_TYPE_MASK ? | ||
| 138 | MT_TOOL_PALM : MT_TOOL_FINGER; | ||
| 139 | |||
| 140 | input_mt_slot(input, i); | ||
| 141 | input_mt_report_slot_state(input, toolType, down); | ||
| 142 | |||
| 143 | if (down) { | ||
| 144 | asus_report_contact_down(input, toolType, contactData); | ||
| 145 | contactData += CONTACT_DATA_SIZE; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 149 | input_report_key(input, BTN_LEFT, data[1] & BTN_LEFT_MASK); | ||
| 150 | asus_report_tool_width(input); | ||
| 151 | |||
| 152 | input_mt_sync_frame(input); | ||
| 153 | input_sync(input); | ||
| 154 | } | ||
| 155 | |||
| 156 | static int asus_raw_event(struct hid_device *hdev, | ||
| 157 | struct hid_report *report, u8 *data, int size) | ||
| 158 | { | ||
| 159 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | ||
| 160 | |||
| 161 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH && | ||
| 162 | data[0] == INPUT_REPORT_ID && | ||
| 163 | size == INPUT_REPORT_SIZE) { | ||
| 164 | asus_report_input(drvdata->input, data); | ||
| 165 | return 1; | ||
| 166 | } | ||
| 167 | |||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) | ||
| 172 | { | ||
| 173 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | ||
| 174 | |||
| 175 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { | ||
| 176 | int ret; | ||
| 177 | struct input_dev *input = hi->input; | ||
| 178 | |||
| 179 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); | ||
| 180 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); | ||
| 181 | input_set_abs_params(input, ABS_TOOL_WIDTH, 0, MAX_TOUCH_MAJOR, 0, 0); | ||
| 182 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, MAX_TOUCH_MAJOR, 0, 0); | ||
| 183 | input_set_abs_params(input, ABS_MT_PRESSURE, 0, MAX_PRESSURE, 0, 0); | ||
| 184 | |||
| 185 | __set_bit(BTN_LEFT, input->keybit); | ||
| 186 | __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); | ||
| 187 | |||
| 188 | ret = input_mt_init_slots(input, MAX_CONTACTS, INPUT_MT_POINTER); | ||
| 189 | |||
| 190 | if (ret) { | ||
| 191 | hid_err(hdev, "Asus input mt init slots failed: %d\n", ret); | ||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | |||
| 195 | drvdata->input = input; | ||
| 196 | } | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int asus_input_mapping(struct hid_device *hdev, | ||
| 202 | struct hid_input *hi, struct hid_field *field, | ||
| 203 | struct hid_usage *usage, unsigned long **bit, | ||
| 204 | int *max) | ||
| 205 | { | ||
| 206 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | ||
| 207 | |||
| 208 | if (drvdata->quirks & QUIRK_SKIP_INPUT_MAPPING) { | ||
| 209 | /* Don't map anything from the HID report. | ||
| 210 | * We do it all manually in asus_input_configured | ||
| 211 | */ | ||
| 212 | return -1; | ||
| 213 | } | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } | ||
| 217 | |||
| 218 | static int asus_start_multitouch(struct hid_device *hdev) | ||
| 219 | { | ||
| 220 | int ret; | ||
| 221 | const unsigned char buf[] = { FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00 }; | ||
| 222 | unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL); | ||
| 223 | |||
| 224 | if (!dmabuf) { | ||
| 225 | ret = -ENOMEM; | ||
| 226 | hid_err(hdev, "Asus failed to alloc dma buf: %d\n", ret); | ||
| 227 | return ret; | ||
| 228 | } | ||
| 229 | |||
| 230 | ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf), | ||
| 231 | HID_FEATURE_REPORT, HID_REQ_SET_REPORT); | ||
| 232 | |||
| 233 | kfree(dmabuf); | ||
| 234 | |||
| 235 | if (ret != sizeof(buf)) { | ||
| 236 | hid_err(hdev, "Asus failed to start multitouch: %d\n", ret); | ||
| 237 | return ret; | ||
| 238 | } | ||
| 239 | |||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int __maybe_unused asus_reset_resume(struct hid_device *hdev) | ||
| 244 | { | ||
| 245 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | ||
| 246 | |||
| 247 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH) | ||
| 248 | return asus_start_multitouch(hdev); | ||
| 249 | |||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
| 254 | { | ||
| 255 | int ret; | ||
| 256 | struct asus_drvdata *drvdata; | ||
| 257 | |||
| 258 | drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); | ||
| 259 | if (drvdata == NULL) { | ||
| 260 | hid_err(hdev, "Can't alloc Asus descriptor\n"); | ||
| 261 | return -ENOMEM; | ||
| 262 | } | ||
| 263 | |||
| 264 | hid_set_drvdata(hdev, drvdata); | ||
| 265 | |||
| 266 | drvdata->quirks = id->driver_data; | ||
| 267 | |||
| 268 | if (drvdata->quirks & QUIRK_NO_INIT_REPORTS) | ||
| 269 | hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; | ||
| 270 | |||
| 271 | ret = hid_parse(hdev); | ||
| 272 | if (ret) { | ||
| 273 | hid_err(hdev, "Asus hid parse failed: %d\n", ret); | ||
| 274 | return ret; | ||
| 275 | } | ||
| 276 | |||
| 277 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 278 | if (ret) { | ||
| 279 | hid_err(hdev, "Asus hw start failed: %d\n", ret); | ||
| 280 | return ret; | ||
| 281 | } | ||
| 282 | |||
| 283 | if (!drvdata->input) { | ||
| 284 | hid_err(hdev, "Asus input not registered\n"); | ||
| 285 | ret = -ENOMEM; | ||
| 286 | goto err_stop_hw; | ||
| 287 | } | ||
| 288 | |||
| 289 | drvdata->input->name = "Asus TouchPad"; | ||
| 290 | |||
| 291 | if (drvdata->quirks & QUIRK_IS_MULTITOUCH) { | ||
| 292 | ret = asus_start_multitouch(hdev); | ||
| 293 | if (ret) | ||
| 294 | goto err_stop_hw; | ||
| 295 | } | ||
| 296 | |||
| 297 | return 0; | ||
| 298 | err_stop_hw: | ||
| 299 | hid_hw_stop(hdev); | ||
| 300 | return ret; | ||
| 301 | } | ||
| 302 | |||
| 29 | static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 303 | static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 30 | unsigned int *rsize) | 304 | unsigned int *rsize) |
| 31 | { | 305 | { |
| 32 | if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x65) { | 306 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); |
| 307 | |||
| 308 | if (drvdata->quirks & QUIRK_FIX_NOTEBOOK_REPORT && | ||
| 309 | *rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x65) { | ||
| 33 | hid_info(hdev, "Fixing up Asus notebook report descriptor\n"); | 310 | hid_info(hdev, "Fixing up Asus notebook report descriptor\n"); |
| 34 | rdesc[55] = 0xdd; | 311 | rdesc[55] = 0xdd; |
| 35 | } | 312 | } |
| @@ -37,15 +314,25 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 37 | } | 314 | } |
| 38 | 315 | ||
| 39 | static const struct hid_device_id asus_devices[] = { | 316 | static const struct hid_device_id asus_devices[] = { |
| 40 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, | 317 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, |
| 318 | USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), NOTEBOOK_QUIRKS}, | ||
| 319 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, | ||
| 320 | USB_DEVICE_ID_ASUSTEK_TOUCHPAD), TOUCHPAD_QUIRKS }, | ||
| 41 | { } | 321 | { } |
| 42 | }; | 322 | }; |
| 43 | MODULE_DEVICE_TABLE(hid, asus_devices); | 323 | MODULE_DEVICE_TABLE(hid, asus_devices); |
| 44 | 324 | ||
| 45 | static struct hid_driver asus_driver = { | 325 | static struct hid_driver asus_driver = { |
| 46 | .name = "asus", | 326 | .name = "asus", |
| 47 | .id_table = asus_devices, | 327 | .id_table = asus_devices, |
| 48 | .report_fixup = asus_report_fixup | 328 | .report_fixup = asus_report_fixup, |
| 329 | .probe = asus_probe, | ||
| 330 | .input_mapping = asus_input_mapping, | ||
| 331 | .input_configured = asus_input_configured, | ||
| 332 | #ifdef CONFIG_PM | ||
| 333 | .reset_resume = asus_reset_resume, | ||
| 334 | #endif | ||
| 335 | .raw_event = asus_raw_event | ||
| 49 | }; | 336 | }; |
| 50 | module_hid_driver(asus_driver); | 337 | module_hid_driver(asus_driver); |
| 51 | 338 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 2b89c701076f..689cd9cf5025 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1857,6 +1857,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
| 1857 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1857 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 1858 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1858 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 1859 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, | 1859 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, |
| 1860 | { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_TOUCHPAD) }, | ||
| 1860 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | 1861 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
| 1861 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1862 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
| 1862 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, | 1863 | { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 575aa65436d1..b531bd408f93 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -171,6 +171,7 @@ | |||
| 171 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 | 171 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 |
| 172 | #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b | 172 | #define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b |
| 173 | #define USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD 0x8585 | 173 | #define USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD 0x8585 |
| 174 | #define USB_DEVICE_ID_ASUSTEK_TOUCHPAD 0x0101 | ||
| 174 | 175 | ||
| 175 | #define USB_VENDOR_ID_ATEN 0x0557 | 176 | #define USB_VENDOR_ID_ATEN 0x0557 |
| 176 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 | 177 | #define USB_DEVICE_ID_ATEN_UC100KM 0x2004 |
