2 * HID driver for THQ PS3 uDraw tablet
4 * Copyright (C) 2016 Red Hat Inc. All Rights Reserved
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.
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.
16 #include <linux/device.h>
17 #include <linux/hid.h>
18 #include <linux/module.h>
21 MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
22 MODULE_DESCRIPTION("PS3 uDraw tablet driver");
23 MODULE_LICENSE("GPL");
26 * Protocol information from:
27 * http://brandonw.net/udraw/
28 * and the source code of:
29 * https://vvvv.org/contribution/udraw-hid
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
54 * Accelerometer min/max values
55 * in order, X, Y and Z
61 [AXIS_X
] = { 490, 534 },
62 [AXIS_Y
] = { 490, 534 },
63 [AXIS_Z
] = { 492, 536 }
66 #define DEVICE_NAME "THQ uDraw Game Tablet for PS3"
67 /* resolution in pixels */
73 #define PRESSURE_OFFSET 113
74 #define MAX_PRESSURE (255 - PRESSURE_OFFSET)
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
;
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.
89 * We'll make do without it, and try to report the first touch
90 * as reliably as possible.
92 int last_one_finger_x
;
93 int last_one_finger_y
;
94 int last_two_finger_x
;
95 int last_two_finger_y
;
98 static int clamp_accel(int axis
, int offset
)
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);
109 static int udraw_raw_event(struct hid_device
*hdev
, struct hid_report
*report
,
112 struct udraw
*udraw
= hid_get_drvdata(hdev
);
119 if (data
[11] == 0x00)
121 else if (data
[11] == 0x40)
123 else if (data
[11] == 0x80)
124 touch
= TOUCH_FINGER
;
126 touch
= TOUCH_TWOFINGER
;
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));
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));
172 input_report_abs(udraw
->joy_input_dev
, ABS_X
, x
);
173 input_report_abs(udraw
->joy_input_dev
, ABS_Y
, y
);
175 input_sync(udraw
->joy_input_dev
);
177 /* For pen and touchpad */
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];
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
) {
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.
198 * See the udraw struct definition for why this was
199 * implemented this way.
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
;
206 x
= udraw
->last_one_finger_x
;
207 y
= udraw
->last_one_finger_y
;
210 * Offset the 2-finger coords using the
211 * saved data from the first finger
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
);
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
);
228 input_report_abs(udraw
->touch_input_dev
, ABS_X
, x
);
229 input_report_abs(udraw
->touch_input_dev
, ABS_Y
, y
);
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);
235 input_sync(udraw
->touch_input_dev
);
238 if (touch
== TOUCH_PEN
) {
241 level
= clamp(data
[13] - PRESSURE_OFFSET
,
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
);
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);
254 input_sync(udraw
->pen_input_dev
);
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
);
268 /* let hidraw and hiddev handle the report */
272 static int udraw_open(struct input_dev
*dev
)
274 struct udraw
*udraw
= input_get_drvdata(dev
);
276 return hid_hw_open(udraw
->hdev
);
279 static void udraw_close(struct input_dev
*dev
)
281 struct udraw
*udraw
= input_get_drvdata(dev
);
283 hid_hw_close(udraw
->hdev
);
286 static struct input_dev
*allocate_and_setup(struct hid_device
*hdev
,
289 struct input_dev
*input_dev
;
291 input_dev
= devm_input_allocate_device(&hdev
->dev
);
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
));
310 static bool udraw_setup_touch(struct udraw
*udraw
,
311 struct hid_device
*hdev
)
313 struct input_dev
*input_dev
;
315 input_dev
= allocate_and_setup(hdev
, DEVICE_NAME
" Touchpad");
319 input_dev
->evbit
[0] = BIT(EV_ABS
) | BIT(EV_KEY
);
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
);
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
);
330 set_bit(INPUT_PROP_POINTER
, input_dev
->propbit
);
332 udraw
->touch_input_dev
= input_dev
;
337 static bool udraw_setup_pen(struct udraw
*udraw
,
338 struct hid_device
*hdev
)
340 struct input_dev
*input_dev
;
342 input_dev
= allocate_and_setup(hdev
, DEVICE_NAME
" Pen");
346 input_dev
->evbit
[0] = BIT(EV_ABS
) | BIT(EV_KEY
);
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);
355 set_bit(BTN_TOUCH
, input_dev
->keybit
);
356 set_bit(BTN_TOOL_PEN
, input_dev
->keybit
);
358 set_bit(INPUT_PROP_POINTER
, input_dev
->propbit
);
360 udraw
->pen_input_dev
= input_dev
;
365 static bool udraw_setup_accel(struct udraw
*udraw
,
366 struct hid_device
*hdev
)
368 struct input_dev
*input_dev
;
370 input_dev
= allocate_and_setup(hdev
, DEVICE_NAME
" Accelerometer");
374 input_dev
->evbit
[0] = BIT(EV_ABS
);
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);
381 set_bit(INPUT_PROP_ACCELEROMETER
, input_dev
->propbit
);
383 udraw
->accel_input_dev
= input_dev
;
388 static bool udraw_setup_joypad(struct udraw
*udraw
,
389 struct hid_device
*hdev
)
391 struct input_dev
*input_dev
;
393 input_dev
= allocate_and_setup(hdev
, DEVICE_NAME
" Joypad");
397 input_dev
->evbit
[0] = BIT(EV_KEY
) | BIT(EV_ABS
);
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
);
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);
410 udraw
->joy_input_dev
= input_dev
;
415 static int udraw_probe(struct hid_device
*hdev
, const struct hid_device_id
*id
)
420 udraw
= devm_kzalloc(&hdev
->dev
, sizeof(struct udraw
), GFP_KERNEL
);
425 udraw
->last_two_finger_x
= -1;
426 udraw
->last_two_finger_y
= -1;
428 hid_set_drvdata(hdev
, udraw
);
430 ret
= hid_parse(hdev
);
432 hid_err(hdev
, "parse failed\n");
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");
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
);
449 hid_err(hdev
, "failed to register interfaces\n");
453 ret
= hid_hw_start(hdev
, HID_CONNECT_HIDRAW
| HID_CONNECT_DRIVER
);
455 hid_err(hdev
, "hw start failed\n");
462 static const struct hid_device_id udraw_devices
[] = {
463 { HID_USB_DEVICE(USB_VENDOR_ID_THQ
, USB_DEVICE_ID_THQ_PS3_UDRAW
) },
466 MODULE_DEVICE_TABLE(hid
, udraw_devices
);
468 static struct hid_driver udraw_driver
= {
470 .id_table
= udraw_devices
,
471 .raw_event
= udraw_raw_event
,
472 .probe
= udraw_probe
,
474 module_hid_driver(udraw_driver
);