wacom_sys.c (4247f24c23589bcc3bc3490515ef8c9497e9ae55) wacom_sys.c (83417206427bdf0fef9fa69957807194f25923c3)
1/*
2 * drivers/input/tablet/wacom_sys.c
3 *
4 * USB Wacom tablet support - system specific code
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify

--- 42 unchanged lines hidden (view full) ---

51
52 if (retval < 0)
53 hid_err(hdev, "wacom_set_report: ran out of retries "
54 "(last error = %d)\n", retval);
55
56 return retval;
57}
58
1/*
2 * drivers/input/tablet/wacom_sys.c
3 *
4 * USB Wacom tablet support - system specific code
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify

--- 42 unchanged lines hidden (view full) ---

51
52 if (retval < 0)
53 hid_err(hdev, "wacom_set_report: ran out of retries "
54 "(last error = %d)\n", retval);
55
56 return retval;
57}
58
59static void wacom_wac_queue_insert(struct hid_device *hdev,
60 struct kfifo_rec_ptr_2 *fifo,
61 u8 *raw_data, int size)
62{
63 bool warned = false;
64
65 while (kfifo_avail(fifo) < size) {
66 if (!warned)
67 hid_warn(hdev, "%s: kfifo has filled, starting to drop events\n", __func__);
68 warned = true;
69
70 kfifo_skip(fifo);
71 }
72
73 kfifo_in(fifo, raw_data, size);
74}
75
76static void wacom_wac_queue_flush(struct hid_device *hdev,
77 struct kfifo_rec_ptr_2 *fifo)
78{
79 while (!kfifo_is_empty(fifo)) {
80 u8 buf[WACOM_PKGLEN_MAX];
81 int size;
82 int err;
83
84 size = kfifo_out(fifo, buf, sizeof(buf));
85 err = hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, false);
86 if (err) {
87 hid_warn(hdev, "%s: unable to flush event due to error %d\n",
88 __func__, err);
89 }
90 }
91}
92
93static int wacom_wac_pen_serial_enforce(struct hid_device *hdev,
94 struct hid_report *report, u8 *raw_data, int size)
95{
96 struct wacom *wacom = hid_get_drvdata(hdev);
97 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
98 struct wacom_features *features = &wacom_wac->features;
99 bool flush = false;
100 bool insert = false;
101 int i, j;
102
103 if (wacom_wac->serial[0] || !(features->quirks & WACOM_QUIRK_TOOLSERIAL))
104 return 0;
105
106 /* Queue events which have invalid tool type or serial number */
107 for (i = 0; i < report->maxfield; i++) {
108 for (j = 0; j < report->field[i]->maxusage; j++) {
109 struct hid_field *field = report->field[i];
110 struct hid_usage *usage = &field->usage[j];
111 unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
112 unsigned int offset;
113 unsigned int size;
114 unsigned int value;
115
116 if (equivalent_usage != HID_DG_INRANGE &&
117 equivalent_usage != HID_DG_TOOLSERIALNUMBER &&
118 equivalent_usage != WACOM_HID_WD_SERIALHI &&
119 equivalent_usage != WACOM_HID_WD_TOOLTYPE)
120 continue;
121
122 offset = field->report_offset;
123 size = field->report_size;
124 value = hid_field_extract(hdev, raw_data+1, offset + j * size, size);
125
126 /* If we go out of range, we need to flush the queue ASAP */
127 if (equivalent_usage == HID_DG_INRANGE)
128 value = !value;
129
130 if (value) {
131 flush = true;
132 switch (equivalent_usage) {
133 case HID_DG_TOOLSERIALNUMBER:
134 wacom_wac->serial[0] = value;
135 break;
136
137 case WACOM_HID_WD_SERIALHI:
138 wacom_wac->serial[0] |= ((__u64)value) << 32;
139 break;
140
141 case WACOM_HID_WD_TOOLTYPE:
142 wacom_wac->id[0] = value;
143 break;
144 }
145 }
146 else {
147 insert = true;
148 }
149 }
150 }
151
152 if (flush)
153 wacom_wac_queue_flush(hdev, &wacom_wac->pen_fifo);
154 else if (insert)
155 wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, raw_data, size);
156
157 return insert && !flush;
158}
159
59static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
60 u8 *raw_data, int size)
61{
62 struct wacom *wacom = hid_get_drvdata(hdev);
63
64 if (size > WACOM_PKGLEN_MAX)
65 return 1;
66
160static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
161 u8 *raw_data, int size)
162{
163 struct wacom *wacom = hid_get_drvdata(hdev);
164
165 if (size > WACOM_PKGLEN_MAX)
166 return 1;
167
168 if (wacom_wac_pen_serial_enforce(hdev, report, raw_data, size))
169 return -1;
170
67 memcpy(wacom->wacom_wac.data, raw_data, size);
68
69 wacom_wac_irq(&wacom->wacom_wac, size);
70
71 return 0;
72}
73
74static int wacom_open(struct input_dev *dev)

--- 116 unchanged lines hidden (view full) ---

191 data, n, 0);
192 } else {
193 hid_warn(hdev, "%s: could not retrieve sensor offsets\n",
194 __func__);
195 }
196 kfree(data);
197 break;
198 }
171 memcpy(wacom->wacom_wac.data, raw_data, size);
172
173 wacom_wac_irq(&wacom->wacom_wac, size);
174
175 return 0;
176}
177
178static int wacom_open(struct input_dev *dev)

--- 116 unchanged lines hidden (view full) ---

295 data, n, 0);
296 } else {
297 hid_warn(hdev, "%s: could not retrieve sensor offsets\n",
298 __func__);
299 }
300 kfree(data);
301 break;
302 }
303
304 if (hdev->vendor == USB_VENDOR_ID_WACOM &&
305 hdev->product == 0x4200 /* Dell Canvas 27 */ &&
306 field->application == HID_UP_MSVENDOR) {
307 wacom->wacom_wac.mode_report = field->report->id;
308 wacom->wacom_wac.mode_value = 2;
309 }
199}
200
201/*
202 * Interface Descriptor of wacom devices can be incomplete and
203 * inconsistent so wacom_features table is used to store stylus
204 * device's packet lengths, various maximum values, and tablet
205 * resolution based on product ID's.
206 *

--- 2361 unchanged lines hidden (view full) ---

2568 wacom_wac->features = *((struct wacom_features *)id->driver_data);
2569 features = &wacom_wac->features;
2570
2571 if (features->check_for_hid_type && features->hid_type != hdev->type) {
2572 error = -ENODEV;
2573 goto fail;
2574 }
2575
310}
311
312/*
313 * Interface Descriptor of wacom devices can be incomplete and
314 * inconsistent so wacom_features table is used to store stylus
315 * device's packet lengths, various maximum values, and tablet
316 * resolution based on product ID's.
317 *

--- 2361 unchanged lines hidden (view full) ---

2679 wacom_wac->features = *((struct wacom_features *)id->driver_data);
2680 features = &wacom_wac->features;
2681
2682 if (features->check_for_hid_type && features->hid_type != hdev->type) {
2683 error = -ENODEV;
2684 goto fail;
2685 }
2686
2687 error = kfifo_alloc(&wacom_wac->pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL);
2688 if (error)
2689 goto fail;
2690
2576 wacom_wac->hid_data.inputmode = -1;
2577 wacom_wac->mode_report = -1;
2578
2579 wacom->usbdev = dev;
2580 wacom->intf = intf;
2581 mutex_init(&wacom->lock);
2582 INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work);
2583 INIT_WORK(&wacom->wireless_work, wacom_wireless_work);

--- 47 unchanged lines hidden (view full) ---

2631 device_remove_file(&hdev->dev, &dev_attr_speed);
2632
2633 /* make sure we don't trigger the LEDs */
2634 wacom_led_groups_release(wacom);
2635
2636 if (wacom->wacom_wac.features.type != REMOTE)
2637 wacom_release_resources(wacom);
2638
2691 wacom_wac->hid_data.inputmode = -1;
2692 wacom_wac->mode_report = -1;
2693
2694 wacom->usbdev = dev;
2695 wacom->intf = intf;
2696 mutex_init(&wacom->lock);
2697 INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work);
2698 INIT_WORK(&wacom->wireless_work, wacom_wireless_work);

--- 47 unchanged lines hidden (view full) ---

2746 device_remove_file(&hdev->dev, &dev_attr_speed);
2747
2748 /* make sure we don't trigger the LEDs */
2749 wacom_led_groups_release(wacom);
2750
2751 if (wacom->wacom_wac.features.type != REMOTE)
2752 wacom_release_resources(wacom);
2753
2754 kfifo_free(&wacom_wac->pen_fifo);
2755
2639 hid_set_drvdata(hdev, NULL);
2640}
2641
2642#ifdef CONFIG_PM
2643static int wacom_resume(struct hid_device *hdev)
2644{
2645 struct wacom *wacom = hid_get_drvdata(hdev);
2646

--- 35 unchanged lines hidden ---
2756 hid_set_drvdata(hdev, NULL);
2757}
2758
2759#ifdef CONFIG_PM
2760static int wacom_resume(struct hid_device *hdev)
2761{
2762 struct wacom *wacom = hid_get_drvdata(hdev);
2763

--- 35 unchanged lines hidden ---