aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2018-07-13 10:13:47 -0400
committerJiri Kosina <jkosina@suse.cz>2018-07-17 09:33:47 -0400
commit8dfe14b3b47ff832cb638731f9fc696a3a84f804 (patch)
tree8e4d1d1f80e006389b39a634e1939c9d6121babc /drivers/hid
parent3ceb3826448d1ec4650a6c2b62baa9e0994ac7d3 (diff)
HID: multitouch: ditch mt_report_id
Now that the driver can handle more than one multitouch collection in a single HID device, ditch the last bit that contains us to use only one mt collection. Acked-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-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-multitouch.c126
1 files changed, 94 insertions, 32 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index beaac36f61a7..a2c10fc62ef2 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -147,6 +147,13 @@ struct mt_fields {
147 unsigned int length; 147 unsigned int length;
148}; 148};
149 149
150struct mt_report_data {
151 struct list_head list;
152 struct hid_report *report;
153 struct mt_application *application;
154 bool is_mt_collection;
155};
156
150struct mt_device { 157struct mt_device {
151 struct mt_class mtclass; /* our mt device class */ 158 struct mt_class mtclass; /* our mt device class */
152 struct timer_list release_timer; /* to release sticky fingers */ 159 struct timer_list release_timer; /* to release sticky fingers */
@@ -154,13 +161,13 @@ struct mt_device {
154 struct mt_fields *fields; /* temporary placeholder for storing the 161 struct mt_fields *fields; /* temporary placeholder for storing the
155 multitouch fields */ 162 multitouch fields */
156 unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */ 163 unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_*) */
157 unsigned mt_report_id; /* the report ID of the multitouch device */
158 __u8 inputmode_value; /* InputMode HID feature value */ 164 __u8 inputmode_value; /* InputMode HID feature value */
159 __u8 maxcontacts; 165 __u8 maxcontacts;
160 bool is_buttonpad; /* is this device a button pad? */ 166 bool is_buttonpad; /* is this device a button pad? */
161 bool serial_maybe; /* need to check for serial protocol */ 167 bool serial_maybe; /* need to check for serial protocol */
162 168
163 struct list_head applications; 169 struct list_head applications;
170 struct list_head reports;
164}; 171};
165 172
166static void mt_post_parse_default_settings(struct mt_device *td, 173static void mt_post_parse_default_settings(struct mt_device *td,
@@ -526,6 +533,60 @@ static struct mt_application *mt_find_application(struct mt_device *td,
526 return mt_application; 533 return mt_application;
527} 534}
528 535
536static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
537 struct hid_report *report)
538{
539 struct mt_report_data *rdata;
540 struct hid_field *field;
541 int r, n;
542
543 rdata = devm_kzalloc(&td->hdev->dev, sizeof(*rdata), GFP_KERNEL);
544 if (!rdata)
545 return NULL;
546
547 rdata->report = report;
548 rdata->application = mt_find_application(td, report->application);
549
550 if (!rdata->application) {
551 devm_kfree(&td->hdev->dev, rdata);
552 return NULL;
553 }
554
555 for (r = 0; r < report->maxfield; r++) {
556 field = report->field[r];
557
558 if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
559 continue;
560
561 for (n = 0; n < field->report_count; n++) {
562 if (field->usage[n].hid == HID_DG_CONTACTID)
563 rdata->is_mt_collection = true;
564 }
565 }
566
567 list_add_tail(&rdata->list, &td->reports);
568
569 return rdata;
570}
571
572static struct mt_report_data *mt_find_report_data(struct mt_device *td,
573 struct hid_report *report)
574{
575 struct mt_report_data *tmp, *rdata = NULL;
576
577 list_for_each_entry(tmp, &td->reports, list) {
578 if (report == tmp->report) {
579 rdata = tmp;
580 break;
581 }
582 }
583
584 if (!rdata)
585 rdata = mt_allocate_report_data(td, report);
586
587 return rdata;
588}
589
529static void mt_store_field(struct hid_usage *usage, struct mt_device *td, 590static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
530 struct hid_input *hi) 591 struct hid_input *hi)
531{ 592{
@@ -614,7 +675,6 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
614 case HID_DG_CONTACTID: 675 case HID_DG_CONTACTID:
615 mt_store_field(usage, td, hi); 676 mt_store_field(usage, td, hi);
616 app->touches_by_report++; 677 app->touches_by_report++;
617 td->mt_report_id = field->report->id;
618 return 1; 678 return 1;
619 case HID_DG_WIDTH: 679 case HID_DG_WIDTH:
620 hid_map_usage(hi, usage, bit, max, 680 hid_map_usage(hi, usage, bit, max,
@@ -979,10 +1039,12 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
979 } 1039 }
980} 1040}
981 1041
982static void mt_touch_report(struct hid_device *hid, struct hid_report *report) 1042static void mt_touch_report(struct hid_device *hid,
1043 struct mt_report_data *rdata)
983{ 1044{
984 struct mt_device *td = hid_get_drvdata(hid); 1045 struct mt_device *td = hid_get_drvdata(hid);
985 struct mt_application *app; 1046 struct hid_report *report = rdata->report;
1047 struct mt_application *app = rdata->application;
986 struct hid_field *field; 1048 struct hid_field *field;
987 bool first_packet; 1049 bool first_packet;
988 unsigned count; 1050 unsigned count;
@@ -994,11 +1056,6 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
994 if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) 1056 if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
995 return; 1057 return;
996 1058
997 app = mt_find_application(td, report->application);
998
999 if (!app)
1000 return;
1001
1002 /* 1059 /*
1003 * Includes multi-packet support where subsequent 1060 * Includes multi-packet support where subsequent
1004 * packets are sent with zero contactcount. 1061 * packets are sent with zero contactcount.
@@ -1119,8 +1176,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
1119{ 1176{
1120 struct mt_device *td = hid_get_drvdata(hdev); 1177 struct mt_device *td = hid_get_drvdata(hdev);
1121 struct mt_application *application; 1178 struct mt_application *application;
1179 struct mt_report_data *rdata;
1180
1181 rdata = mt_find_report_data(td, field->report);
1182 if (!rdata) {
1183 hid_err(hdev, "failed to allocate data for report\n");
1184 return 0;
1185 }
1122 1186
1123 application = mt_find_application(td, field->application); 1187 application = rdata->application;
1124 1188
1125 /* 1189 /*
1126 * If mtclass.export_all_inputs is not set, only map fields from 1190 * If mtclass.export_all_inputs is not set, only map fields from
@@ -1163,22 +1227,9 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
1163 return 1; 1227 return 1;
1164 } 1228 }
1165 1229
1166 /* 1230 if (rdata->is_mt_collection &&
1167 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN" 1231 (field->application == HID_DG_TOUCHSCREEN ||
1168 * for the stylus. 1232 field->application == HID_DG_TOUCHPAD))
1169 * The check for mt_report_id ensures we don't process
1170 * HID_DG_CONTACTCOUNT from the pen report as it is outside the physical
1171 * collection, but within the report ID.
1172 */
1173 if (field->physical == HID_DG_STYLUS)
1174 return 0;
1175 else if ((field->physical == 0) &&
1176 (field->report->id != td->mt_report_id) &&
1177 (td->mt_report_id != -1))
1178 return 0;
1179
1180 if (field->application == HID_DG_TOUCHSCREEN ||
1181 field->application == HID_DG_TOUCHPAD)
1182 return mt_touch_input_mapping(hdev, hi, field, usage, bit, max, 1233 return mt_touch_input_mapping(hdev, hi, field, usage, bit, max,
1183 application); 1234 application);
1184 1235
@@ -1211,8 +1262,10 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
1211 struct hid_usage *usage, __s32 value) 1262 struct hid_usage *usage, __s32 value)
1212{ 1263{
1213 struct mt_device *td = hid_get_drvdata(hid); 1264 struct mt_device *td = hid_get_drvdata(hid);
1265 struct mt_report_data *rdata;
1214 1266
1215 if (field->report->id == td->mt_report_id) 1267 rdata = mt_find_report_data(td, field->report);
1268 if (rdata && rdata->is_mt_collection)
1216 return mt_touch_event(hid, field, usage, value); 1269 return mt_touch_event(hid, field, usage, value);
1217 1270
1218 return 0; 1271 return 0;
@@ -1222,12 +1275,14 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
1222{ 1275{
1223 struct mt_device *td = hid_get_drvdata(hid); 1276 struct mt_device *td = hid_get_drvdata(hid);
1224 struct hid_field *field = report->field[0]; 1277 struct hid_field *field = report->field[0];
1278 struct mt_report_data *rdata;
1225 1279
1226 if (!(hid->claimed & HID_CLAIMED_INPUT)) 1280 if (!(hid->claimed & HID_CLAIMED_INPUT))
1227 return; 1281 return;
1228 1282
1229 if (report->id == td->mt_report_id) 1283 rdata = mt_find_report_data(td, report);
1230 return mt_touch_report(hid, report); 1284 if (rdata && rdata->is_mt_collection)
1285 return mt_touch_report(hid, rdata);
1231 1286
1232 if (field && field->hidinput && field->hidinput->input) 1287 if (field && field->hidinput && field->hidinput->input)
1233 input_sync(field->hidinput->input); 1288 input_sync(field->hidinput->input);
@@ -1368,15 +1423,22 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
1368 char *name; 1423 char *name;
1369 const char *suffix = NULL; 1424 const char *suffix = NULL;
1370 unsigned int application = 0; 1425 unsigned int application = 0;
1426 struct mt_report_data *rdata;
1371 struct mt_application *mt_application = NULL; 1427 struct mt_application *mt_application = NULL;
1372 struct hid_report *report; 1428 struct hid_report *report;
1373 int ret; 1429 int ret;
1374 1430
1375 list_for_each_entry(report, &hi->reports, hidinput_list) { 1431 list_for_each_entry(report, &hi->reports, hidinput_list) {
1376 application = report->application; 1432 application = report->application;
1377 mt_application = mt_find_application(td, application); 1433 rdata = mt_find_report_data(td, report);
1434 if (!rdata) {
1435 hid_err(hdev, "failed to allocate data for report\n");
1436 return -ENOMEM;
1437 }
1438
1439 mt_application = rdata->application;
1378 1440
1379 if (report->id == td->mt_report_id) { 1441 if (rdata->is_mt_collection) {
1380 ret = mt_touch_input_configured(hdev, hi, 1442 ret = mt_touch_input_configured(hdev, hi,
1381 mt_application); 1443 mt_application);
1382 if (ret) 1444 if (ret)
@@ -1529,10 +1591,10 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
1529 td->hdev = hdev; 1591 td->hdev = hdev;
1530 td->mtclass = *mtclass; 1592 td->mtclass = *mtclass;
1531 td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN; 1593 td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
1532 td->mt_report_id = -1;
1533 hid_set_drvdata(hdev, td); 1594 hid_set_drvdata(hdev, td);
1534 1595
1535 INIT_LIST_HEAD(&td->applications); 1596 INIT_LIST_HEAD(&td->applications);
1597 INIT_LIST_HEAD(&td->reports);
1536 1598
1537 td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields), 1599 td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields),
1538 GFP_KERNEL); 1600 GFP_KERNEL);