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