History

Merge branches 'device-groups', 'logitech' and 'multitouch' into for-linus

Jiri Kosina committed 14 years ago

Commit b3d07e03 parents b565a39 c6e6dc8 3ac36d14 files · +287 −89Browse files

Unified · Split

4 files
  1. drivers/hid/hid-lg.c +32 −23
  2. drivers/hid/hid-lg.h +5 −0
  3. drivers/hid/hid-lg4ff.c +204 −54
  4. drivers/hid/hid-multitouch.c +46 −12
drivers/hid/hid-lg.c+32−23
@@ -109,23 +109,23 @@ static __u8 dfp_rdesc_fixed[] = { · 108 unmodified lines
109109 static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
110110 unsigned int *rsize)
111111 {
112− unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
112+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev);
113113
114− if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
114+ if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
115115 rdesc[84] == 0x8c && rdesc[85] == 0x02) {
116116 hid_info(hdev,
117117 "fixing up Logitech keyboard report descriptor\n");
118118 rdesc[84] = rdesc[89] = 0x4d;
119119 rdesc[85] = rdesc[90] = 0x10;
120120 }
121− if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
121+ if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
122122 rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
123123 rdesc[49] == 0x81 && rdesc[50] == 0x06) {
124124 hid_info(hdev,
125125 "fixing up rel/abs in Logitech report descriptor\n");
126126 rdesc[33] = rdesc[50] = 0x02;
127127 }
128− if ((quirks & LG_FF4) && *rsize >= 101 &&
128+ if ((drv_data->quirks & LG_FF4) && *rsize >= 101 &&
129129 rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
130130 rdesc[47] == 0x05 && rdesc[48] == 0x09) {
131131 hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n");
@@ -278,7 +278,7 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 146 unmodified lines
278278 0, 0, 0, 0, 0,183,184,185,186,187,
279279 188,189,190,191,192,193,194, 0, 0, 0
280280 };
281− unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
281+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev);
282282 unsigned int hid = usage->hid;
283283
284284 if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER &&
@@ -289,7 +289,7 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 4 unmodified lines
289289 lg_dinovo_mapping(hi, usage, bit, max))
290290 return 1;
291291
292− if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
292+ if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
293293 return 1;
294294
295295 if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
@@ -299,11 +299,11 @@ static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 3 unmodified lines
299299
300300 /* Special handling for Logitech Cordless Desktop */
301301 if (field->application == HID_GD_MOUSE) {
302− if ((quirks & LG_IGNORE_DOUBLED_WHEEL) &&
302+ if ((drv_data->quirks & LG_IGNORE_DOUBLED_WHEEL) &&
303303 (hid == 7 || hid == 8))
304304 return -1;
305305 } else {
306− if ((quirks & LG_EXPANDED_KEYMAP) &&
306+ if ((drv_data->quirks & LG_EXPANDED_KEYMAP) &&
307307 hid < ARRAY_SIZE(e_keymap) &&
308308 e_keymap[hid] != 0) {
309309 hid_map_usage(hi, usage, bit, max, EV_KEY,
@@ -319,13 +319,13 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, · 9 unmodified lines
319319 struct hid_field *field, struct hid_usage *usage,
320320 unsigned long **bit, int *max)
321321 {
322− unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
322+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev);
323323
324− if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
324+ if ((drv_data->quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
325325 (field->flags & HID_MAIN_ITEM_RELATIVE))
326326 field->flags &= ~HID_MAIN_ITEM_RELATIVE;
327327
328− if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
328+ if ((drv_data->quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
329329 usage->type == EV_REL || usage->type == EV_ABS))
330330 clear_bit(usage->code, *bit);
331331
@@ -335,9 +335,9 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, · 3 unmodified lines
335335 static int lg_event(struct hid_device *hdev, struct hid_field *field,
336336 struct hid_usage *usage, __s32 value)
337337 {
338− unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
338+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev);
339339
340− if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
340+ if ((drv_data->quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
341341 input_event(field->hidinput->input, usage->type, usage->code,
342342 -value);
343343 return 1;
@@ -348,13 +348,20 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field, · 4 unmodified lines
348348
349349 static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
350350 {
351− unsigned long quirks = id->driver_data;
352351 unsigned int connect_mask = HID_CONNECT_DEFAULT;
352+ struct lg_drv_data *drv_data;
353353 int ret;
354354
355− hid_set_drvdata(hdev, (void *)quirks);
355+ drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
356+ if (!drv_data) {
357+ hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
358+ return -ENOMEM;
359+ }
360+ drv_data->quirks = id->driver_data;
361+
362+ hid_set_drvdata(hdev, (void *)drv_data);
356363
357− if (quirks & LG_NOGET)
364+ if (drv_data->quirks & LG_NOGET)
358365 hdev->quirks |= HID_QUIRK_NOGET;
359366
360367 ret = hid_parse(hdev);
@@ -363,7 +370,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) · 2 unmodified lines
363370 goto err_free;
364371 }
365372
366− if (quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
373+ if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
367374 connect_mask &= ~HID_CONNECT_FF;
368375
369376 ret = hid_hw_start(hdev, connect_mask);
@@ -392,27 +399,29 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) · 22 unmodified lines
392399 }
393400 }
394401
395− if (quirks & LG_FF)
402+ if (drv_data->quirks & LG_FF)
396403 lgff_init(hdev);
397− if (quirks & LG_FF2)
404+ if (drv_data->quirks & LG_FF2)
398405 lg2ff_init(hdev);
399− if (quirks & LG_FF3)
406+ if (drv_data->quirks & LG_FF3)
400407 lg3ff_init(hdev);
401− if (quirks & LG_FF4)
408+ if (drv_data->quirks & LG_FF4)
402409 lg4ff_init(hdev);
403410
404411 return 0;
405412 err_free:
413+ kfree(drv_data);
406414 return ret;
407415 }
408416
409417 static void lg_remove(struct hid_device *hdev)
410418 {
411− unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
412− if(quirks & LG_FF4)
419+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hdev);
420+ if (drv_data->quirks & LG_FF4)
413421 lg4ff_deinit(hdev);
414422
415423 hid_hw_stop(hdev);
424+ kfree(drv_data);
416425 }
417426
418427 static const struct hid_device_id lg_devices[] = {
drivers/hid/hid-lg.h+5−0
@@ -1,6 +1,11 @@
11 #ifndef __HID_LG_H
22 #define __HID_LG_H
33
4+struct lg_drv_data {
5+ unsigned long quirks;
6+ void *device_props; /* Device specific properties */
7+};
8+
49 #ifdef CONFIG_LOGITECH_FF
510 int lgff_init(struct hid_device *hdev);
611 #else
drivers/hid/hid-lg4ff.c+204−54
@@ -1,7 +1,8 @@
11 /*
2− * Force feedback support for Logitech Speed Force Wireless
2+ * Force feedback support for Logitech Gaming Wheels
33 *
4− * http://wiibrew.org/wiki/Logitech_USB_steering_wheel
4+ * Including G27, G25, DFP, DFGT, FFEX, Momo, Momo2 &
5+ * Speed Force Wireless (WiiWheel)
56 *
67 * Copyright (c) 2010 Simon Wood <simon@mungewell.org>
78 */
@@ -51,20 +52,18 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at · 43 unmodified lines
5152
5253 static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
5354
54−static bool list_inited;
55−
5655 struct lg4ff_device_entry {
57− char *device_id; /* Use name in respective kobject structure's address as the ID */
5856 __u16 range;
5957 __u16 min_range;
6058 __u16 max_range;
61− __u8 leds;
59+#ifdef CONFIG_LEDS_CLASS
60+ __u8 led_state;
61+ struct led_classdev *led[5];
62+#endif
6263 struct list_head list;
6364 void (*set_range)(struct hid_device *hid, u16 range);
6465 };
6566
66−static struct lg4ff_device_entry device_list;
67−
6867 static const signed short lg4ff_wheel_effects[] = {
6968 FF_CONSTANT,
7069 FF_AUTOCENTER,
@@ -285,18 +284,20 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n · 214 unmodified lines
285284 /* Read current range and display it in terminal */
286285 static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
287286 {
288− struct lg4ff_device_entry *uninitialized_var(entry);
289− struct list_head *h;
290287 struct hid_device *hid = to_hid_device(dev);
288+ struct lg4ff_device_entry *entry;
289+ struct lg_drv_data *drv_data;
291290 size_t count;
292291
293− list_for_each(h, &device_list.list) {
294− entry = list_entry(h, struct lg4ff_device_entry, list);
295− if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
296− break;
292+ drv_data = hid_get_drvdata(hid);
293+ if (!drv_data) {
294+ hid_err(hid, "Private driver data not found!\n");
295+ return 0;
297296 }
298− if (h == &device_list.list) {
299− dbg_hid("Device not found!");
297+
298+ entry = drv_data->device_props;
299+ if (!entry) {
300+ hid_err(hid, "Device properties not found!\n");
300301 return 0;
301302 }
302303
@@ -308,19 +309,21 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att · 5 unmodified lines
308309 * according to the type of the wheel */
309310 static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
310311 {
311− struct lg4ff_device_entry *uninitialized_var(entry);
312− struct list_head *h;
313312 struct hid_device *hid = to_hid_device(dev);
313+ struct lg4ff_device_entry *entry;
314+ struct lg_drv_data *drv_data;
314315 __u16 range = simple_strtoul(buf, NULL, 10);
315316
316− list_for_each(h, &device_list.list) {
317− entry = list_entry(h, struct lg4ff_device_entry, list);
318− if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0)
319− break;
317+ drv_data = hid_get_drvdata(hid);
318+ if (!drv_data) {
319+ hid_err(hid, "Private driver data not found!\n");
320+ return 0;
320321 }
321− if (h == &device_list.list) {
322− dbg_hid("Device not found!");
323− return count;
322+
323+ entry = drv_data->device_props;
324+ if (!entry) {
325+ hid_err(hid, "Device properties not found!\n");
326+ return 0;
324327 }
325328
326329 if (range == 0)
@@ -336,6 +339,88 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at · 9 unmodified lines
336339 return count;
337340 }
338341
342+#ifdef CONFIG_LEDS_CLASS
343+static void lg4ff_set_leds(struct hid_device *hid, __u8 leds)
344+{
345+ struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
346+ struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
347+
348+ report->field[0]->value[0] = 0xf8;
349+ report->field[0]->value[1] = 0x12;
350+ report->field[0]->value[2] = leds;
351+ report->field[0]->value[3] = 0x00;
352+ report->field[0]->value[4] = 0x00;
353+ report->field[0]->value[5] = 0x00;
354+ report->field[0]->value[6] = 0x00;
355+ usbhid_submit_report(hid, report, USB_DIR_OUT);
356+}
357+
358+static void lg4ff_led_set_brightness(struct led_classdev *led_cdev,
359+ enum led_brightness value)
360+{
361+ struct device *dev = led_cdev->dev->parent;
362+ struct hid_device *hid = container_of(dev, struct hid_device, dev);
363+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hid);
364+ struct lg4ff_device_entry *entry;
365+ int i, state = 0;
366+
367+ if (!drv_data) {
368+ hid_err(hid, "Device data not found.");
369+ return;
370+ }
371+
372+ entry = (struct lg4ff_device_entry *)drv_data->device_props;
373+
374+ if (!entry) {
375+ hid_err(hid, "Device properties not found.");
376+ return;
377+ }
378+
379+ for (i = 0; i < 5; i++) {
380+ if (led_cdev != entry->led[i])
381+ continue;
382+ state = (entry->led_state >> i) & 1;
383+ if (value == LED_OFF && state) {
384+ entry->led_state &= ~(1 << i);
385+ lg4ff_set_leds(hid, entry->led_state);
386+ } else if (value != LED_OFF && !state) {
387+ entry->led_state |= 1 << i;
388+ lg4ff_set_leds(hid, entry->led_state);
389+ }
390+ break;
391+ }
392+}
393+
394+static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cdev)
395+{
396+ struct device *dev = led_cdev->dev->parent;
397+ struct hid_device *hid = container_of(dev, struct hid_device, dev);
398+ struct lg_drv_data *drv_data = (struct lg_drv_data *)hid_get_drvdata(hid);
399+ struct lg4ff_device_entry *entry;
400+ int i, value = 0;
401+
402+ if (!drv_data) {
403+ hid_err(hid, "Device data not found.");
404+ return LED_OFF;
405+ }
406+
407+ entry = (struct lg4ff_device_entry *)drv_data->device_props;
408+
409+ if (!entry) {
410+ hid_err(hid, "Device properties not found.");
411+ return LED_OFF;
412+ }
413+
414+ for (i = 0; i < 5; i++)
415+ if (led_cdev == entry->led[i]) {
416+ value = (entry->led_state >> i) & 1;
417+ break;
418+ }
419+
420+ return value ? LED_FULL : LED_OFF;
421+}
422+#endif
423+
339424 int lg4ff_init(struct hid_device *hid)
340425 {
341426 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
@@ -344,6 +429,7 @@ int lg4ff_init(struct hid_device *hid) · 2 unmodified lines
344429 struct hid_report *report;
345430 struct hid_field *field;
346431 struct lg4ff_device_entry *entry;
432+ struct lg_drv_data *drv_data;
347433 struct usb_device_descriptor *udesc;
348434 int error, i, j;
349435 __u16 bcdDevice, rev_maj, rev_min;
@@ -423,28 +509,24 @@ int lg4ff_init(struct hid_device *hid) · 73 unmodified lines
423509 dev->ff->set_autocenter(dev, 0);
424510 }
425511
426− /* Initialize device_list if this is the first device to handle by lg4ff */
427− if (!list_inited) {
428− INIT_LIST_HEAD(&device_list.list);
429− list_inited = 1;
512+ /* Get private driver data */
513+ drv_data = hid_get_drvdata(hid);
514+ if (!drv_data) {
515+ hid_err(hid, "Cannot add device, private driver data not allocated\n");
516+ return -1;
430517 }
431518
432− /* Add the device to device_list */
519+ /* Initialize device properties */
433520 entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL);
434521 if (!entry) {
435− hid_err(hid, "Cannot add device, insufficient memory.\n");
436− return -ENOMEM;
437− }
438− entry->device_id = kstrdup((&hid->dev)->kobj.name, GFP_KERNEL);
439− if (!entry->device_id) {
440− hid_err(hid, "Cannot set device_id, insufficient memory.\n");
441− kfree(entry);
522+ hid_err(hid, "Cannot add device, insufficient memory to allocate device properties.\n");
442523 return -ENOMEM;
443524 }
525+ drv_data->device_props = entry;
526+
444527 entry->min_range = lg4ff_devices[i].min_range;
445528 entry->max_range = lg4ff_devices[i].max_range;
446529 entry->set_range = lg4ff_devices[i].set_range;
447− list_add(&entry->list, &device_list.list);
448530
449531 /* Create sysfs interface */
450532 error = device_create_file(&hid->dev, &dev_attr_range);
@@ -457,32 +539,100 @@ int lg4ff_init(struct hid_device *hid) · 6 unmodified lines
457539 if (entry->set_range != NULL)
458540 entry->set_range(hid, entry->range);
459541
460− hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood <simon@mungewell.org>\n");
542+#ifdef CONFIG_LEDS_CLASS
543+ /* register led subsystem - G27 only */
544+ entry->led_state = 0;
545+ for (j = 0; j < 5; j++)
546+ entry->led[j] = NULL;
547+
548+ if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) {
549+ struct led_classdev *led;
550+ size_t name_sz;
551+ char *name;
552+
553+ lg4ff_set_leds(hid, 0);
554+
555+ name_sz = strlen(dev_name(&hid->dev)) + 8;
556+
557+ for (j = 0; j < 5; j++) {
558+ led = kzalloc(sizeof(struct led_classdev)+name_sz, GFP_KERNEL);
559+ if (!led) {
560+ hid_err(hid, "can't allocate memory for LED %d\n", j);
561+ goto err;
562+ }
563+
564+ name = (void *)(&led[1]);
565+ snprintf(name, name_sz, "%s::RPM%d", dev_name(&hid->dev), j+1);
566+ led->name = name;
567+ led->brightness = 0;
568+ led->max_brightness = 1;
569+ led->brightness_get = lg4ff_led_get_brightness;
570+ led->brightness_set = lg4ff_led_set_brightness;
571+
572+ entry->led[j] = led;
573+ error = led_classdev_register(&hid->dev, led);
574+
575+ if (error) {
576+ hid_err(hid, "failed to register LED %d. Aborting.\n", j);
577+err:
578+ /* Deregister LEDs (if any) */
579+ for (j = 0; j < 5; j++) {
580+ led = entry->led[j];
581+ entry->led[j] = NULL;
582+ if (!led)
583+ continue;
584+ led_classdev_unregister(led);
585+ kfree(led);
586+ }
587+ goto out; /* Let the driver continue without LEDs */
588+ }
589+ }
590+ }
591+out:
592+#endif
593+ hid_info(hid, "Force feedback support for Logitech Gaming Wheels\n");
461594 return 0;
462595 }
463596
464597 int lg4ff_deinit(struct hid_device *hid)
465598 {
466− bool found = 0;
467599 struct lg4ff_device_entry *entry;
468− struct list_head *h, *g;
469− list_for_each_safe(h, g, &device_list.list) {
470− entry = list_entry(h, struct lg4ff_device_entry, list);
471− if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) {
472− list_del(h);
473− kfree(entry->device_id);
474− kfree(entry);
475− found = 1;
476− break;
477− }
478− }
600+ struct lg_drv_data *drv_data;
601+
602+ device_remove_file(&hid->dev, &dev_attr_range);
479603
480− if (!found) {
481− dbg_hid("Device entry not found!\n");
604+ drv_data = hid_get_drvdata(hid);
605+ if (!drv_data) {
606+ hid_err(hid, "Error while deinitializing device, no private driver data.\n");
607+ return -1;
608+ }
609+ entry = drv_data->device_props;
610+ if (!entry) {
611+ hid_err(hid, "Error while deinitializing device, no device properties data.\n");
482612 return -1;
483613 }
484614
485− device_remove_file(&hid->dev, &dev_attr_range);
615+#ifdef CONFIG_LEDS_CLASS
616+ {
617+ int j;
618+ struct led_classdev *led;
619+
620+ /* Deregister LEDs (if any) */
621+ for (j = 0; j < 5; j++) {
622+
623+ led = entry->led[j];
624+ entry->led[j] = NULL;
625+ if (!led)
626+ continue;
627+ led_classdev_unregister(led);
628+ kfree(led);
629+ }
630+ }
631+#endif
632+
633+ /* Deallocate memory */
634+ kfree(entry);
635+
486636 dbg_hid("Device successfully unregistered\n");
487637 return 0;
488638 }
drivers/hid/hid-multitouch.c+46−12
@@ -70,9 +70,16 @@ struct mt_class { · 69 unmodified lines
7070 bool is_indirect; /* true for touchpads */
7171 };
7272
73+struct mt_fields {
74+ unsigned usages[HID_MAX_FIELDS];
75+ unsigned int length;
76+};
77+
7378 struct mt_device {
7479 struct mt_slot curdata; /* placeholder of incoming data */
7580 struct mt_class mtclass; /* our mt device class */
81+ struct mt_fields *fields; /* temporary placeholder for storing the
82+ multitouch fields */
7683 unsigned last_field_index; /* last field index of the report */
7784 unsigned last_slot_field; /* the last field of a slot */
7885 __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
@@ -278,11 +285,15 @@ static void set_abs(struct input_dev *input, unsigned int code, · 199 unmodified lines
278285 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
279286 }
280287
281−static void set_last_slot_field(struct hid_usage *usage, struct mt_device *td,
288+static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
282289 struct hid_input *hi)
283290 {
284− if (!test_bit(usage->hid, hi->input->absbit))
285− td->last_slot_field = usage->hid;
291+ struct mt_fields *f = td->fields;
292+
293+ if (f->length >= HID_MAX_FIELDS)
294+ return;
295+
296+ f->usages[f->length++] = usage->hid;
286297 }
287298
288299 static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
@@ -333,7 +344,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 44 unmodified lines
333344 cls->sn_move);
334345 /* touchscreen emulation */
335346 set_abs(hi->input, ABS_X, field, cls->sn_move);
336− set_last_slot_field(usage, td, hi);
347+ mt_store_field(usage, td, hi);
337348 td->last_field_index = field->index;
338349 return 1;
339350 case HID_GD_Y:
@@ -343,7 +354,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 3 unmodified lines
343354 cls->sn_move);
344355 /* touchscreen emulation */
345356 set_abs(hi->input, ABS_Y, field, cls->sn_move);
346− set_last_slot_field(usage, td, hi);
357+ mt_store_field(usage, td, hi);
347358 td->last_field_index = field->index;
348359 return 1;
349360 }
@@ -352,24 +363,24 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 2 unmodified lines
352363 case HID_UP_DIGITIZER:
353364 switch (usage->hid) {
354365 case HID_DG_INRANGE:
355− set_last_slot_field(usage, td, hi);
366+ mt_store_field(usage, td, hi);
356367 td->last_field_index = field->index;
357368 return 1;
358369 case HID_DG_CONFIDENCE:
359− set_last_slot_field(usage, td, hi);
370+ mt_store_field(usage, td, hi);
360371 td->last_field_index = field->index;
361372 return 1;
362373 case HID_DG_TIPSWITCH:
363374 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
364375 input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
365− set_last_slot_field(usage, td, hi);
376+ mt_store_field(usage, td, hi);
366377 td->last_field_index = field->index;
367378 return 1;
368379 case HID_DG_CONTACTID:
369380 if (!td->maxcontacts)
370381 td->maxcontacts = MT_DEFAULT_MAXCONTACT;
371382 input_mt_init_slots(hi->input, td->maxcontacts);
372− td->last_slot_field = usage->hid;
383+ mt_store_field(usage, td, hi);
373384 td->last_field_index = field->index;
374385 td->touches_by_report++;
375386 return 1;
@@ -378,7 +389,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 2 unmodified lines
378389 EV_ABS, ABS_MT_TOUCH_MAJOR);
379390 set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
380391 cls->sn_width);
381− set_last_slot_field(usage, td, hi);
392+ mt_store_field(usage, td, hi);
382393 td->last_field_index = field->index;
383394 return 1;
384395 case HID_DG_HEIGHT:
@@ -388,7 +399,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 3 unmodified lines
388399 cls->sn_height);
389400 input_set_abs_params(hi->input,
390401 ABS_MT_ORIENTATION, 0, 1, 0, 0);
391− set_last_slot_field(usage, td, hi);
402+ mt_store_field(usage, td, hi);
392403 td->last_field_index = field->index;
393404 return 1;
394405 case HID_DG_TIPPRESSURE:
@@ -399,7 +410,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 4 unmodified lines
399410 /* touchscreen emulation */
400411 set_abs(hi->input, ABS_PRESSURE, field,
401412 cls->sn_pressure);
402− set_last_slot_field(usage, td, hi);
413+ mt_store_field(usage, td, hi);
403414 td->last_field_index = field->index;
404415 return 1;
405416 case HID_DG_CONTACTCOUNT:
@@ -653,6 +664,16 @@ static void mt_post_parse_default_settings(struct mt_device *td) · 247 unmodified lines
653664 td->mtclass.quirks = quirks;
654665 }
655666
667+static void mt_post_parse(struct mt_device *td)
668+{
669+ struct mt_fields *f = td->fields;
670+
671+ if (td->touches_by_report > 0) {
672+ int field_count_per_touch = f->length / td->touches_by_report;
673+ td->last_slot_field = f->usages[field_count_per_touch - 1];
674+ }
675+}
676+
656677 static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
657678 {
658679 int ret, i;
@@ -683,6 +704,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 24 unmodified lines
683704 td->maxcontact_report_id = -1;
684705 hid_set_drvdata(hdev, td);
685706
707+ td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL);
708+ if (!td->fields) {
709+ dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
710+ ret = -ENOMEM;
711+ goto fail;
712+ }
713+
686714 ret = hid_parse(hdev);
687715 if (ret != 0)
688716 goto fail;
@@ -691,6 +719,8 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 2 unmodified lines
691719 if (ret)
692720 goto fail;
693721
722+ mt_post_parse(td);
723+
694724 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
695725 mt_post_parse_default_settings(td);
696726
@@ -708,9 +738,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 11 unmodified lines
708738 mt_set_maxcontacts(hdev);
709739 mt_set_input_mode(hdev);
710740
741+ kfree(td->fields);
742+ td->fields = NULL;
743+
711744 return 0;
712745
713746 fail:
747+ kfree(td->fields);
714748 kfree(td);
715749 return ret;
716750 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t