diff options
| -rw-r--r-- | drivers/hid/hid-ids.h | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-sensor-hub.c | 45 |
2 files changed, 49 insertions, 0 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f9304cb37154..fe9cd9df7011 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -445,6 +445,10 @@ | |||
| 445 | #define USB_VENDOR_ID_ILITEK 0x222a | 445 | #define USB_VENDOR_ID_ILITEK 0x222a |
| 446 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 | 446 | #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 |
| 447 | 447 | ||
| 448 | #define USB_VENDOR_ID_INTEL_0 0x8086 | ||
| 449 | #define USB_VENDOR_ID_INTEL_1 0x8087 | ||
| 450 | #define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa | ||
| 451 | |||
| 448 | #define USB_VENDOR_ID_ION 0x15e4 | 452 | #define USB_VENDOR_ID_ION 0x15e4 |
| 449 | #define USB_DEVICE_ID_ICADE 0x0132 | 453 | #define USB_DEVICE_ID_ICADE 0x0132 |
| 450 | 454 | ||
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 8fab82829f8b..46f4480035bc 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
| @@ -26,6 +26,8 @@ | |||
| 26 | #include <linux/hid-sensor-hub.h> | 26 | #include <linux/hid-sensor-hub.h> |
| 27 | #include "hid-ids.h" | 27 | #include "hid-ids.h" |
| 28 | 28 | ||
| 29 | #define HID_SENSOR_HUB_ENUM_QUIRK 0x01 | ||
| 30 | |||
| 29 | /** | 31 | /** |
| 30 | * struct sensor_hub_pending - Synchronous read pending information | 32 | * struct sensor_hub_pending - Synchronous read pending information |
| 31 | * @status: Pending status true/false. | 33 | * @status: Pending status true/false. |
| @@ -64,6 +66,7 @@ struct sensor_hub_data { | |||
| 64 | spinlock_t dyn_callback_lock; | 66 | spinlock_t dyn_callback_lock; |
| 65 | struct mfd_cell *hid_sensor_hub_client_devs; | 67 | struct mfd_cell *hid_sensor_hub_client_devs; |
| 66 | int hid_sensor_client_cnt; | 68 | int hid_sensor_client_cnt; |
| 69 | unsigned long quirks; | ||
| 67 | }; | 70 | }; |
| 68 | 71 | ||
| 69 | /** | 72 | /** |
| @@ -497,6 +500,40 @@ void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev) | |||
| 497 | } | 500 | } |
| 498 | EXPORT_SYMBOL_GPL(sensor_hub_device_close); | 501 | EXPORT_SYMBOL_GPL(sensor_hub_device_close); |
| 499 | 502 | ||
| 503 | static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc, | ||
| 504 | unsigned int *rsize) | ||
| 505 | { | ||
| 506 | int index; | ||
| 507 | struct sensor_hub_data *sd = hid_get_drvdata(hdev); | ||
| 508 | unsigned char report_block[] = { | ||
| 509 | 0x0a, 0x16, 0x03, 0x15, 0x00, 0x25, 0x05}; | ||
| 510 | unsigned char power_block[] = { | ||
| 511 | 0x0a, 0x19, 0x03, 0x15, 0x00, 0x25, 0x05}; | ||
| 512 | |||
| 513 | if (!(sd->quirks & HID_SENSOR_HUB_ENUM_QUIRK)) { | ||
| 514 | hid_dbg(hdev, "No Enum quirks\n"); | ||
| 515 | return rdesc; | ||
| 516 | } | ||
| 517 | |||
| 518 | /* Looks for power and report state usage id and force to 1 */ | ||
| 519 | for (index = 0; index < *rsize; ++index) { | ||
| 520 | if (((*rsize - index) > sizeof(report_block)) && | ||
| 521 | !memcmp(&rdesc[index], report_block, | ||
| 522 | sizeof(report_block))) { | ||
| 523 | rdesc[index + 4] = 0x01; | ||
| 524 | index += sizeof(report_block); | ||
| 525 | } | ||
| 526 | if (((*rsize - index) > sizeof(power_block)) && | ||
| 527 | !memcmp(&rdesc[index], power_block, | ||
| 528 | sizeof(power_block))) { | ||
| 529 | rdesc[index + 4] = 0x01; | ||
| 530 | index += sizeof(power_block); | ||
| 531 | } | ||
| 532 | } | ||
| 533 | |||
| 534 | return rdesc; | ||
| 535 | } | ||
| 536 | |||
| 500 | static int sensor_hub_probe(struct hid_device *hdev, | 537 | static int sensor_hub_probe(struct hid_device *hdev, |
| 501 | const struct hid_device_id *id) | 538 | const struct hid_device_id *id) |
| 502 | { | 539 | { |
| @@ -520,6 +557,7 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 520 | return -ENOMEM; | 557 | return -ENOMEM; |
| 521 | } | 558 | } |
| 522 | hid_set_drvdata(hdev, sd); | 559 | hid_set_drvdata(hdev, sd); |
| 560 | sd->quirks = id->driver_data; | ||
| 523 | sd->hsdev->hdev = hdev; | 561 | sd->hsdev->hdev = hdev; |
| 524 | sd->hsdev->vendor_id = hdev->vendor; | 562 | sd->hsdev->vendor_id = hdev->vendor; |
| 525 | sd->hsdev->product_id = hdev->product; | 563 | sd->hsdev->product_id = hdev->product; |
| @@ -621,6 +659,12 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 621 | } | 659 | } |
| 622 | 660 | ||
| 623 | static const struct hid_device_id sensor_hub_devices[] = { | 661 | static const struct hid_device_id sensor_hub_devices[] = { |
| 662 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0, | ||
| 663 | USB_DEVICE_ID_INTEL_HID_SENSOR), | ||
| 664 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
| 665 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, | ||
| 666 | USB_DEVICE_ID_INTEL_HID_SENSOR), | ||
| 667 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
| 624 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, | 668 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
| 625 | HID_ANY_ID) }, | 669 | HID_ANY_ID) }, |
| 626 | { } | 670 | { } |
| @@ -633,6 +677,7 @@ static struct hid_driver sensor_hub_driver = { | |||
| 633 | .probe = sensor_hub_probe, | 677 | .probe = sensor_hub_probe, |
| 634 | .remove = sensor_hub_remove, | 678 | .remove = sensor_hub_remove, |
| 635 | .raw_event = sensor_hub_raw_event, | 679 | .raw_event = sensor_hub_raw_event, |
| 680 | .report_fixup = sensor_hub_report_fixup, | ||
| 636 | #ifdef CONFIG_PM | 681 | #ifdef CONFIG_PM |
| 637 | .suspend = sensor_hub_suspend, | 682 | .suspend = sensor_hub_suspend, |
| 638 | .resume = sensor_hub_resume, | 683 | .resume = sensor_hub_resume, |
