diff options
| -rw-r--r-- | drivers/hid/hid-rmi.c | 99 |
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 | |||
| 614 | static 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 | |||
| 607 | static int rmi_populate_f11(struct hid_device *hdev) | 698 | static 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); |
