aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2017-08-07 00:52:01 -0400
committerJiri Kosina <jkosina@suse.cz>2017-08-09 16:15:59 -0400
commitb0f847e16c1ea6ead5680cf58cade70918363315 (patch)
tree690755027b3329bac77c861364d10e6c83ace641
parenta9d0683e0b62b46c7a5d0ebd8f642d8f9a4b7b32 (diff)
HID: hid-sensor-hub: Force logical minimum to 1 for power and report state
In the reference HID sensor hub firmware all Named array enums were 0-based. There is no description of the default base of enums in HID sensor hub specification as logical minimum should have set this base value. Every sensor hub implemented enum as 1-based, without explicitly setting logical minimum to 1, because of the implementation by one of the major OS vendor. In Linux we used logical minimum to decide the enum base. Some sensor hub FWs already changed logical minimum from 0 to 1. We hoped that every other vendor will follow. But that didn't happen and we had to fix the report header for every sensor hub to change logical minimum to 1 by using .report_fixup() callback. So for every new sensor hub we had to modify source code by adding this quirk based on the vendor and device id. This is becoming a maintenance burden. This patch hardcodes the logical minimum of power and report state attributes to 1. In this way we can remove the existing quirks and also we don't have to add more quirks. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-sensor-hub.c94
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c3
2 files changed, 3 insertions, 94 deletions
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 4ef73374a8f9..25363fc571bc 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -579,54 +579,6 @@ void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
579} 579}
580EXPORT_SYMBOL_GPL(sensor_hub_device_close); 580EXPORT_SYMBOL_GPL(sensor_hub_device_close);
581 581
582static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc,
583 unsigned int *rsize)
584{
585 int index;
586 struct sensor_hub_data *sd = hid_get_drvdata(hdev);
587 unsigned char report_block[] = {
588 0x0a, 0x16, 0x03, 0x15, 0x00, 0x25, 0x05};
589 unsigned char power_block[] = {
590 0x0a, 0x19, 0x03, 0x15, 0x00, 0x25, 0x05};
591
592 if (!(sd->quirks & HID_SENSOR_HUB_ENUM_QUIRK)) {
593 hid_dbg(hdev, "No Enum quirks\n");
594 return rdesc;
595 }
596
597 /* Looks for power and report state usage id and force to 1 */
598 for (index = 0; index < *rsize; ++index) {
599 if (((*rsize - index) > sizeof(report_block)) &&
600 !memcmp(&rdesc[index], report_block,
601 sizeof(report_block))) {
602 rdesc[index + 4] = 0x01;
603 index += sizeof(report_block);
604 }
605 if (((*rsize - index) > sizeof(power_block)) &&
606 !memcmp(&rdesc[index], power_block,
607 sizeof(power_block))) {
608 rdesc[index + 4] = 0x01;
609 index += sizeof(power_block);
610 }
611 }
612
613 /* Checks if the report descriptor of Thinkpad Helix 2 has a logical
614 * minimum for magnetic flux axis greater than the maximum */
615 if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&
616 *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&
617 rdesc[915] == 0x81 && rdesc[916] == 0x08 &&
618 rdesc[917] == 0x00 && rdesc[918] == 0x27 &&
619 rdesc[921] == 0x07 && rdesc[922] == 0x00) {
620 /* Sets negative logical minimum for mag x, y and z */
621 rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;
622 rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;
623 rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;
624 rdesc[917] = rdesc[938] = rdesc[959] = 0xff;
625 }
626
627 return rdesc;
628}
629
630static int sensor_hub_probe(struct hid_device *hdev, 582static int sensor_hub_probe(struct hid_device *hdev,
631 const struct hid_device_id *id) 583 const struct hid_device_id *id)
632{ 584{
@@ -778,51 +730,6 @@ static void sensor_hub_remove(struct hid_device *hdev)
778} 730}
779 731
780static const struct hid_device_id sensor_hub_devices[] = { 732static const struct hid_device_id sensor_hub_devices[] = {
781 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
782 USB_DEVICE_ID_INTEL_HID_SENSOR_0),
783 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
784 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
785 USB_DEVICE_ID_INTEL_HID_SENSOR_0),
786 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
787 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
788 USB_DEVICE_ID_INTEL_HID_SENSOR_1),
789 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
790 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
791 USB_DEVICE_ID_MS_SURFACE_PRO_2),
792 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
793 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
794 USB_DEVICE_ID_MS_TOUCH_COVER_2),
795 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
796 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
797 USB_DEVICE_ID_MS_TYPE_COVER_2),
798 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
799 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROSOFT,
800 0x07bd), /* Microsoft Surface 3 */
801 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
802 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_MICROCHIP,
803 0x0f01), /* MM7150 */
804 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
805 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
806 USB_DEVICE_ID_STM_HID_SENSOR),
807 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
808 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
809 USB_DEVICE_ID_STM_HID_SENSOR_1),
810 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
811 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS,
812 USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA),
813 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
814 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE,
815 USB_DEVICE_ID_ITE_LENOVO_YOGA),
816 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
817 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE,
818 USB_DEVICE_ID_ITE_LENOVO_YOGA2),
819 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
820 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE,
821 USB_DEVICE_ID_ITE_LENOVO_YOGA900),
822 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
823 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
824 0x22D8),
825 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
826 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, 733 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID,
827 HID_ANY_ID) }, 734 HID_ANY_ID) },
828 { } 735 { }
@@ -835,7 +742,6 @@ static struct hid_driver sensor_hub_driver = {
835 .probe = sensor_hub_probe, 742 .probe = sensor_hub_probe,
836 .remove = sensor_hub_remove, 743 .remove = sensor_hub_remove,
837 .raw_event = sensor_hub_raw_event, 744 .raw_event = sensor_hub_raw_event,
838 .report_fixup = sensor_hub_report_fixup,
839#ifdef CONFIG_PM 745#ifdef CONFIG_PM
840 .suspend = sensor_hub_suspend, 746 .suspend = sensor_hub_suspend,
841 .resume = sensor_hub_resume, 747 .resume = sensor_hub_resume,
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index f5d4d786e193..ed3849d6fc6a 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -473,6 +473,9 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
473 HID_USAGE_SENSOR_PROY_POWER_STATE, 473 HID_USAGE_SENSOR_PROY_POWER_STATE,
474 &st->power_state); 474 &st->power_state);
475 475
476 st->power_state.logical_minimum = 1;
477 st->report_state.logical_minimum = 1;
478
476 sensor_hub_input_get_attribute_info(hsdev, 479 sensor_hub_input_get_attribute_info(hsdev,
477 HID_FEATURE_REPORT, usage_id, 480 HID_FEATURE_REPORT, usage_id,
478 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, 481 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,