Merge remote-tracking branches 'spi/topic/ti-qspi' and 'spi/topic/topcliff-pch' into...
[sfrench/cifs-2.6.git] / drivers / hid / hid-udraw-ps3.c
1 /*
2  * HID driver for THQ PS3 uDraw tablet
3  *
4  * Copyright (C) 2016 Red Hat Inc. All Rights Reserved
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 #include <linux/device.h>
17 #include <linux/hid.h>
18 #include <linux/module.h>
19 #include "hid-ids.h"
20
21 MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
22 MODULE_DESCRIPTION("PS3 uDraw tablet driver");
23 MODULE_LICENSE("GPL");
24
25 /*
26  * Protocol information from:
27  * http://brandonw.net/udraw/
28  * and the source code of:
29  * https://vvvv.org/contribution/udraw-hid
30  */
31
32 /*
33  * The device is setup with multiple input devices:
34  * - the touch area which works as a touchpad
35  * - the tablet area which works as a touchpad/drawing tablet
36  * - a joypad with a d-pad, and 7 buttons
37  * - an accelerometer device
38  */
39
40 enum {
41         TOUCH_NONE,
42         TOUCH_PEN,
43         TOUCH_FINGER,
44         TOUCH_TWOFINGER
45 };
46
47 enum {
48         AXIS_X,
49         AXIS_Y,
50         AXIS_Z
51 };
52
53 /*
54  * Accelerometer min/max values
55  * in order, X, Y and Z
56  */
57 static struct {
58         int min;
59         int max;
60 } accel_limits[] = {
61         [AXIS_X] = { 490, 534 },
62         [AXIS_Y] = { 490, 534 },
63         [AXIS_Z] = { 492, 536 }
64 };
65
66 #define DEVICE_NAME "THQ uDraw Game Tablet for PS3"
67 /* resolution in pixels */
68 #define RES_X 1920
69 #define RES_Y 1080
70 /* size in mm */
71 #define WIDTH  160
72 #define HEIGHT 90
73 #define PRESSURE_OFFSET 113
74 #define MAX_PRESSURE (255 - PRESSURE_OFFSET)
75
76 struct udraw {
77         struct input_dev *joy_input_dev;
78         struct input_dev *touch_input_dev;
79         struct input_dev *pen_input_dev;
80         struct input_dev *accel_input_dev;
81         struct hid_device *hdev;
82
83         /*
84          * The device's two-finger support is pretty unreliable, as
85          * the device could report a single touch when the two fingers
86          * are too close together, and the distance between fingers, even
87          * though reported is not in the same unit as the touches.
88          *
89          * We'll make do without it, and try to report the first touch
90          * as reliably as possible.
91          */
92         int last_one_finger_x;
93         int last_one_finger_y;
94         int last_two_finger_x;
95         int last_two_finger_y;
96 };
97
98 static int clamp_accel(int axis, int offset)
99 {
100         axis = clamp(axis,
101                         accel_limits[offset].min,
102                         accel_limits[offset].max);
103         axis = (axis - accel_limits[offset].min) /
104                         ((accel_limits[offset].max -
105                           accel_limits[offset].min) * 0xFF);
106         return axis;
107 }
108
109 static int udraw_raw_event(struct hid_device *hdev, struct hid_report *report,
110          u8 *data, int len)
111 {
112         struct udraw *udraw = hid_get_drvdata(hdev);
113         int touch;
114         int x, y, z;
115
116         if (len != 27)
117                 return 0;
118
119         if (data[11] == 0x00)
120                 touch = TOUCH_NONE;
121         else if (data[11] == 0x40)
122                 touch = TOUCH_PEN;
123         else if (data[11] == 0x80)
124                 touch = TOUCH_FINGER;
125         else
126                 touch = TOUCH_TWOFINGER;
127
128         /* joypad */
129         input_report_key(udraw->joy_input_dev, BTN_WEST, data[0] & 1);
130         input_report_key(udraw->joy_input_dev, BTN_SOUTH, !!(data[0] & 2));
131         input_report_key(udraw->joy_input_dev, BTN_EAST, !!(data[0] & 4));
132         input_report_key(udraw->joy_input_dev, BTN_NORTH, !!(data[0] & 8));
133
134         input_report_key(udraw->joy_input_dev, BTN_SELECT, !!(data[1] & 1));
135         input_report_key(udraw->joy_input_dev, BTN_START, !!(data[1] & 2));
136         input_report_key(udraw->joy_input_dev, BTN_MODE, !!(data[1] & 16));
137
138         x = y = 0;
139         switch (data[2]) {
140         case 0x0:
141                 y = -127;
142                 break;
143         case 0x1:
144                 y = -127;
145                 x = 127;
146                 break;
147         case 0x2:
148                 x = 127;
149                 break;
150         case 0x3:
151                 y = 127;
152                 x = 127;
153                 break;
154         case 0x4:
155                 y = 127;
156                 break;
157         case 0x5:
158                 y = 127;
159                 x = -127;
160                 break;
161         case 0x6:
162                 x = -127;
163                 break;
164         case 0x7:
165                 y = -127;
166                 x = -127;
167                 break;
168         default:
169                 break;
170         }
171
172         input_report_abs(udraw->joy_input_dev, ABS_X, x);
173         input_report_abs(udraw->joy_input_dev, ABS_Y, y);
174
175         input_sync(udraw->joy_input_dev);
176
177         /* For pen and touchpad */
178         x = y = 0;
179         if (touch != TOUCH_NONE) {
180                 if (data[15] != 0x0F)
181                         x = data[15] * 256 + data[17];
182                 if (data[16] != 0x0F)
183                         y = data[16] * 256 + data[18];
184         }
185
186         if (touch == TOUCH_FINGER) {
187                 /* Save the last one-finger touch */
188                 udraw->last_one_finger_x = x;
189                 udraw->last_one_finger_y = y;
190                 udraw->last_two_finger_x = -1;
191                 udraw->last_two_finger_y = -1;
192         } else if (touch == TOUCH_TWOFINGER) {
193                 /*
194                  * We have a problem because x/y is the one for the
195                  * second finger but we want the first finger given
196                  * to user-space otherwise it'll look as if it jumped.
197                  *
198                  * See the udraw struct definition for why this was
199                  * implemented this way.
200                  */
201                 if (udraw->last_two_finger_x == -1) {
202                         /* Save the position of the 2nd finger */
203                         udraw->last_two_finger_x = x;
204                         udraw->last_two_finger_y = y;
205
206                         x = udraw->last_one_finger_x;
207                         y = udraw->last_one_finger_y;
208                 } else {
209                         /*
210                          * Offset the 2-finger coords using the
211                          * saved data from the first finger
212                          */
213                         x = x - (udraw->last_two_finger_x
214                                 - udraw->last_one_finger_x);
215                         y = y - (udraw->last_two_finger_y
216                                 - udraw->last_one_finger_y);
217                 }
218         }
219
220         /* touchpad */
221         if (touch == TOUCH_FINGER || touch == TOUCH_TWOFINGER) {
222                 input_report_key(udraw->touch_input_dev, BTN_TOUCH, 1);
223                 input_report_key(udraw->touch_input_dev, BTN_TOOL_FINGER,
224                                 touch == TOUCH_FINGER);
225                 input_report_key(udraw->touch_input_dev, BTN_TOOL_DOUBLETAP,
226                                 touch == TOUCH_TWOFINGER);
227
228                 input_report_abs(udraw->touch_input_dev, ABS_X, x);
229                 input_report_abs(udraw->touch_input_dev, ABS_Y, y);
230         } else {
231                 input_report_key(udraw->touch_input_dev, BTN_TOUCH, 0);
232                 input_report_key(udraw->touch_input_dev, BTN_TOOL_FINGER, 0);
233                 input_report_key(udraw->touch_input_dev, BTN_TOOL_DOUBLETAP, 0);
234         }
235         input_sync(udraw->touch_input_dev);
236
237         /* pen */
238         if (touch == TOUCH_PEN) {
239                 int level;
240
241                 level = clamp(data[13] - PRESSURE_OFFSET,
242                                 0, MAX_PRESSURE);
243
244                 input_report_key(udraw->pen_input_dev, BTN_TOUCH, (level != 0));
245                 input_report_key(udraw->pen_input_dev, BTN_TOOL_PEN, 1);
246                 input_report_abs(udraw->pen_input_dev, ABS_PRESSURE, level);
247                 input_report_abs(udraw->pen_input_dev, ABS_X, x);
248                 input_report_abs(udraw->pen_input_dev, ABS_Y, y);
249         } else {
250                 input_report_key(udraw->pen_input_dev, BTN_TOUCH, 0);
251                 input_report_key(udraw->pen_input_dev, BTN_TOOL_PEN, 0);
252                 input_report_abs(udraw->pen_input_dev, ABS_PRESSURE, 0);
253         }
254         input_sync(udraw->pen_input_dev);
255
256         /* accel */
257         x = (data[19] + (data[20] << 8));
258         x = clamp_accel(x, AXIS_X);
259         y = (data[21] + (data[22] << 8));
260         y = clamp_accel(y, AXIS_Y);
261         z = (data[23] + (data[24] << 8));
262         z = clamp_accel(z, AXIS_Z);
263         input_report_abs(udraw->accel_input_dev, ABS_X, x);
264         input_report_abs(udraw->accel_input_dev, ABS_Y, y);
265         input_report_abs(udraw->accel_input_dev, ABS_Z, z);
266         input_sync(udraw->accel_input_dev);
267
268         /* let hidraw and hiddev handle the report */
269         return 0;
270 }
271
272 static int udraw_open(struct input_dev *dev)
273 {
274         struct udraw *udraw = input_get_drvdata(dev);
275
276         return hid_hw_open(udraw->hdev);
277 }
278
279 static void udraw_close(struct input_dev *dev)
280 {
281         struct udraw *udraw = input_get_drvdata(dev);
282
283         hid_hw_close(udraw->hdev);
284 }
285
286 static struct input_dev *allocate_and_setup(struct hid_device *hdev,
287                 const char *name)
288 {
289         struct input_dev *input_dev;
290
291         input_dev = devm_input_allocate_device(&hdev->dev);
292         if (!input_dev)
293                 return NULL;
294
295         input_dev->name = name;
296         input_dev->phys = hdev->phys;
297         input_dev->dev.parent = &hdev->dev;
298         input_dev->open = udraw_open;
299         input_dev->close = udraw_close;
300         input_dev->uniq = hdev->uniq;
301         input_dev->id.bustype = hdev->bus;
302         input_dev->id.vendor  = hdev->vendor;
303         input_dev->id.product = hdev->product;
304         input_dev->id.version = hdev->version;
305         input_set_drvdata(input_dev, hid_get_drvdata(hdev));
306
307         return input_dev;
308 }
309
310 static bool udraw_setup_touch(struct udraw *udraw,
311                 struct hid_device *hdev)
312 {
313         struct input_dev *input_dev;
314
315         input_dev = allocate_and_setup(hdev, DEVICE_NAME " Touchpad");
316         if (!input_dev)
317                 return false;
318
319         input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
320
321         input_set_abs_params(input_dev, ABS_X, 0, RES_X, 1, 0);
322         input_abs_set_res(input_dev, ABS_X, RES_X / WIDTH);
323         input_set_abs_params(input_dev, ABS_Y, 0, RES_Y, 1, 0);
324         input_abs_set_res(input_dev, ABS_Y, RES_Y / HEIGHT);
325
326         set_bit(BTN_TOUCH, input_dev->keybit);
327         set_bit(BTN_TOOL_FINGER, input_dev->keybit);
328         set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
329
330         set_bit(INPUT_PROP_POINTER, input_dev->propbit);
331
332         udraw->touch_input_dev = input_dev;
333
334         return true;
335 }
336
337 static bool udraw_setup_pen(struct udraw *udraw,
338                 struct hid_device *hdev)
339 {
340         struct input_dev *input_dev;
341
342         input_dev = allocate_and_setup(hdev, DEVICE_NAME " Pen");
343         if (!input_dev)
344                 return false;
345
346         input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
347
348         input_set_abs_params(input_dev, ABS_X, 0, RES_X, 1, 0);
349         input_abs_set_res(input_dev, ABS_X, RES_X / WIDTH);
350         input_set_abs_params(input_dev, ABS_Y, 0, RES_Y, 1, 0);
351         input_abs_set_res(input_dev, ABS_Y, RES_Y / HEIGHT);
352         input_set_abs_params(input_dev, ABS_PRESSURE,
353                         0, MAX_PRESSURE, 0, 0);
354
355         set_bit(BTN_TOUCH, input_dev->keybit);
356         set_bit(BTN_TOOL_PEN, input_dev->keybit);
357
358         set_bit(INPUT_PROP_POINTER, input_dev->propbit);
359
360         udraw->pen_input_dev = input_dev;
361
362         return true;
363 }
364
365 static bool udraw_setup_accel(struct udraw *udraw,
366                 struct hid_device *hdev)
367 {
368         struct input_dev *input_dev;
369
370         input_dev = allocate_and_setup(hdev, DEVICE_NAME " Accelerometer");
371         if (!input_dev)
372                 return false;
373
374         input_dev->evbit[0] = BIT(EV_ABS);
375
376         /* 1G accel is reported as ~256, so clamp to 2G */
377         input_set_abs_params(input_dev, ABS_X, -512, 512, 0, 0);
378         input_set_abs_params(input_dev, ABS_Y, -512, 512, 0, 0);
379         input_set_abs_params(input_dev, ABS_Z, -512, 512, 0, 0);
380
381         set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit);
382
383         udraw->accel_input_dev = input_dev;
384
385         return true;
386 }
387
388 static bool udraw_setup_joypad(struct udraw *udraw,
389                 struct hid_device *hdev)
390 {
391         struct input_dev *input_dev;
392
393         input_dev = allocate_and_setup(hdev, DEVICE_NAME " Joypad");
394         if (!input_dev)
395                 return false;
396
397         input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
398
399         set_bit(BTN_SOUTH, input_dev->keybit);
400         set_bit(BTN_NORTH, input_dev->keybit);
401         set_bit(BTN_EAST, input_dev->keybit);
402         set_bit(BTN_WEST, input_dev->keybit);
403         set_bit(BTN_SELECT, input_dev->keybit);
404         set_bit(BTN_START, input_dev->keybit);
405         set_bit(BTN_MODE, input_dev->keybit);
406
407         input_set_abs_params(input_dev, ABS_X, -127, 127, 0, 0);
408         input_set_abs_params(input_dev, ABS_Y, -127, 127, 0, 0);
409
410         udraw->joy_input_dev = input_dev;
411
412         return true;
413 }
414
415 static int udraw_probe(struct hid_device *hdev, const struct hid_device_id *id)
416 {
417         struct udraw *udraw;
418         int ret;
419
420         udraw = devm_kzalloc(&hdev->dev, sizeof(struct udraw), GFP_KERNEL);
421         if (!udraw)
422                 return -ENOMEM;
423
424         udraw->hdev = hdev;
425         udraw->last_two_finger_x = -1;
426         udraw->last_two_finger_y = -1;
427
428         hid_set_drvdata(hdev, udraw);
429
430         ret = hid_parse(hdev);
431         if (ret) {
432                 hid_err(hdev, "parse failed\n");
433                 return ret;
434         }
435
436         if (!udraw_setup_joypad(udraw, hdev) ||
437             !udraw_setup_touch(udraw, hdev) ||
438             !udraw_setup_pen(udraw, hdev) ||
439             !udraw_setup_accel(udraw, hdev)) {
440                 hid_err(hdev, "could not allocate interfaces\n");
441                 return -ENOMEM;
442         }
443
444         ret = input_register_device(udraw->joy_input_dev) ||
445                 input_register_device(udraw->touch_input_dev) ||
446                 input_register_device(udraw->pen_input_dev) ||
447                 input_register_device(udraw->accel_input_dev);
448         if (ret) {
449                 hid_err(hdev, "failed to register interfaces\n");
450                 return ret;
451         }
452
453         ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW | HID_CONNECT_DRIVER);
454         if (ret) {
455                 hid_err(hdev, "hw start failed\n");
456                 return ret;
457         }
458
459         return 0;
460 }
461
462 static const struct hid_device_id udraw_devices[] = {
463         { HID_USB_DEVICE(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW) },
464         { }
465 };
466 MODULE_DEVICE_TABLE(hid, udraw_devices);
467
468 static struct hid_driver udraw_driver = {
469         .name = "hid-udraw",
470         .id_table = udraw_devices,
471         .raw_event = udraw_raw_event,
472         .probe = udraw_probe,
473 };
474 module_hid_driver(udraw_driver);