aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-rmi.c
diff options
context:
space:
mode:
authorAndrew Duggan <aduggan@synaptics.com>2015-02-10 15:36:55 -0500
committerJiri Kosina <jkosina@suse.cz>2015-02-17 07:25:03 -0500
commit70e003f75fab6c1496147838acf59be85d2520c0 (patch)
treecd91dbc365752b8d88ff3189f3a653985d36188f /drivers/hid/hid-rmi.c
parent870fd0f5df4e131467612cc46db46fc3b69fd706 (diff)
HID: rmi: Print the firmware id of the touchpad
Knowing the firmware id is extremely useful when debugging issues related to the touchpad. It can be used to determine the hardware, firmware version, and configuation of the touchpad. This patch queries the firmware id and prints it as the touchpad is starting so that it will show up in the dmesg output included in bug reports. Signed-off-by: Andrew Duggan <aduggan@synaptics.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-rmi.c')
-rw-r--r--drivers/hid/hid-rmi.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index 49d4fe4f5987..28579d783155 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -104,6 +104,7 @@ struct rmi_data {
104 104
105 unsigned long flags; 105 unsigned long flags;
106 106
107 struct rmi_function f01;
107 struct rmi_function f11; 108 struct rmi_function f11;
108 struct rmi_function f30; 109 struct rmi_function f30;
109 110
@@ -124,6 +125,7 @@ struct rmi_data {
124 struct hid_device *hdev; 125 struct hid_device *hdev;
125 126
126 unsigned long device_flags; 127 unsigned long device_flags;
128 unsigned long firmware_id;
127}; 129};
128 130
129#define RMI_PAGE(addr) (((addr) >> 8) & 0xff) 131#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
@@ -532,6 +534,9 @@ static void rmi_register_function(struct rmi_data *data,
532 u16 page_base = page << 8; 534 u16 page_base = page << 8;
533 535
534 switch (pdt_entry->function_number) { 536 switch (pdt_entry->function_number) {
537 case 0x01:
538 f = &data->f01;
539 break;
535 case 0x11: 540 case 0x11:
536 f = &data->f11; 541 f = &data->f11;
537 break; 542 break;
@@ -604,6 +609,92 @@ error_exit:
604 return retval; 609 return retval;
605} 610}
606 611
612#define RMI_DEVICE_F01_BASIC_QUERY_LEN 11
613
614static int rmi_populate_f01(struct hid_device *hdev)
615{
616 struct rmi_data *data = hid_get_drvdata(hdev);
617 u8 basic_queries[RMI_DEVICE_F01_BASIC_QUERY_LEN];
618 u8 info[3];
619 int ret;
620 bool has_query42;
621 bool has_lts;
622 bool has_sensor_id;
623 bool has_ds4_queries = false;
624 bool has_build_id_query = false;
625 bool has_package_id_query = false;
626 u16 query_offset = data->f01.query_base_addr;
627 u16 prod_info_addr;
628 u8 ds4_query_len;
629
630 ret = rmi_read_block(hdev, query_offset, basic_queries,
631 RMI_DEVICE_F01_BASIC_QUERY_LEN);
632 if (ret) {
633 hid_err(hdev, "Can not read basic queries from Function 0x1.\n");
634 return ret;
635 }
636
637 has_lts = !!(basic_queries[0] & BIT(2));
638 has_sensor_id = !!(basic_queries[1] & BIT(3));
639 has_query42 = !!(basic_queries[1] & BIT(7));
640
641 query_offset += 11;
642 prod_info_addr = query_offset + 6;
643 query_offset += 10;
644
645 if (has_lts)
646 query_offset += 20;
647
648 if (has_sensor_id)
649 query_offset++;
650
651 if (has_query42) {
652 ret = rmi_read(hdev, query_offset, info);
653 if (ret) {
654 hid_err(hdev, "Can not read query42.\n");
655 return ret;
656 }
657 has_ds4_queries = !!(info[0] & BIT(0));
658 query_offset++;
659 }
660
661 if (has_ds4_queries) {
662 ret = rmi_read(hdev, query_offset, &ds4_query_len);
663 if (ret) {
664 hid_err(hdev, "Can not read DS4 Query length.\n");
665 return ret;
666 }
667 query_offset++;
668
669 if (ds4_query_len > 0) {
670 ret = rmi_read(hdev, query_offset, info);
671 if (ret) {
672 hid_err(hdev, "Can not read DS4 query.\n");
673 return ret;
674 }
675
676 has_package_id_query = !!(info[0] & BIT(0));
677 has_build_id_query = !!(info[0] & BIT(1));
678 }
679 }
680
681 if (has_package_id_query)
682 prod_info_addr++;
683
684 if (has_build_id_query) {
685 ret = rmi_read_block(hdev, prod_info_addr, info, 3);
686 if (ret) {
687 hid_err(hdev, "Can not read product info.\n");
688 return ret;
689 }
690
691 data->firmware_id = info[1] << 8 | info[0];
692 data->firmware_id += info[2] * 65536;
693 }
694
695 return 0;
696}
697
607static int rmi_populate_f11(struct hid_device *hdev) 698static int rmi_populate_f11(struct hid_device *hdev)
608{ 699{
609 struct rmi_data *data = hid_get_drvdata(hdev); 700 struct rmi_data *data = hid_get_drvdata(hdev);
@@ -858,6 +949,12 @@ static int rmi_populate(struct hid_device *hdev)
858 return ret; 949 return ret;
859 } 950 }
860 951
952 ret = rmi_populate_f01(hdev);
953 if (ret) {
954 hid_err(hdev, "Error while initializing F01 (%d).\n", ret);
955 return ret;
956 }
957
861 ret = rmi_populate_f11(hdev); 958 ret = rmi_populate_f11(hdev);
862 if (ret) { 959 if (ret) {
863 hid_err(hdev, "Error while initializing F11 (%d).\n", ret); 960 hid_err(hdev, "Error while initializing F11 (%d).\n", ret);
@@ -907,6 +1004,8 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
907 if (ret) 1004 if (ret)
908 goto exit; 1005 goto exit;
909 1006
1007 hid_info(hdev, "firmware id: %ld\n", data->firmware_id);
1008
910 __set_bit(EV_ABS, input->evbit); 1009 __set_bit(EV_ABS, input->evbit);
911 input_set_abs_params(input, ABS_MT_POSITION_X, 1, data->max_x, 0, 0); 1010 input_set_abs_params(input, ABS_MT_POSITION_X, 1, data->max_x, 0, 0);
912 input_set_abs_params(input, ABS_MT_POSITION_Y, 1, data->max_y, 0, 0); 1011 input_set_abs_params(input, ABS_MT_POSITION_Y, 1, data->max_y, 0, 0);