aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorAndrew Duggan <aduggan@synaptics.com>2014-12-19 17:45:41 -0500
committerJiri Kosina <jkosina@suse.cz>2014-12-22 08:22:57 -0500
commit2f43de605e700f5aa5cad15e19f8ffe54b1d4c86 (patch)
tree0a9a2c7675ac7f63c6935cd2d7b2036cd2325243 /drivers/hid
parente39f2d5956999c05c85814787a113ffadbcd4b26 (diff)
HID: rmi: Support non rmi devices by passing events to hid-input
Allowing hid-rmi to bind to non rmi devices allows us to support composite USB devices which contain several HID devices one of which is a HID touchpad. Since all of the devices have the same VID and PID we can add the device to the hid_have_special_driver list and have hid-rmi handle all of the devices. Then hid-rmi's probe can look for the rmi specific HID report IDs and decide if it should handle the device as a rmi device or simply report that the events needs additional processing. Signed-off-by: Andrew Duggan <aduggan@synaptics.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-rmi.c93
1 files changed, 76 insertions, 17 deletions
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index b51200fe2f33..018f80f5fec6 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -33,6 +33,9 @@
33#define RMI_READ_DATA_PENDING BIT(1) 33#define RMI_READ_DATA_PENDING BIT(1)
34#define RMI_STARTED BIT(2) 34#define RMI_STARTED BIT(2)
35 35
36/* device flags */
37#define RMI_DEVICE BIT(0)
38
36enum rmi_mode_type { 39enum rmi_mode_type {
37 RMI_MODE_OFF = 0, 40 RMI_MODE_OFF = 0,
38 RMI_MODE_ATTN_REPORTS = 1, 41 RMI_MODE_ATTN_REPORTS = 1,
@@ -118,6 +121,8 @@ struct rmi_data {
118 121
119 struct work_struct reset_work; 122 struct work_struct reset_work;
120 struct hid_device *hdev; 123 struct hid_device *hdev;
124
125 unsigned long device_flags;
121}; 126};
122 127
123#define RMI_PAGE(addr) (((addr) >> 8) & 0xff) 128#define RMI_PAGE(addr) (((addr) >> 8) & 0xff)
@@ -452,9 +457,23 @@ static int rmi_raw_event(struct hid_device *hdev,
452 return rmi_read_data_event(hdev, data, size); 457 return rmi_read_data_event(hdev, data, size);
453 case RMI_ATTN_REPORT_ID: 458 case RMI_ATTN_REPORT_ID:
454 return rmi_input_event(hdev, data, size); 459 return rmi_input_event(hdev, data, size);
455 case RMI_MOUSE_REPORT_ID: 460 default:
461 return 1;
462 }
463
464 return 0;
465}
466
467static int rmi_event(struct hid_device *hdev, struct hid_field *field,
468 struct hid_usage *usage, __s32 value)
469{
470 struct rmi_data *data = hid_get_drvdata(hdev);
471
472 if ((data->device_flags & RMI_DEVICE) &&
473 (field->application == HID_GD_POINTER ||
474 field->application == HID_GD_MOUSE)) {
456 rmi_schedule_reset(hdev); 475 rmi_schedule_reset(hdev);
457 break; 476 return 1;
458 } 477 }
459 478
460 return 0; 479 return 0;
@@ -856,6 +875,9 @@ static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi)
856 if (ret) 875 if (ret)
857 return; 876 return;
858 877
878 if (!(data->device_flags & RMI_DEVICE))
879 return;
880
859 /* Allow incoming hid reports */ 881 /* Allow incoming hid reports */
860 hid_device_io_start(hdev); 882 hid_device_io_start(hdev);
861 883
@@ -914,8 +936,33 @@ static int rmi_input_mapping(struct hid_device *hdev,
914 struct hid_input *hi, struct hid_field *field, 936 struct hid_input *hi, struct hid_field *field,
915 struct hid_usage *usage, unsigned long **bit, int *max) 937 struct hid_usage *usage, unsigned long **bit, int *max)
916{ 938{
917 /* we want to make HID ignore the advertised HID collection */ 939 struct rmi_data *data = hid_get_drvdata(hdev);
918 return -1; 940
941 /*
942 * we want to make HID ignore the advertised HID collection
943 * for RMI deivces
944 */
945 if (data->device_flags & RMI_DEVICE)
946 return -1;
947
948 return 0;
949}
950
951static int rmi_check_valid_report_id(struct hid_device *hdev, unsigned type,
952 unsigned id, struct hid_report **report)
953{
954 int i;
955
956 *report = hdev->report_enum[type].report_id_hash[id];
957 if (*report) {
958 for (i = 0; i < (*report)->maxfield; i++) {
959 unsigned app = (*report)->field[i]->application;
960 if ((app & HID_USAGE_PAGE) >= HID_UP_MSVENDOR)
961 return 1;
962 }
963 }
964
965 return 0;
919} 966}
920 967
921static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) 968static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
@@ -925,6 +972,7 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
925 size_t alloc_size; 972 size_t alloc_size;
926 struct hid_report *input_report; 973 struct hid_report *input_report;
927 struct hid_report *output_report; 974 struct hid_report *output_report;
975 struct hid_report *feature_report;
928 976
929 data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL); 977 data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL);
930 if (!data) 978 if (!data)
@@ -943,27 +991,35 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
943 return ret; 991 return ret;
944 } 992 }
945 993
946 input_report = hdev->report_enum[HID_INPUT_REPORT] 994 /*
947 .report_id_hash[RMI_ATTN_REPORT_ID]; 995 * Check for the RMI specific report ids. If they are misisng
948 if (!input_report) { 996 * simply return and let the events be processed by hid-input
949 hid_err(hdev, "device does not have expected input report\n"); 997 */
950 ret = -ENODEV; 998 if (!rmi_check_valid_report_id(hdev, HID_FEATURE_REPORT,
951 return ret; 999 RMI_SET_RMI_MODE_REPORT_ID, &feature_report)) {
1000 hid_dbg(hdev, "device does not have set mode feature report\n");
1001 goto start;
1002 }
1003
1004 if (!rmi_check_valid_report_id(hdev, HID_INPUT_REPORT,
1005 RMI_ATTN_REPORT_ID, &input_report)) {
1006 hid_dbg(hdev, "device does not have attention input report\n");
1007 goto start;
952 } 1008 }
953 1009
954 data->input_report_size = (input_report->size >> 3) + 1 /* report id */; 1010 data->input_report_size = (input_report->size >> 3) + 1 /* report id */;
955 1011
956 output_report = hdev->report_enum[HID_OUTPUT_REPORT] 1012 if (!rmi_check_valid_report_id(hdev, HID_OUTPUT_REPORT,
957 .report_id_hash[RMI_WRITE_REPORT_ID]; 1013 RMI_WRITE_REPORT_ID, &output_report)) {
958 if (!output_report) { 1014 hid_dbg(hdev,
959 hid_err(hdev, "device does not have expected output report\n"); 1015 "device does not have rmi write output report\n");
960 ret = -ENODEV; 1016 goto start;
961 return ret;
962 } 1017 }
963 1018
964 data->output_report_size = (output_report->size >> 3) 1019 data->output_report_size = (output_report->size >> 3)
965 + 1 /* report id */; 1020 + 1 /* report id */;
966 1021
1022 data->device_flags |= RMI_DEVICE;
967 alloc_size = data->output_report_size + data->input_report_size; 1023 alloc_size = data->output_report_size + data->input_report_size;
968 1024
969 data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); 1025 data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL);
@@ -978,13 +1034,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
978 1034
979 mutex_init(&data->page_mutex); 1035 mutex_init(&data->page_mutex);
980 1036
1037start:
981 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 1038 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
982 if (ret) { 1039 if (ret) {
983 hid_err(hdev, "hw start failed\n"); 1040 hid_err(hdev, "hw start failed\n");
984 return ret; 1041 return ret;
985 } 1042 }
986 1043
987 if (!test_bit(RMI_STARTED, &data->flags)) 1044 if ((data->device_flags & RMI_DEVICE) &&
1045 !test_bit(RMI_STARTED, &data->flags))
988 /* 1046 /*
989 * The device maybe in the bootloader if rmi_input_configured 1047 * The device maybe in the bootloader if rmi_input_configured
990 * failed to find F11 in the PDT. Print an error, but don't 1048 * failed to find F11 in the PDT. Print an error, but don't
@@ -1017,6 +1075,7 @@ static struct hid_driver rmi_driver = {
1017 .id_table = rmi_id, 1075 .id_table = rmi_id,
1018 .probe = rmi_probe, 1076 .probe = rmi_probe,
1019 .remove = rmi_remove, 1077 .remove = rmi_remove,
1078 .event = rmi_event,
1020 .raw_event = rmi_raw_event, 1079 .raw_event = rmi_raw_event,
1021 .input_mapping = rmi_input_mapping, 1080 .input_mapping = rmi_input_mapping,
1022 .input_configured = rmi_input_configured, 1081 .input_configured = rmi_input_configured,