ACPI: clean up white space in a few places for consistency
[sfrench/cifs-2.6.git] / drivers / hid / hid-uclogic-core.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  HID driver for UC-Logic devices not fully compliant with HID standard
4  *
5  *  Copyright (c) 2010-2014 Nikolai Kondrashov
6  *  Copyright (c) 2013 Martin Rusko
7  */
8
9 /*
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by the Free
12  * Software Foundation; either version 2 of the License, or (at your option)
13  * any later version.
14  */
15
16 #include <linux/device.h>
17 #include <linux/hid.h>
18 #include <linux/module.h>
19 #include <linux/timer.h>
20 #include "usbhid/usbhid.h"
21 #include "hid-uclogic-params.h"
22
23 #include "hid-ids.h"
24
25 /* Driver data */
26 struct uclogic_drvdata {
27         /* Interface parameters */
28         struct uclogic_params params;
29         /* Pointer to the replacement report descriptor. NULL if none. */
30         __u8 *desc_ptr;
31         /*
32          * Size of the replacement report descriptor.
33          * Only valid if desc_ptr is not NULL
34          */
35         unsigned int desc_size;
36         /* Pen input device */
37         struct input_dev *pen_input;
38         /* In-range timer */
39         struct timer_list inrange_timer;
40         /* Last rotary encoder state, or U8_MAX for none */
41         u8 re_state;
42 };
43
44 /**
45  * uclogic_inrange_timeout - handle pen in-range state timeout.
46  * Emulate input events normally generated when pen goes out of range for
47  * tablets which don't report that.
48  *
49  * @t:  The timer the timeout handler is attached to, stored in a struct
50  *      uclogic_drvdata.
51  */
52 static void uclogic_inrange_timeout(struct timer_list *t)
53 {
54         struct uclogic_drvdata *drvdata = from_timer(drvdata, t,
55                                                         inrange_timer);
56         struct input_dev *input = drvdata->pen_input;
57
58         if (input == NULL)
59                 return;
60         input_report_abs(input, ABS_PRESSURE, 0);
61         /* If BTN_TOUCH state is changing */
62         if (test_bit(BTN_TOUCH, input->key)) {
63                 input_event(input, EV_MSC, MSC_SCAN,
64                                 /* Digitizer Tip Switch usage */
65                                 0xd0042);
66                 input_report_key(input, BTN_TOUCH, 0);
67         }
68         input_report_key(input, BTN_TOOL_PEN, 0);
69         input_sync(input);
70 }
71
72 static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
73                                         unsigned int *rsize)
74 {
75         struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
76
77         if (drvdata->desc_ptr != NULL) {
78                 rdesc = drvdata->desc_ptr;
79                 *rsize = drvdata->desc_size;
80         }
81         return rdesc;
82 }
83
84 static int uclogic_input_configured(struct hid_device *hdev,
85                 struct hid_input *hi)
86 {
87         struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
88         struct uclogic_params *params = &drvdata->params;
89         char *name;
90         const char *suffix = NULL;
91         struct hid_field *field;
92         size_t len;
93
94         /* no report associated (HID_QUIRK_MULTI_INPUT not set) */
95         if (!hi->report)
96                 return 0;
97
98         /*
99          * If this is the input corresponding to the pen report
100          * in need of tweaking.
101          */
102         if (hi->report->id == params->pen.id) {
103                 /* Remember the input device so we can simulate events */
104                 drvdata->pen_input = hi->input;
105         }
106
107         field = hi->report->field[0];
108
109         switch (field->application) {
110         case HID_GD_KEYBOARD:
111                 suffix = "Keyboard";
112                 break;
113         case HID_GD_MOUSE:
114                 suffix = "Mouse";
115                 break;
116         case HID_GD_KEYPAD:
117                 suffix = "Pad";
118                 break;
119         case HID_DG_PEN:
120                 suffix = "Pen";
121                 break;
122         case HID_CP_CONSUMER_CONTROL:
123                 suffix = "Consumer Control";
124                 break;
125         case HID_GD_SYSTEM_CONTROL:
126                 suffix = "System Control";
127                 break;
128         }
129
130         if (suffix) {
131                 len = strlen(hdev->name) + 2 + strlen(suffix);
132                 name = devm_kzalloc(&hi->input->dev, len, GFP_KERNEL);
133                 if (name) {
134                         snprintf(name, len, "%s %s", hdev->name, suffix);
135                         hi->input->name = name;
136                 }
137         }
138
139         return 0;
140 }
141
142 static int uclogic_probe(struct hid_device *hdev,
143                 const struct hid_device_id *id)
144 {
145         int rc;
146         struct uclogic_drvdata *drvdata = NULL;
147         bool params_initialized = false;
148
149         if (!hid_is_usb(hdev))
150                 return -EINVAL;
151
152         /*
153          * libinput requires the pad interface to be on a different node
154          * than the pen, so use QUIRK_MULTI_INPUT for all tablets.
155          */
156         hdev->quirks |= HID_QUIRK_MULTI_INPUT;
157
158         /* Allocate and assign driver data */
159         drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
160         if (drvdata == NULL) {
161                 rc = -ENOMEM;
162                 goto failure;
163         }
164         timer_setup(&drvdata->inrange_timer, uclogic_inrange_timeout, 0);
165         drvdata->re_state = U8_MAX;
166         hid_set_drvdata(hdev, drvdata);
167
168         /* Initialize the device and retrieve interface parameters */
169         rc = uclogic_params_init(&drvdata->params, hdev);
170         if (rc != 0) {
171                 hid_err(hdev, "failed probing parameters: %d\n", rc);
172                 goto failure;
173         }
174         params_initialized = true;
175         hid_dbg(hdev, "parameters:\n" UCLOGIC_PARAMS_FMT_STR,
176                 UCLOGIC_PARAMS_FMT_ARGS(&drvdata->params));
177         if (drvdata->params.invalid) {
178                 hid_info(hdev, "interface is invalid, ignoring\n");
179                 rc = -ENODEV;
180                 goto failure;
181         }
182
183         /* Generate replacement report descriptor */
184         rc = uclogic_params_get_desc(&drvdata->params,
185                                      &drvdata->desc_ptr,
186                                      &drvdata->desc_size);
187         if (rc) {
188                 hid_err(hdev,
189                         "failed generating replacement report descriptor: %d\n",
190                         rc);
191                 goto failure;
192         }
193
194         rc = hid_parse(hdev);
195         if (rc) {
196                 hid_err(hdev, "parse failed\n");
197                 goto failure;
198         }
199
200         rc = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
201         if (rc) {
202                 hid_err(hdev, "hw start failed\n");
203                 goto failure;
204         }
205
206         return 0;
207 failure:
208         /* Assume "remove" might not be called if "probe" failed */
209         if (params_initialized)
210                 uclogic_params_cleanup(&drvdata->params);
211         return rc;
212 }
213
214 #ifdef CONFIG_PM
215 static int uclogic_resume(struct hid_device *hdev)
216 {
217         int rc;
218         struct uclogic_params params;
219
220         /* Re-initialize the device, but discard parameters */
221         rc = uclogic_params_init(&params, hdev);
222         if (rc != 0)
223                 hid_err(hdev, "failed to re-initialize the device\n");
224         else
225                 uclogic_params_cleanup(&params);
226
227         return rc;
228 }
229 #endif
230
231 /**
232  * uclogic_raw_event_pen - handle raw pen events (pen HID reports).
233  *
234  * @drvdata:    Driver data.
235  * @data:       Report data buffer, can be modified.
236  * @size:       Report data size, bytes.
237  *
238  * Returns:
239  *      Negative value on error (stops event delivery), zero for success.
240  */
241 static int uclogic_raw_event_pen(struct uclogic_drvdata *drvdata,
242                                         u8 *data, int size)
243 {
244         struct uclogic_params_pen *pen = &drvdata->params.pen;
245
246         WARN_ON(drvdata == NULL);
247         WARN_ON(data == NULL && size != 0);
248
249         /* If in-range reports are inverted */
250         if (pen->inrange ==
251                 UCLOGIC_PARAMS_PEN_INRANGE_INVERTED) {
252                 /* Invert the in-range bit */
253                 data[1] ^= 0x40;
254         }
255         /*
256          * If report contains fragmented high-resolution pen
257          * coordinates
258          */
259         if (size >= 10 && pen->fragmented_hires) {
260                 u8 pressure_low_byte;
261                 u8 pressure_high_byte;
262
263                 /* Lift pressure bytes */
264                 pressure_low_byte = data[6];
265                 pressure_high_byte = data[7];
266                 /*
267                  * Move Y coord to make space for high-order X
268                  * coord byte
269                  */
270                 data[6] = data[5];
271                 data[5] = data[4];
272                 /* Move high-order X coord byte */
273                 data[4] = data[8];
274                 /* Move high-order Y coord byte */
275                 data[7] = data[9];
276                 /* Place pressure bytes */
277                 data[8] = pressure_low_byte;
278                 data[9] = pressure_high_byte;
279         }
280         /* If we need to emulate in-range detection */
281         if (pen->inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE) {
282                 /* Set in-range bit */
283                 data[1] |= 0x40;
284                 /* (Re-)start in-range timeout */
285                 mod_timer(&drvdata->inrange_timer,
286                                 jiffies + msecs_to_jiffies(100));
287         }
288         /* If we report tilt and Y direction is flipped */
289         if (size >= 12 && pen->tilt_y_flipped)
290                 data[11] = -data[11];
291
292         return 0;
293 }
294
295 /**
296  * uclogic_raw_event_frame - handle raw frame events (frame HID reports).
297  *
298  * @drvdata:    Driver data.
299  * @frame:      The parameters of the frame controls to handle.
300  * @data:       Report data buffer, can be modified.
301  * @size:       Report data size, bytes.
302  *
303  * Returns:
304  *      Negative value on error (stops event delivery), zero for success.
305  */
306 static int uclogic_raw_event_frame(
307                 struct uclogic_drvdata *drvdata,
308                 const struct uclogic_params_frame *frame,
309                 u8 *data, int size)
310 {
311         WARN_ON(drvdata == NULL);
312         WARN_ON(data == NULL && size != 0);
313
314         /* If need to, and can, set pad device ID for Wacom drivers */
315         if (frame->dev_id_byte > 0 && frame->dev_id_byte < size) {
316                 data[frame->dev_id_byte] = 0xf;
317         }
318         /* If need to, and can, read rotary encoder state change */
319         if (frame->re_lsb > 0 && frame->re_lsb / 8 < size) {
320                 unsigned int byte = frame->re_lsb / 8;
321                 unsigned int bit = frame->re_lsb % 8;
322
323                 u8 change;
324                 u8 prev_state = drvdata->re_state;
325                 /* Read Gray-coded state */
326                 u8 state = (data[byte] >> bit) & 0x3;
327                 /* Encode state change into 2-bit signed integer */
328                 if ((prev_state == 1 && state == 0) ||
329                     (prev_state == 2 && state == 3)) {
330                         change = 1;
331                 } else if ((prev_state == 2 && state == 0) ||
332                            (prev_state == 1 && state == 3)) {
333                         change = 3;
334                 } else {
335                         change = 0;
336                 }
337                 /* Write change */
338                 data[byte] = (data[byte] & ~((u8)3 << bit)) |
339                                 (change << bit);
340                 /* Remember state */
341                 drvdata->re_state = state;
342         }
343
344         return 0;
345 }
346
347 static int uclogic_raw_event(struct hid_device *hdev,
348                                 struct hid_report *report,
349                                 u8 *data, int size)
350 {
351         unsigned int report_id = report->id;
352         struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
353         struct uclogic_params *params = &drvdata->params;
354         struct uclogic_params_pen_subreport *subreport;
355         struct uclogic_params_pen_subreport *subreport_list_end;
356         size_t i;
357
358         /* Do not handle anything but input reports */
359         if (report->type != HID_INPUT_REPORT)
360                 return 0;
361
362         while (true) {
363                 /* Tweak pen reports, if necessary */
364                 if ((report_id == params->pen.id) && (size >= 2)) {
365                         subreport_list_end =
366                                 params->pen.subreport_list +
367                                 ARRAY_SIZE(params->pen.subreport_list);
368                         /* Try to match a subreport */
369                         for (subreport = params->pen.subreport_list;
370                              subreport < subreport_list_end; subreport++) {
371                                 if (subreport->value != 0 &&
372                                     subreport->value == data[1]) {
373                                         break;
374                                 }
375                         }
376                         /* If a subreport matched */
377                         if (subreport < subreport_list_end) {
378                                 /* Change to subreport ID, and restart */
379                                 report_id = data[0] = subreport->id;
380                                 continue;
381                         } else {
382                                 return uclogic_raw_event_pen(drvdata, data, size);
383                         }
384                 }
385
386                 /* Tweak frame control reports, if necessary */
387                 for (i = 0; i < ARRAY_SIZE(params->frame_list); i++) {
388                         if (report_id == params->frame_list[i].id) {
389                                 return uclogic_raw_event_frame(
390                                         drvdata, &params->frame_list[i],
391                                         data, size);
392                         }
393                 }
394
395                 break;
396         }
397
398         return 0;
399 }
400
401 static void uclogic_remove(struct hid_device *hdev)
402 {
403         struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev);
404
405         del_timer_sync(&drvdata->inrange_timer);
406         hid_hw_stop(hdev);
407         kfree(drvdata->desc_ptr);
408         uclogic_params_cleanup(&drvdata->params);
409 }
410
411 static const struct hid_device_id uclogic_devices[] = {
412         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
413                                 USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
414         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
415                                 USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
416         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
417                                 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
418         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
419                                 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
420         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
421                                 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
422         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
423                                 USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
424         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
425                                 USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) },
426         { HID_USB_DEVICE(USB_VENDOR_ID_HUION,
427                                 USB_DEVICE_ID_HUION_TABLET) },
428         { HID_USB_DEVICE(USB_VENDOR_ID_HUION,
429                                 USB_DEVICE_ID_HUION_TABLET2) },
430         { HID_USB_DEVICE(USB_VENDOR_ID_TRUST,
431                                 USB_DEVICE_ID_TRUST_PANORA_TABLET) },
432         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
433                                 USB_DEVICE_ID_HUION_TABLET) },
434         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
435                                 USB_DEVICE_ID_YIYNOVA_TABLET) },
436         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
437                                 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_81) },
438         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
439                                 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_45) },
440         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
441                                 USB_DEVICE_ID_UCLOGIC_UGEE_TABLET_47) },
442         { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
443                                 USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) },
444         { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
445                                 USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
446         { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
447                                 USB_DEVICE_ID_UGTIZER_TABLET_GT5040) },
448         { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
449                                 USB_DEVICE_ID_UGEE_TABLET_G5) },
450         { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
451                                 USB_DEVICE_ID_UGEE_TABLET_EX07S) },
452         { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
453                                 USB_DEVICE_ID_UGEE_TABLET_RAINBOW_CV720) },
454         { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
455                                 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540) },
456         { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
457                                 USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640) },
458         { HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
459                                 USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01) },
460         { }
461 };
462 MODULE_DEVICE_TABLE(hid, uclogic_devices);
463
464 static struct hid_driver uclogic_driver = {
465         .name = "uclogic",
466         .id_table = uclogic_devices,
467         .probe = uclogic_probe,
468         .remove = uclogic_remove,
469         .report_fixup = uclogic_report_fixup,
470         .raw_event = uclogic_raw_event,
471         .input_configured = uclogic_input_configured,
472 #ifdef CONFIG_PM
473         .resume           = uclogic_resume,
474         .reset_resume     = uclogic_resume,
475 #endif
476 };
477 module_hid_driver(uclogic_driver);
478
479 MODULE_AUTHOR("Martin Rusko");
480 MODULE_AUTHOR("Nikolai Kondrashov");
481 MODULE_LICENSE("GPL");