diff options
Diffstat (limited to 'drivers/hid/hid-sensor-hub.c')
-rw-r--r-- | drivers/hid/hid-sensor-hub.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 8fab82829f8b..9c22e14c57f0 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,15 @@ 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}, | ||
668 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, | ||
669 | USB_DEVICE_ID_STM_HID_SENSOR), | ||
670 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
624 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, | 671 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
625 | HID_ANY_ID) }, | 672 | HID_ANY_ID) }, |
626 | { } | 673 | { } |
@@ -633,6 +680,7 @@ static struct hid_driver sensor_hub_driver = { | |||
633 | .probe = sensor_hub_probe, | 680 | .probe = sensor_hub_probe, |
634 | .remove = sensor_hub_remove, | 681 | .remove = sensor_hub_remove, |
635 | .raw_event = sensor_hub_raw_event, | 682 | .raw_event = sensor_hub_raw_event, |
683 | .report_fixup = sensor_hub_report_fixup, | ||
636 | #ifdef CONFIG_PM | 684 | #ifdef CONFIG_PM |
637 | .suspend = sensor_hub_suspend, | 685 | .suspend = sensor_hub_suspend, |
638 | .resume = sensor_hub_resume, | 686 | .resume = sensor_hub_resume, |