1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Pegasus Mobile Notetaker Pen input tablet driver
4 *
5 * Copyright (c) 2016 Martin Kepplinger <martink@posteo.de>
6 */
7
8 /*
9 * request packet (control endpoint):
10 * |-------------------------------------|
11 * | Report ID | Nr of bytes | command |
12 * | (1 byte) | (1 byte) | (n bytes) |
13 * |-------------------------------------|
14 * | 0x02 | n | |
15 * |-------------------------------------|
16 *
17 * data packet after set xy mode command, 0x80 0xb5 0x02 0x01
18 * and pen is in range:
19 *
20 * byte byte name value (bits)
21 * --------------------------------------------
22 * 0 status 0 1 0 0 0 0 X X
23 * 1 color 0 0 0 0 H 0 S T
24 * 2 X low
25 * 3 X high
26 * 4 Y low
27 * 5 Y high
28 *
29 * X X battery state:
30 * no state reported 0x00
31 * battery low 0x01
32 * battery good 0x02
33 *
34 * H Hovering
35 * S Switch 1 (pen button)
36 * T Tip
37 */
38
39 #include <linux/kernel.h>
40 #include <linux/module.h>
41 #include <linux/input.h>
42 #include <linux/usb/input.h>
43 #include <linux/slab.h>
44 #include <linux/workqueue.h>
45 #include <linux/mutex.h>
46
47 /* USB HID defines */
48 #define USB_REQ_GET_REPORT 0x01
49 #define USB_REQ_SET_REPORT 0x09
50
51 #define USB_VENDOR_ID_PEGASUSTECH 0x0e20
52 #define USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100 0x0101
53
54 /* device specific defines */
55 #define NOTETAKER_REPORT_ID 0x02
56 #define NOTETAKER_SET_CMD 0x80
57 #define NOTETAKER_SET_MODE 0xb5
58
59 #define NOTETAKER_LED_MOUSE 0x02
60 #define PEN_MODE_XY 0x01
61
62 #define SPECIAL_COMMAND 0x80
63 #define BUTTON_PRESSED 0xb5
64 #define COMMAND_VERSION 0xa9
65
66 /* 1 Status + 1 Color + 2 X + 2 Y = 6 bytes */
67 #define NOTETAKER_PACKET_SIZE 6
68
69 /* in xy data packet */
70 #define BATTERY_NO_REPORT 0x40
71 #define BATTERY_LOW 0x41
72 #define BATTERY_GOOD 0x42
73 #define PEN_BUTTON_PRESSED BIT(1)
74 #define PEN_TIP BIT(0)
75
76 struct pegasus {
77 unsigned char *data;
78 u8 data_len;
79 dma_addr_t data_dma;
80 struct input_dev *dev;
81 struct usb_device *usbdev;
82 struct usb_interface *intf;
83 struct urb *irq;
84
85 /* serialize access to open/suspend */
86 struct mutex pm_mutex;
87 bool is_open;
88
89 char name[128];
90 char phys[64];
91 struct work_struct init;
92 };
93
pegasus_control_msg(struct pegasus * pegasus,u8 * data,int len)94 static int pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
95 {
96 const int sizeof_buf = len + 2;
97 int result;
98 int error;
99 u8 *cmd_buf;
100
101 cmd_buf = kmalloc(sizeof_buf, GFP_KERNEL);
102 if (!cmd_buf)
103 return -ENOMEM;
104
105 cmd_buf[0] = NOTETAKER_REPORT_ID;
106 cmd_buf[1] = len;
107 memcpy(cmd_buf + 2, data, len);
108
109 result = usb_control_msg(pegasus->usbdev,
110 usb_sndctrlpipe(pegasus->usbdev, 0),
111 USB_REQ_SET_REPORT,
112 USB_TYPE_VENDOR | USB_DIR_OUT,
113 0, 0, cmd_buf, sizeof_buf,
114 USB_CTRL_SET_TIMEOUT);
115
116 kfree(cmd_buf);
117
118 if (unlikely(result != sizeof_buf)) {
119 error = result < 0 ? result : -EIO;
120 dev_err(&pegasus->usbdev->dev, "control msg error: %d\n",
121 error);
122 return error;
123 }
124
125 return 0;
126 }
127
pegasus_set_mode(struct pegasus * pegasus,u8 mode,u8 led)128 static int pegasus_set_mode(struct pegasus *pegasus, u8 mode, u8 led)
129 {
130 u8 cmd[] = { NOTETAKER_SET_CMD, NOTETAKER_SET_MODE, led, mode };
131
132 return pegasus_control_msg(pegasus, cmd, sizeof(cmd));
133 }
134
pegasus_parse_packet(struct pegasus * pegasus)135 static void pegasus_parse_packet(struct pegasus *pegasus)
136 {
137 unsigned char *data = pegasus->data;
138 struct input_dev *dev = pegasus->dev;
139 u16 x, y;
140
141 switch (data[0]) {
142 case SPECIAL_COMMAND:
143 /* device button pressed */
144 if (data[1] == BUTTON_PRESSED)
145 schedule_work(&pegasus->init);
146
147 break;
148
149 /* xy data */
150 case BATTERY_LOW:
151 dev_warn_once(&dev->dev, "Pen battery low\n");
152 fallthrough;
153
154 case BATTERY_NO_REPORT:
155 case BATTERY_GOOD:
156 x = le16_to_cpup((__le16 *)&data[2]);
157 y = le16_to_cpup((__le16 *)&data[4]);
158
159 /* pen-up event */
160 if (x == 0 && y == 0)
161 break;
162
163 input_report_key(dev, BTN_TOUCH, data[1] & PEN_TIP);
164 input_report_key(dev, BTN_RIGHT, data[1] & PEN_BUTTON_PRESSED);
165 input_report_key(dev, BTN_TOOL_PEN, 1);
166 input_report_abs(dev, ABS_X, (s16)x);
167 input_report_abs(dev, ABS_Y, y);
168
169 input_sync(dev);
170 break;
171
172 default:
173 dev_warn_once(&pegasus->usbdev->dev,
174 "unknown answer from device\n");
175 }
176 }
177
pegasus_irq(struct urb * urb)178 static void pegasus_irq(struct urb *urb)
179 {
180 struct pegasus *pegasus = urb->context;
181 struct usb_device *dev = pegasus->usbdev;
182 int retval;
183
184 switch (urb->status) {
185 case 0:
186 pegasus_parse_packet(pegasus);
187 usb_mark_last_busy(pegasus->usbdev);
188 break;
189
190 case -ECONNRESET:
191 case -ENOENT:
192 case -ESHUTDOWN:
193 dev_err(&dev->dev, "%s - urb shutting down with status: %d",
194 __func__, urb->status);
195 return;
196
197 default:
198 dev_err(&dev->dev, "%s - nonzero urb status received: %d",
199 __func__, urb->status);
200 break;
201 }
202
203 retval = usb_submit_urb(urb, GFP_ATOMIC);
204 if (retval)
205 dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d",
206 __func__, retval);
207 }
208
pegasus_init(struct work_struct * work)209 static void pegasus_init(struct work_struct *work)
210 {
211 struct pegasus *pegasus = container_of(work, struct pegasus, init);
212 int error;
213
214 error = pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
215 if (error)
216 dev_err(&pegasus->usbdev->dev, "pegasus_set_mode error: %d\n",
217 error);
218 }
219
__pegasus_open(struct pegasus * pegasus)220 static int __pegasus_open(struct pegasus *pegasus)
221 {
222 int error;
223
224 guard(mutex)(&pegasus->pm_mutex);
225
226 pegasus->irq->dev = pegasus->usbdev;
227 if (usb_submit_urb(pegasus->irq, GFP_KERNEL))
228 return -EIO;
229
230 error = pegasus_set_mode(pegasus, PEN_MODE_XY, NOTETAKER_LED_MOUSE);
231 if (error) {
232 usb_kill_urb(pegasus->irq);
233 cancel_work_sync(&pegasus->init);
234 return error;
235 }
236
237 pegasus->is_open = true;
238
239 return 0;
240 }
241
pegasus_open(struct input_dev * dev)242 static int pegasus_open(struct input_dev *dev)
243 {
244 struct pegasus *pegasus = input_get_drvdata(dev);
245 int error;
246
247 error = usb_autopm_get_interface(pegasus->intf);
248 if (error)
249 return error;
250
251 error = __pegasus_open(pegasus);
252 if (error) {
253 usb_autopm_put_interface(pegasus->intf);
254 return error;
255 }
256
257 return 0;
258 }
259
pegasus_close(struct input_dev * dev)260 static void pegasus_close(struct input_dev *dev)
261 {
262 struct pegasus *pegasus = input_get_drvdata(dev);
263
264 scoped_guard(mutex, &pegasus->pm_mutex) {
265 usb_kill_urb(pegasus->irq);
266 cancel_work_sync(&pegasus->init);
267
268 pegasus->is_open = false;
269 }
270
271 usb_autopm_put_interface(pegasus->intf);
272 }
273
pegasus_probe(struct usb_interface * intf,const struct usb_device_id * id)274 static int pegasus_probe(struct usb_interface *intf,
275 const struct usb_device_id *id)
276 {
277 struct usb_device *dev = interface_to_usbdev(intf);
278 struct usb_endpoint_descriptor *endpoint;
279 struct pegasus *pegasus;
280 struct input_dev *input_dev;
281 int error;
282 int pipe;
283
284 /* We control interface 0 */
285 if (intf->cur_altsetting->desc.bInterfaceNumber >= 1)
286 return -ENODEV;
287
288 /* Sanity check that the device has an endpoint */
289 if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
290 dev_err(&intf->dev, "Invalid number of endpoints\n");
291 return -EINVAL;
292 }
293
294 endpoint = &intf->cur_altsetting->endpoint[0].desc;
295
296 pegasus = kzalloc_obj(*pegasus);
297 input_dev = input_allocate_device();
298 if (!pegasus || !input_dev) {
299 error = -ENOMEM;
300 goto err_free_mem;
301 }
302
303 mutex_init(&pegasus->pm_mutex);
304
305 pegasus->usbdev = dev;
306 pegasus->dev = input_dev;
307 pegasus->intf = intf;
308
309 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
310 /* Sanity check that pipe's type matches endpoint's type */
311 if (usb_pipe_type_check(dev, pipe)) {
312 error = -EINVAL;
313 goto err_free_mem;
314 }
315
316 pegasus->data_len = usb_maxpacket(dev, pipe);
317 if (pegasus->data_len < NOTETAKER_PACKET_SIZE) {
318 dev_err(&intf->dev, "packet size is too small (%d)\n",
319 pegasus->data_len);
320 error = -EINVAL;
321 goto err_free_mem;
322 }
323
324 pegasus->data = usb_alloc_coherent(dev, pegasus->data_len, GFP_KERNEL,
325 &pegasus->data_dma);
326 if (!pegasus->data) {
327 error = -ENOMEM;
328 goto err_free_mem;
329 }
330
331 pegasus->irq = usb_alloc_urb(0, GFP_KERNEL);
332 if (!pegasus->irq) {
333 error = -ENOMEM;
334 goto err_free_dma;
335 }
336
337 usb_fill_int_urb(pegasus->irq, dev, pipe,
338 pegasus->data, pegasus->data_len,
339 pegasus_irq, pegasus, endpoint->bInterval);
340
341 pegasus->irq->transfer_dma = pegasus->data_dma;
342 pegasus->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
343
344 if (dev->manufacturer)
345 strscpy(pegasus->name, dev->manufacturer,
346 sizeof(pegasus->name));
347
348 if (dev->product) {
349 if (dev->manufacturer)
350 strlcat(pegasus->name, " ", sizeof(pegasus->name));
351 strlcat(pegasus->name, dev->product, sizeof(pegasus->name));
352 }
353
354 if (!strlen(pegasus->name))
355 snprintf(pegasus->name, sizeof(pegasus->name),
356 "USB Pegasus Device %04x:%04x",
357 le16_to_cpu(dev->descriptor.idVendor),
358 le16_to_cpu(dev->descriptor.idProduct));
359
360 usb_make_path(dev, pegasus->phys, sizeof(pegasus->phys));
361 strlcat(pegasus->phys, "/input0", sizeof(pegasus->phys));
362
363 INIT_WORK(&pegasus->init, pegasus_init);
364
365 usb_set_intfdata(intf, pegasus);
366
367 input_dev->name = pegasus->name;
368 input_dev->phys = pegasus->phys;
369 usb_to_input_id(dev, &input_dev->id);
370 input_dev->dev.parent = &intf->dev;
371
372 input_set_drvdata(input_dev, pegasus);
373
374 input_dev->open = pegasus_open;
375 input_dev->close = pegasus_close;
376
377 __set_bit(EV_ABS, input_dev->evbit);
378 __set_bit(EV_KEY, input_dev->evbit);
379
380 __set_bit(ABS_X, input_dev->absbit);
381 __set_bit(ABS_Y, input_dev->absbit);
382
383 __set_bit(BTN_TOUCH, input_dev->keybit);
384 __set_bit(BTN_RIGHT, input_dev->keybit);
385 __set_bit(BTN_TOOL_PEN, input_dev->keybit);
386
387 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
388 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
389
390 input_set_abs_params(input_dev, ABS_X, -1500, 1500, 8, 0);
391 input_set_abs_params(input_dev, ABS_Y, 1600, 3000, 8, 0);
392
393 error = input_register_device(pegasus->dev);
394 if (error)
395 goto err_free_urb;
396
397 return 0;
398
399 err_free_urb:
400 usb_free_urb(pegasus->irq);
401 err_free_dma:
402 usb_free_coherent(dev, pegasus->data_len,
403 pegasus->data, pegasus->data_dma);
404 err_free_mem:
405 input_free_device(input_dev);
406 kfree(pegasus);
407 usb_set_intfdata(intf, NULL);
408
409 return error;
410 }
411
pegasus_disconnect(struct usb_interface * intf)412 static void pegasus_disconnect(struct usb_interface *intf)
413 {
414 struct pegasus *pegasus = usb_get_intfdata(intf);
415
416 input_unregister_device(pegasus->dev);
417
418 usb_free_urb(pegasus->irq);
419 usb_free_coherent(interface_to_usbdev(intf),
420 pegasus->data_len, pegasus->data,
421 pegasus->data_dma);
422
423 kfree(pegasus);
424 usb_set_intfdata(intf, NULL);
425 }
426
pegasus_suspend(struct usb_interface * intf,pm_message_t message)427 static int pegasus_suspend(struct usb_interface *intf, pm_message_t message)
428 {
429 struct pegasus *pegasus = usb_get_intfdata(intf);
430
431 guard(mutex)(&pegasus->pm_mutex);
432
433 usb_kill_urb(pegasus->irq);
434 cancel_work_sync(&pegasus->init);
435
436 return 0;
437 }
438
pegasus_resume(struct usb_interface * intf)439 static int pegasus_resume(struct usb_interface *intf)
440 {
441 struct pegasus *pegasus = usb_get_intfdata(intf);
442
443 guard(mutex)(&pegasus->pm_mutex);
444
445 if (pegasus->is_open && usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
446 return -EIO;
447
448 return 0;
449 }
450
pegasus_reset_resume(struct usb_interface * intf)451 static int pegasus_reset_resume(struct usb_interface *intf)
452 {
453 struct pegasus *pegasus = usb_get_intfdata(intf);
454 int error;
455
456 guard(mutex)(&pegasus->pm_mutex);
457
458 if (pegasus->is_open) {
459 error = pegasus_set_mode(pegasus, PEN_MODE_XY,
460 NOTETAKER_LED_MOUSE);
461 if (error)
462 return error;
463
464 if (usb_submit_urb(pegasus->irq, GFP_NOIO) < 0)
465 return -EIO;
466 }
467
468 return 0;
469 }
470
471 static const struct usb_device_id pegasus_ids[] = {
472 { USB_DEVICE(USB_VENDOR_ID_PEGASUSTECH,
473 USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100) },
474 { }
475 };
476 MODULE_DEVICE_TABLE(usb, pegasus_ids);
477
478 static struct usb_driver pegasus_driver = {
479 .name = "pegasus_notetaker",
480 .probe = pegasus_probe,
481 .disconnect = pegasus_disconnect,
482 .suspend = pegasus_suspend,
483 .resume = pegasus_resume,
484 .reset_resume = pegasus_reset_resume,
485 .id_table = pegasus_ids,
486 .supports_autosuspend = 1,
487 };
488
489 module_usb_driver(pegasus_driver);
490
491 MODULE_AUTHOR("Martin Kepplinger <martink@posteo.de>");
492 MODULE_DESCRIPTION("Pegasus Mobile Notetaker Pen tablet driver");
493 MODULE_LICENSE("GPL");
494