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#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
  72struct 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
  90static 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
 124static 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
 131static 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
 174static 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
 205static 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
 216static 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
 240err_kill_urb:
 241        usb_kill_urb(pegasus->irq);
 242        cancel_work_sync(&pegasus->init);
 243err_autopm_put:
 244        mutex_unlock(&pegasus->pm_mutex);
 245        usb_autopm_put_interface(pegasus->intf);
 246        return error;
 247}
 248
 249static 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
 262static 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
 375err_free_urb:
 376        usb_free_urb(pegasus->irq);
 377err_free_dma:
 378        usb_free_coherent(dev, pegasus->data_len,
 379                          pegasus->data, pegasus->data_dma);
 380err_free_mem:
 381        input_free_device(input_dev);
 382        kfree(pegasus);
 383        usb_set_intfdata(intf, NULL);
 384
 385        return error;
 386}
 387
 388static 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
 403static 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
 415static 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
 428static 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
 445static const struct usb_device_id pegasus_ids[] = {
 446        { USB_DEVICE(USB_VENDOR_ID_PEGASUSTECH,
 447                     USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100) },
 448        { }
 449};
 450MODULE_DEVICE_TABLE(usb, pegasus_ids);
 451
 452static 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
 463module_usb_driver(pegasus_driver);
 464
 465MODULE_AUTHOR("Martin Kepplinger <martink@posteo.de>");
 466MODULE_DESCRIPTION("Pegasus Mobile Notetaker Pen tablet driver");
 467MODULE_LICENSE("GPL");
 468