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