1 #include <linux/kernel.h>
 
   2 #include <linux/slab.h>
 
   3 #include <linux/module.h>
 
   4 #include <linux/init.h>
 
   5 #include <linux/usb/input.h>
 
   6 #include <asm/unaligned.h>
 
  10  * v0.0.1 - Original, extremely basic version, 2.4.xx only
 
  11  * v0.0.2 - Updated, works with 2.5.62 and 2.4.20;
 
  12  *           - added pressure-threshold modules param code from
 
  13  *              Alex Perry <alex.perry@ieee.org>
 
  16 #define DRIVER_VERSION "v0.0.2"
 
  17 #define DRIVER_AUTHOR "Josh Myer <josh@joshisanerd.com>"
 
  18 #define DRIVER_DESC "USB KB Gear JamStudio Tablet driver"
 
  19 #define DRIVER_LICENSE "GPL"
 
  21 MODULE_AUTHOR(DRIVER_AUTHOR);
 
  22 MODULE_DESCRIPTION(DRIVER_DESC);
 
  23 MODULE_LICENSE(DRIVER_LICENSE);
 
  25 #define USB_VENDOR_ID_KBGEAR    0x084e
 
  27 static int kb_pressure_click = 0x10;
 
  28 module_param(kb_pressure_click, int, 0);
 
  29 MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
 
  34         struct input_dev *dev;
 
  35         struct usb_device *usbdev;
 
  44 static void kbtab_irq(struct urb *urb)
 
  46         struct kbtab *kbtab = urb->context;
 
  47         unsigned char *data = kbtab->data;
 
  48         struct input_dev *dev = kbtab->dev;
 
  51         switch (urb->status) {
 
  58                 /* this urb is terminated, clean up */
 
  59                 dbg("%s - urb shutting down with status: %d", __func__, urb->status);
 
  62                 dbg("%s - nonzero urb status received: %d", __func__, urb->status);
 
  66         kbtab->x = get_unaligned_le16(&data[1]);
 
  67         kbtab->y = get_unaligned_le16(&data[3]);
 
  69         kbtab->pressure = (data[5]);
 
  71         input_report_key(dev, BTN_TOOL_PEN, 1);
 
  73         input_report_abs(dev, ABS_X, kbtab->x);
 
  74         input_report_abs(dev, ABS_Y, kbtab->y);
 
  76         /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
 
  77         input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
 
  79         if (-1 == kb_pressure_click) {
 
  80                 input_report_abs(dev, ABS_PRESSURE, kbtab->pressure);
 
  82                 input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0);
 
  88         retval = usb_submit_urb (urb, GFP_ATOMIC);
 
  90                 err ("%s - usb_submit_urb failed with result %d",
 
  94 static struct usb_device_id kbtab_ids[] = {
 
  95         { USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 },
 
  99 MODULE_DEVICE_TABLE(usb, kbtab_ids);
 
 101 static int kbtab_open(struct input_dev *dev)
 
 103         struct kbtab *kbtab = input_get_drvdata(dev);
 
 105         kbtab->irq->dev = kbtab->usbdev;
 
 106         if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
 
 112 static void kbtab_close(struct input_dev *dev)
 
 114         struct kbtab *kbtab = input_get_drvdata(dev);
 
 116         usb_kill_urb(kbtab->irq);
 
 119 static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 121         struct usb_device *dev = interface_to_usbdev(intf);
 
 122         struct usb_endpoint_descriptor *endpoint;
 
 124         struct input_dev *input_dev;
 
 127         kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
 
 128         input_dev = input_allocate_device();
 
 129         if (!kbtab || !input_dev)
 
 132         kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
 
 136         kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
 
 141         kbtab->dev = input_dev;
 
 143         usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
 
 144         strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
 
 146         input_dev->name = "KB Gear Tablet";
 
 147         input_dev->phys = kbtab->phys;
 
 148         usb_to_input_id(dev, &input_dev->id);
 
 149         input_dev->dev.parent = &intf->dev;
 
 151         input_set_drvdata(input_dev, kbtab);
 
 153         input_dev->open = kbtab_open;
 
 154         input_dev->close = kbtab_close;
 
 156         input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
 
 158         input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
 
 159                 BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
 
 160         input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
 
 162         input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
 
 163         input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
 
 164         input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
 
 165         input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
 
 167         endpoint = &intf->cur_altsetting->endpoint[0].desc;
 
 169         usb_fill_int_urb(kbtab->irq, dev,
 
 170                          usb_rcvintpipe(dev, endpoint->bEndpointAddress),
 
 172                          kbtab_irq, kbtab, endpoint->bInterval);
 
 173         kbtab->irq->transfer_dma = kbtab->data_dma;
 
 174         kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 176         error = input_register_device(kbtab->dev);
 
 180         usb_set_intfdata(intf, kbtab);
 
 184  fail3: usb_free_urb(kbtab->irq);
 
 185  fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
 
 186  fail1: input_free_device(input_dev);
 
 191 static void kbtab_disconnect(struct usb_interface *intf)
 
 193         struct kbtab *kbtab = usb_get_intfdata(intf);
 
 195         usb_set_intfdata(intf, NULL);
 
 197                 usb_kill_urb(kbtab->irq);
 
 198                 input_unregister_device(kbtab->dev);
 
 199                 usb_free_urb(kbtab->irq);
 
 200                 usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
 
 205 static struct usb_driver kbtab_driver = {
 
 207         .probe =        kbtab_probe,
 
 208         .disconnect =   kbtab_disconnect,
 
 209         .id_table =     kbtab_ids,
 
 212 static int __init kbtab_init(void)
 
 215         retval = usb_register(&kbtab_driver);
 
 218         printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
 
 224 static void __exit kbtab_exit(void)
 
 226         usb_deregister(&kbtab_driver);
 
 229 module_init(kbtab_init);
 
 230 module_exit(kbtab_exit);