Messages in this thread Patch in this message | | | Date | Fri, 25 Oct 2002 02:04:25 -0500 (CDT) | From | Josh Myer <> | Subject | [PATCH] KB Gear JamStudio USB Tablet |
| |
Attached is a patch against 2.4.19 for basic support of the KB Gear JamStudio USB tablet (it's a decent enough 30$ tablet--not quite wacom quality, but definitely not wacom pricing).
Comments highly encouraged, thanks. I'd like to get this driver cleaned up a little before submitting, but I'm not quite certain where to start.
The code is based heavily on the wacom driver, and a big "You Rule!" to Pavel and anyone else involved with the Input layer. It may be a little convoluted, and slightly non-intuitive, but it's a hell of a lot better than the USB HID spec! -- /jbm, but you can call me Josh. Really, you can! this signature brought to you by the phrase, "this signature brought to you by the phrase, '...' and contributions by viewers like you" 7958 1C1C 306A CDF8 4468 3EDE 1F93 F49D 5FA1 49C4 diff -urN linux-2.4.19/Documentation/Configure.help linux-2.4.19-kb/Documentation/Configure.help --- linux-2.4.19/Documentation/Configure.help 2002-08-02 20:39:42.000000000 -0400 +++ linux-2.4.19-kb/Documentation/Configure.help 2002-10-25 01:58:24.000000000 -0400 @@ -13108,6 +13108,17 @@ The module will be called wacom.o. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +KB Gear JamStudio tablet support +CONFIG_USB_KBGEAR + Say Y here if you want to use the KB Gear JamStudio USB Tablet. + Make sure to say Y to "Mouse support" (CONFIG_INPUT_MOUSEDEV) + and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called wacom.o. If you want to compile it as a + module, say M here and read <file:Documentation/modules.txt>. + Aiptek 8000U tablet support CONFIG_USB_AIPTEK Say Y here if you want to use the USB version of the Aiptek 8000U diff -urN linux-2.4.19/drivers/usb/Config.in linux-2.4.19-kb/drivers/usb/Config.in --- linux-2.4.19/drivers/usb/Config.in 2002-08-02 20:39:44.000000000 -0400 +++ linux-2.4.19-kb/drivers/usb/Config.in 2002-10-25 01:56:40.000000000 -0400 @@ -60,6 +60,7 @@ dep_tristate ' USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT fi dep_tristate ' Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT + dep_tristate ' KB Gear JamStudio tablet support' CONFIG_USB_KBGEAR $CONFIG_USB $CONFIG_INPUT comment 'USB Imaging devices' dep_tristate ' USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB diff -urN linux-2.4.19/drivers/usb/Makefile linux-2.4.19-kb/drivers/usb/Makefile --- linux-2.4.19/drivers/usb/Makefile 2002-08-02 20:39:44.000000000 -0400 +++ linux-2.4.19-kb/drivers/usb/Makefile 2002-10-25 02:04:51.000000000 -0400 @@ -63,6 +63,7 @@ obj-$(CONFIG_USB_HID) += hid.o obj-$(CONFIG_USB_KBD) += usbkbd.o obj-$(CONFIG_USB_WACOM) += wacom.o +obj-$(CONFIG_USB_KBGEAR) += kbpad.o obj-$(CONFIG_USB_SCANNER) += scanner.o obj-$(CONFIG_USB_ACM) += acm.o --- linux-2.4.19/drivers/usb/kbpad.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.4.19-kb/drivers/usb/kbpad.c 2002-10-25 02:03:32.000000000 -0400 @@ -0,0 +1,174 @@ +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/usb.h> + +/* + * Version Information + */ +#define DRIVER_VERSION "v0.0.1" +#define DRIVER_AUTHOR "Josh Myer <josh@joshisanerd.com>" +#define DRIVER_DESC "KB Gear Jam Studio Tablet Driver" + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE("GPL"); + +#define USB_VENDOR_ID_KBTAB 0x84e + +struct kbtab { + signed char data[8]; + struct input_dev dev; + struct usb_device *usbdev; + struct urb irq; + int open; + int x, y; + int button; + int pressure; +}; + +static void kbtab_irq(struct urb *urb) +{ + + struct kbtab *tab = urb->context; + unsigned char *data = tab->data; + struct input_dev *dev = &tab->dev; + + if(urb->status) + return; + + tab->x = (data[2] << 8) + data[1]; + tab->y = (data[4] << 8) + data[3]; + + tab->pressure = (data[5]); + + /* XXX: don't report unless actual change */ + + input_report_abs(dev, ABS_X, tab->x); + input_report_abs(dev, ABS_Y, tab->y); + input_report_abs(dev, ABS_PRESSURE, tab->pressure); + + input_report_key(dev, BTN_STYLUS, (data[0] & 2)); + input_report_key(dev, BTN_TOUCH, (data[0] & 1)); + input_report_key(dev, BTN_LEFT, (tab->pressure > 0x10) ? 1 : 0); + + input_event(dev, EV_MSC, MSC_SERIAL, 0); +} + +struct usb_device_id kbtab_ids[] = { + { USB_DEVICE(USB_VENDOR_ID_KBTAB, 0x1001), driver_info : 0 }, + { } +}; + +MODULE_DEVICE_TABLE(usb, kbtab_ids); + +static int kbtab_open(struct input_dev *dev) +{ + struct kbtab *kbtab = dev->private; + + if(kbtab->open++) + return 0; + + kbtab->irq.dev = kbtab->usbdev; + if(usb_submit_urb(&kbtab->irq)) + return -EIO; + + return 0; +} + +static void kbtab_close(struct input_dev *dev) +{ + struct kbtab *kbtab = dev->private; + + if(!--kbtab->open) + usb_unlink_urb(&kbtab->irq); +} + +static void *kbtab_probe(struct usb_device *dev, unsigned int ifnum, const struct usb_device_id *id) +{ + struct usb_endpoint_descriptor *endpoint; + struct kbtab *kbtab; + + if(!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL))) + return NULL; + + memset(kbtab, 0, sizeof(struct kbtab)); + + kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); + kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + + kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS); + + kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL); + + kbtab->dev.absmax[ABS_X] = 0x2000; + kbtab->dev.absmax[ABS_Y] = 0x1750; + + kbtab->dev.absmax[ABS_PRESSURE] = 0xff; + + kbtab->dev.absfuzz[ABS_X] = 4; + kbtab->dev.absfuzz[ABS_Y] = 4; + + kbtab->dev.private = kbtab; + + kbtab->dev.open = kbtab_open; + kbtab->dev.close = kbtab_close; + + kbtab->dev.name = "KB Gear Tablet"; + kbtab->dev.idbus = BUS_USB; + + kbtab->dev.idvendor = dev->descriptor.idVendor; + kbtab->dev.idproduct = dev->descriptor.idProduct; + kbtab->dev.idversion = dev->descriptor.bcdDevice; + kbtab->usbdev = dev; + + + endpoint = dev->config[0].interface[ifnum].altsetting[0].endpoint + 0; + + usb_set_idle(dev, dev->config[0].interface[ifnum].altsetting[0].bInterfaceNumber, 0, 0); + + FILL_INT_URB(&kbtab->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), + kbtab->data, 8, kbtab_irq, kbtab, endpoint->bInterval); + + input_register_device(&kbtab->dev); + + printk(KERN_INFO "input%d: KB Gear Tablet on usb%d:%d.%d\n", + kbtab->dev.number, dev->bus->busnum, dev->devnum, ifnum); + + return kbtab; + +} + +static void kbtab_disconnect(struct usb_device *dev, void *ptr) +{ + struct kbtab *kbtab = ptr; + usb_unlink_urb(&kbtab->irq); + input_unregister_device(&kbtab->dev); + kfree(kbtab); +} + +static struct usb_driver kbtab_driver = { + name: "kbtab", + probe: kbtab_probe, + disconnect: kbtab_disconnect, + id_table: kbtab_ids, +}; + +static int __init kbtab_init(void) +{ + usb_register(&kbtab_driver); + info(DRIVER_VERSION " " DRIVER_AUTHOR); + info(DRIVER_DESC); + return 0; +} + +static void __exit kbtab_exit(void) +{ + usb_deregister(&kbtab_driver); +} + +module_init(kbtab_init); +module_exit(kbtab_exit); | |