linux/drivers/input/tablet/kbtab.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <linux/kernel.h>
   3#include <linux/slab.h>
   4#include <linux/module.h>
   5#include <linux/usb/input.h>
   6#include <asm/unaligned.h>
   7
   8/*
   9 * Pressure-threshold modules param code from Alex Perry <alex.perry@ieee.org>
  10 */
  11
  12MODULE_AUTHOR("Josh Myer <josh@joshisanerd.com>");
  13MODULE_DESCRIPTION("USB KB Gear JamStudio Tablet driver");
  14MODULE_LICENSE("GPL");
  15
  16#define USB_VENDOR_ID_KBGEAR    0x084e
  17
  18static int kb_pressure_click = 0x10;
  19module_param(kb_pressure_click, int, 0);
  20MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
  21
  22struct kbtab {
  23        unsigned char *data;
  24        dma_addr_t data_dma;
  25        struct input_dev *dev;
  26        struct usb_interface *intf;
  27        struct urb *irq;
  28        char phys[32];
  29};
  30
  31static void kbtab_irq(struct urb *urb)
  32{
  33        struct kbtab *kbtab = urb->context;
  34        unsigned char *data = kbtab->data;
  35        struct input_dev *dev = kbtab->dev;
  36        int pressure;
  37        int retval;
  38
  39        switch (urb->status) {
  40        case 0:
  41                /* success */
  42                break;
  43        case -ECONNRESET:
  44        case -ENOENT:
  45        case -ESHUTDOWN:
  46                /* this urb is terminated, clean up */
  47                dev_dbg(&kbtab->intf->dev,
  48                        "%s - urb shutting down with status: %d\n",
  49                        __func__, urb->status);
  50                return;
  51        default:
  52                dev_dbg(&kbtab->intf->dev,
  53                        "%s - nonzero urb status received: %d\n",
  54                        __func__, urb->status);
  55                goto exit;
  56        }
  57
  58
  59        input_report_key(dev, BTN_TOOL_PEN, 1);
  60
  61        input_report_abs(dev, ABS_X, get_unaligned_le16(&data[1]));
  62        input_report_abs(dev, ABS_Y, get_unaligned_le16(&data[3]));
  63
  64        /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
  65        input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
  66
  67        pressure = data[5];
  68        if (kb_pressure_click == -1)
  69                input_report_abs(dev, ABS_PRESSURE, pressure);
  70        else
  71                input_report_key(dev, BTN_LEFT, pressure > kb_pressure_click ? 1 : 0);
  72
  73        input_sync(dev);
  74
  75 exit:
  76        retval = usb_submit_urb(urb, GFP_ATOMIC);
  77        if (retval)
  78                dev_err(&kbtab->intf->dev,
  79                        "%s - usb_submit_urb failed with result %d\n",
  80                        __func__, retval);
  81}
  82
  83static const struct usb_device_id kbtab_ids[] = {
  84        { USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 },
  85        { }
  86};
  87
  88MODULE_DEVICE_TABLE(usb, kbtab_ids);
  89
  90static int kbtab_open(struct input_dev *dev)
  91{
  92        struct kbtab *kbtab = input_get_drvdata(dev);
  93        struct usb_device *udev = interface_to_usbdev(kbtab->intf);
  94
  95        kbtab->irq->dev = udev;
  96        if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
  97                return -EIO;
  98
  99        return 0;
 100}
 101
 102static void kbtab_close(struct input_dev *dev)
 103{
 104        struct kbtab *kbtab = input_get_drvdata(dev);
 105
 106        usb_kill_urb(kbtab->irq);
 107}
 108
 109static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
 110{
 111        struct usb_device *dev = interface_to_usbdev(intf);
 112        struct usb_endpoint_descriptor *endpoint;
 113        struct kbtab *kbtab;
 114        struct input_dev *input_dev;
 115        int error = -ENOMEM;
 116
 117        if (intf->cur_altsetting->desc.bNumEndpoints < 1)
 118                return -ENODEV;
 119
 120        kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
 121        input_dev = input_allocate_device();
 122        if (!kbtab || !input_dev)
 123                goto fail1;
 124
 125        kbtab->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbtab->data_dma);
 126        if (!kbtab->data)
 127                goto fail1;
 128
 129        kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
 130        if (!kbtab->irq)
 131                goto fail2;
 132
 133        kbtab->intf = intf;
 134        kbtab->dev = input_dev;
 135
 136        usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
 137        strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
 138
 139        input_dev->name = "KB Gear Tablet";
 140        input_dev->phys = kbtab->phys;
 141        usb_to_input_id(dev, &input_dev->id);
 142        input_dev->dev.parent = &intf->dev;
 143
 144        input_set_drvdata(input_dev, kbtab);
 145
 146        input_dev->open = kbtab_open;
 147        input_dev->close = kbtab_close;
 148
 149        input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 150        input_dev->keybit[BIT_WORD(BTN_LEFT)] |=
 151                BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
 152        input_dev->keybit[BIT_WORD(BTN_DIGI)] |=
 153                BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_TOUCH);
 154        input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
 155        input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
 156        input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
 157
 158        endpoint = &intf->cur_altsetting->endpoint[0].desc;
 159
 160        usb_fill_int_urb(kbtab->irq, dev,
 161                         usb_rcvintpipe(dev, endpoint->bEndpointAddress),
 162                         kbtab->data, 8,
 163                         kbtab_irq, kbtab, endpoint->bInterval);
 164        kbtab->irq->transfer_dma = kbtab->data_dma;
 165        kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 166
 167        error = input_register_device(kbtab->dev);
 168        if (error)
 169                goto fail3;
 170
 171        usb_set_intfdata(intf, kbtab);
 172
 173        return 0;
 174
 175 fail3: usb_free_urb(kbtab->irq);
 176 fail2: usb_free_coherent(dev, 8, kbtab->data, kbtab->data_dma);
 177 fail1: input_free_device(input_dev);
 178        kfree(kbtab);
 179        return error;
 180}
 181
 182static void kbtab_disconnect(struct usb_interface *intf)
 183{
 184        struct kbtab *kbtab = usb_get_intfdata(intf);
 185        struct usb_device *udev = interface_to_usbdev(intf);
 186
 187        usb_set_intfdata(intf, NULL);
 188
 189        input_unregister_device(kbtab->dev);
 190        usb_free_urb(kbtab->irq);
 191        usb_free_coherent(udev, 8, kbtab->data, kbtab->data_dma);
 192        kfree(kbtab);
 193}
 194
 195static struct usb_driver kbtab_driver = {
 196        .name =         "kbtab",
 197        .probe =        kbtab_probe,
 198        .disconnect =   kbtab_disconnect,
 199        .id_table =     kbtab_ids,
 200};
 201
 202module_usb_driver(kbtab_driver);
 203