0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #include <linux/device.h>
0038 #include <linux/input.h>
0039 #include <linux/hid.h>
0040 #include <linux/module.h>
0041 #include <linux/timer.h>
0042 #include <linux/usb.h>
0043
0044 #include <asm/unaligned.h>
0045
0046 #include "hid-ids.h"
0047
0048 #define LETSKETCH_RAW_IF 0
0049
0050 #define LETSKETCH_RAW_DATA_LEN 12
0051 #define LETSKETCH_RAW_REPORT_ID 8
0052
0053 #define LETSKETCH_PAD_BUTTONS 5
0054
0055 #define LETSKETCH_INFO_STR_IDX_BEGIN 0xc8
0056 #define LETSKETCH_INFO_STR_IDX_END 0xca
0057
0058 #define LETSKETCH_GET_STRING_RETRIES 5
0059
0060 struct letsketch_data {
0061 struct hid_device *hdev;
0062 struct input_dev *input_tablet;
0063 struct input_dev *input_tablet_pad;
0064 struct timer_list inrange_timer;
0065 };
0066
0067 static int letsketch_open(struct input_dev *dev)
0068 {
0069 struct letsketch_data *data = input_get_drvdata(dev);
0070
0071 return hid_hw_open(data->hdev);
0072 }
0073
0074 static void letsketch_close(struct input_dev *dev)
0075 {
0076 struct letsketch_data *data = input_get_drvdata(dev);
0077
0078 hid_hw_close(data->hdev);
0079 }
0080
0081 static struct input_dev *letsketch_alloc_input_dev(struct letsketch_data *data)
0082 {
0083 struct input_dev *input;
0084
0085 input = devm_input_allocate_device(&data->hdev->dev);
0086 if (!input)
0087 return NULL;
0088
0089 input->id.bustype = data->hdev->bus;
0090 input->id.vendor = data->hdev->vendor;
0091 input->id.product = data->hdev->product;
0092 input->id.version = data->hdev->bus;
0093 input->phys = data->hdev->phys;
0094 input->uniq = data->hdev->uniq;
0095 input->open = letsketch_open;
0096 input->close = letsketch_close;
0097
0098 input_set_drvdata(input, data);
0099
0100 return input;
0101 }
0102
0103 static int letsketch_setup_input_tablet(struct letsketch_data *data)
0104 {
0105 struct input_dev *input;
0106
0107 input = letsketch_alloc_input_dev(data);
0108 if (!input)
0109 return -ENOMEM;
0110
0111 input_set_abs_params(input, ABS_X, 0, 50800, 0, 0);
0112 input_set_abs_params(input, ABS_Y, 0, 31750, 0, 0);
0113 input_set_abs_params(input, ABS_PRESSURE, 0, 8192, 0, 0);
0114 input_abs_set_res(input, ABS_X, 240);
0115 input_abs_set_res(input, ABS_Y, 225);
0116 input_set_capability(input, EV_KEY, BTN_TOUCH);
0117 input_set_capability(input, EV_KEY, BTN_TOOL_PEN);
0118 input_set_capability(input, EV_KEY, BTN_STYLUS);
0119 input_set_capability(input, EV_KEY, BTN_STYLUS2);
0120
0121
0122 input->name = "WP9620 Tablet";
0123
0124 data->input_tablet = input;
0125
0126 return input_register_device(data->input_tablet);
0127 }
0128
0129 static int letsketch_setup_input_tablet_pad(struct letsketch_data *data)
0130 {
0131 struct input_dev *input;
0132 int i;
0133
0134 input = letsketch_alloc_input_dev(data);
0135 if (!input)
0136 return -ENOMEM;
0137
0138 for (i = 0; i < LETSKETCH_PAD_BUTTONS; i++)
0139 input_set_capability(input, EV_KEY, BTN_0 + i);
0140
0141
0142
0143
0144
0145 input_set_abs_params(input, ABS_X, 0, 1, 0, 0);
0146 input_set_abs_params(input, ABS_Y, 0, 1, 0, 0);
0147 input_set_capability(input, EV_KEY, BTN_STYLUS);
0148
0149 input->name = "WP9620 Pad";
0150
0151 data->input_tablet_pad = input;
0152
0153 return input_register_device(data->input_tablet_pad);
0154 }
0155
0156 static void letsketch_inrange_timeout(struct timer_list *t)
0157 {
0158 struct letsketch_data *data = from_timer(data, t, inrange_timer);
0159 struct input_dev *input = data->input_tablet;
0160
0161 input_report_key(input, BTN_TOOL_PEN, 0);
0162 input_sync(input);
0163 }
0164
0165 static int letsketch_raw_event(struct hid_device *hdev,
0166 struct hid_report *report,
0167 u8 *raw_data, int size)
0168 {
0169 struct letsketch_data *data = hid_get_drvdata(hdev);
0170 struct input_dev *input;
0171 int i;
0172
0173 if (size != LETSKETCH_RAW_DATA_LEN || raw_data[0] != LETSKETCH_RAW_REPORT_ID)
0174 return 0;
0175
0176 switch (raw_data[1] & 0xf0) {
0177 case 0x80:
0178 input = data->input_tablet;
0179 input_report_key(input, BTN_TOOL_PEN, 1);
0180 input_report_key(input, BTN_TOUCH, raw_data[1] & 0x01);
0181 input_report_key(input, BTN_STYLUS, raw_data[1] & 0x02);
0182 input_report_key(input, BTN_STYLUS2, raw_data[1] & 0x04);
0183 input_report_abs(input, ABS_X,
0184 get_unaligned_le16(raw_data + 2));
0185 input_report_abs(input, ABS_Y,
0186 get_unaligned_le16(raw_data + 4));
0187 input_report_abs(input, ABS_PRESSURE,
0188 get_unaligned_le16(raw_data + 6));
0189
0190
0191
0192
0193 mod_timer(&data->inrange_timer, jiffies + msecs_to_jiffies(100));
0194 break;
0195 case 0xe0:
0196 input = data->input_tablet_pad;
0197 for (i = 0; i < LETSKETCH_PAD_BUTTONS; i++)
0198 input_report_key(input, BTN_0 + i, raw_data[4] == (i + 1));
0199 break;
0200 default:
0201 hid_warn(data->hdev, "Warning unknown data header: 0x%02x\n",
0202 raw_data[0]);
0203 return 0;
0204 }
0205
0206 input_sync(input);
0207 return 0;
0208 }
0209
0210
0211
0212
0213
0214
0215
0216 static int letsketch_get_string(struct usb_device *udev, int index, char *buf, int size)
0217 {
0218 int i, ret;
0219
0220 for (i = 0; i < LETSKETCH_GET_STRING_RETRIES; i++) {
0221 usleep_range(5000, 7000);
0222 ret = usb_string(udev, index, buf, size);
0223 if (ret > 0)
0224 return 0;
0225 }
0226
0227 dev_err(&udev->dev, "Max retries (%d) exceeded reading string descriptor %d\n",
0228 LETSKETCH_GET_STRING_RETRIES, index);
0229 return ret ? ret : -EIO;
0230 }
0231
0232 static int letsketch_probe(struct hid_device *hdev, const struct hid_device_id *id)
0233 {
0234 struct device *dev = &hdev->dev;
0235 struct letsketch_data *data;
0236 struct usb_interface *intf;
0237 struct usb_device *udev;
0238 char buf[256];
0239 int i, ret;
0240
0241 if (!hid_is_using_ll_driver(hdev, &usb_hid_driver))
0242 return -ENODEV;
0243
0244 intf = to_usb_interface(hdev->dev.parent);
0245 if (intf->altsetting->desc.bInterfaceNumber != LETSKETCH_RAW_IF)
0246 return -ENODEV;
0247
0248 udev = interface_to_usbdev(intf);
0249
0250
0251
0252
0253
0254
0255
0256 for (i = LETSKETCH_INFO_STR_IDX_BEGIN; i <= LETSKETCH_INFO_STR_IDX_END; i++) {
0257 ret = letsketch_get_string(udev, i, buf, sizeof(buf));
0258 if (ret)
0259 return ret;
0260
0261 hid_info(hdev, "Device info: %s\n", buf);
0262 }
0263
0264 for (i = 1; i <= 250; i++) {
0265 ret = letsketch_get_string(udev, i, buf, sizeof(buf));
0266 if (ret)
0267 return ret;
0268 }
0269
0270 ret = letsketch_get_string(udev, 0x64, buf, sizeof(buf));
0271 if (ret)
0272 return ret;
0273
0274 ret = letsketch_get_string(udev, LETSKETCH_INFO_STR_IDX_BEGIN, buf, sizeof(buf));
0275 if (ret)
0276 return ret;
0277
0278
0279
0280
0281
0282 usleep_range(5000, 7000);
0283
0284 ret = hid_parse(hdev);
0285 if (ret)
0286 return ret;
0287
0288 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0289 if (!data)
0290 return -ENOMEM;
0291
0292 data->hdev = hdev;
0293 timer_setup(&data->inrange_timer, letsketch_inrange_timeout, 0);
0294 hid_set_drvdata(hdev, data);
0295
0296 ret = letsketch_setup_input_tablet(data);
0297 if (ret)
0298 return ret;
0299
0300 ret = letsketch_setup_input_tablet_pad(data);
0301 if (ret)
0302 return ret;
0303
0304 return hid_hw_start(hdev, HID_CONNECT_HIDRAW);
0305 }
0306
0307 static const struct hid_device_id letsketch_devices[] = {
0308 { HID_USB_DEVICE(USB_VENDOR_ID_LETSKETCH, USB_DEVICE_ID_WP9620N) },
0309 { }
0310 };
0311 MODULE_DEVICE_TABLE(hid, letsketch_devices);
0312
0313 static struct hid_driver letsketch_driver = {
0314 .name = "letsketch",
0315 .id_table = letsketch_devices,
0316 .probe = letsketch_probe,
0317 .raw_event = letsketch_raw_event,
0318 };
0319 module_hid_driver(letsketch_driver);
0320
0321 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
0322 MODULE_LICENSE("GPL");