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