Attached are new drivers for the KB Gear JamStudio Tablet. There are two
files, one is against 2.4.20, the other against 2.5.62. I'm hoping this
isn't too late in the 2.4.21-pre stages to get included (or the 2.5, for
that matter =). This driver Works For Me, on both 2.4.20 and 2.5.62.

Thanks to Alex Perry for adding the threshold support, which probably
should have been done earlier...

Anyway, as usual, comments, complaints, and patches are more than
welcome.
--
/jbm, but you can call me Josh. Really, you can!
 "What's a metaphor?" "For sheep to graze in"
7958 1C1C 306A CDF8 4468  3EDE 1F93 F49D 5FA1 49C4

diff -x '*~' -x '*.o' -x'*.orig' -x'.*' -urN linux-2.4.20/drivers/usb/Config.in 
linux-2.4.20-jbm/drivers/usb/Config.in
--- linux-2.4.20/drivers/usb/Config.in  2003-02-21 21:18:28.000000000 -0500
+++ linux-2.4.20-jbm/drivers/usb/Config.in      2003-02-22 03:11:59.000000000 -0500
@@ -63,6 +63,7 @@
    fi
    dep_tristate '  Aiptek 6000U/8000U tablet support' CONFIG_USB_AIPTEK $CONFIG_USB 
$CONFIG_INPUT
    dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB 
$CONFIG_INPUT
+   dep_tristate '  KB Gear JamStudio tablet support' CONFIG_USB_KBTAB $CONFIG_USB 
$CONFIG_INPUT
 
    comment 'USB Imaging devices'
    dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
diff -x '*~' -x '*.o' -x'*.orig' -x'.*' -urN linux-2.4.20/drivers/usb/Makefile 
linux-2.4.20-jbm/drivers/usb/Makefile
--- linux-2.4.20/drivers/usb/Makefile   2003-02-21 21:18:28.000000000 -0500
+++ linux-2.4.20-jbm/drivers/usb/Makefile       2003-02-21 22:08:57.000000000 -0500
@@ -64,6 +64,7 @@
 obj-$(CONFIG_USB_KBD)          += usbkbd.o
 obj-$(CONFIG_USB_AIPTEK)       += aiptek.o
 obj-$(CONFIG_USB_WACOM)                += wacom.o
+obj-$(CONFIG_USB_KBTAB)                += kbtab.o
 
 obj-$(CONFIG_USB_SCANNER)      += scanner.o
 obj-$(CONFIG_USB_ACM)          += acm.o
diff -x '*~' -x '*.o' -x'*.orig' -x'.*' -urN linux-2.4.20/drivers/usb/hid-core.c 
linux-2.4.20-jbm/drivers/usb/hid-core.c
--- linux-2.4.20/drivers/usb/hid-core.c 2003-02-21 21:18:28.000000000 -0500
+++ linux-2.4.20-jbm/drivers/usb/hid-core.c     2003-02-21 22:12:23.000000000 -0500
@@ -1080,6 +1080,9 @@
 #define USB_DEVICE_ID_WACOM_PL         0x0030
 #define USB_DEVICE_ID_WACOM_INTUOS2    0x0041
 
+#define USB_VENDOR_ID_KBGEAR           0x084e
+#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
+
 #define USB_VENDOR_ID_ATEN             0x0557
 #define USB_DEVICE_ID_ATEN_UC100KM     0x2004
 #define USB_DEVICE_ID_ATEN_CS124U      0x2202
@@ -1111,6 +1114,7 @@
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 2, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
diff -x '*~' -x '*.o' -x'*.orig' -x'.*' -urN linux-2.4.20/drivers/usb/kbtab.c 
linux-2.4.20-jbm/drivers/usb/kbtab.c
--- linux-2.4.20/drivers/usb/kbtab.c    1969-12-31 19:00:00.000000000 -0500
+++ linux-2.4.20-jbm/drivers/usb/kbtab.c        2003-02-22 03:06:36.000000000 -0500
@@ -0,0 +1,179 @@
+#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 <[EMAIL PROTECTED]>"
+#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
+
+static int       kb_pressure_click = 0x10;
+MODULE_PARM     (kb_pressure_click,"i");
+MODULE_PARM_DESC(kb_pressure_click,
+                "pressure threshold for clicks");
+
+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 > kb_pressure_click) ? 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);
--- linux-2.4.20/Documentation/Configure.help   2003-02-21 21:18:05.000000000 -0500
+++ linux-2.4.20-jbm/Documentation/Configure.help       2003-02-21 22:09:24.000000000 
-0500
@@ -13764,6 +13764,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_KBTAB
+  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 kbtab.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 Aiptek 6000U/8000U tablet support
 CONFIG_USB_AIPTEK
   Say Y here if you want to use the USB version of the Aiptek 6000U/8000U
diff -x '*~' -x '*.orig' -x'.*' -uN linux-2.5.62/drivers/usb/input/Kconfig 
linux-2.5.62-jbm/drivers/usb/input/Kconfig
--- linux-2.5.62/drivers/usb/input/Kconfig      2003-02-22 03:07:41.000000000 -0500
+++ linux-2.5.62-jbm/drivers/usb/input/Kconfig  2003-02-21 23:51:44.000000000 -0500
@@ -159,6 +159,20 @@
          The module will be called wacom.  If you want to compile it as a
          module, say M here and read <file:Documentation/modules.txt>.
 
+config USB_KBTAB
+       tristate "KB Gear JamStudio tablet support"
+       depends on USB && INPUT
+       help
+         Say Y here if you want to use the USB version of the KB Gear
+         JamStudio 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 kbtab.o.  If you want to compile it as a
+         module, say M here and read <file:Documentation/modules.txt>.
+
 config USB_POWERMATE
        tristate "Griffin PowerMate and Contour Jog support"
        depends on USB && INPUT
diff -x '*~' -x '*.orig' -x'.*' -uN linux-2.5.62/drivers/usb/input/Makefile 
linux-2.5.62-jbm/drivers/usb/input/Makefile
--- linux-2.5.62/drivers/usb/input/Makefile     2003-02-22 03:07:41.000000000 -0500
+++ linux-2.5.62-jbm/drivers/usb/input/Makefile 2003-02-21 23:51:44.000000000 -0500
@@ -31,5 +31,6 @@
 obj-$(CONFIG_USB_KBD)          += usbkbd.o
 obj-$(CONFIG_USB_MOUSE)                += usbmouse.o
 obj-$(CONFIG_USB_WACOM)                += wacom.o
+obj-$(CONFIG_USB_KBTAB)                += kbtab.o
 obj-$(CONFIG_USB_POWERMATE)    += powermate.o
 obj-$(CONFIG_USB_XPAD)         += xpad.o
Binary files linux-2.5.62/drivers/usb/input/built-in.o and 
linux-2.5.62-jbm/drivers/usb/input/built-in.o differ
diff -x '*~' -x '*.orig' -x'.*' -uN linux-2.5.62/drivers/usb/input/hid-core.c 
linux-2.5.62-jbm/drivers/usb/input/hid-core.c
--- linux-2.5.62/drivers/usb/input/hid-core.c   2003-02-22 03:07:41.000000000 -0500
+++ linux-2.5.62-jbm/drivers/usb/input/hid-core.c       2003-02-21 23:51:44.000000000 
-0500
@@ -1304,6 +1304,10 @@
 #define USB_DEVICE_ID_WACOM_PL         0x0030
 #define USB_DEVICE_ID_WACOM_INTUOS2    0x0040
 
+#define USB_VENDOR_ID_KBGEAR            0x084e
+#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO  0x1001
+
+
 #define USB_VENDOR_ID_AIPTEK           0x08ca
 #define USB_DEVICE_ID_AIPTEK_6000      0x0020
 
@@ -1355,6 +1359,7 @@
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 3, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 4, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 5, HID_QUIRK_IGNORE },
+       { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_6000, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
Binary files linux-2.5.62/drivers/usb/input/hid-core.o and 
linux-2.5.62-jbm/drivers/usb/input/hid-core.o differ
Binary files linux-2.5.62/drivers/usb/input/hid-input.o and 
linux-2.5.62-jbm/drivers/usb/input/hid-input.o differ
Binary files linux-2.5.62/drivers/usb/input/hid.o and 
linux-2.5.62-jbm/drivers/usb/input/hid.o differ
diff -x '*~' -x '*.orig' -x'.*' -uN linux-2.5.62/drivers/usb/input/kbtab.c 
linux-2.5.62-jbm/drivers/usb/input/kbtab.c
--- linux-2.5.62/drivers/usb/input/kbtab.c      1969-12-31 19:00:00.000000000 -0500
+++ linux-2.5.62-jbm/drivers/usb/input/kbtab.c  2003-02-22 03:07:20.000000000 -0500
@@ -0,0 +1,229 @@
+#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
+ * v0.0.1 - Original, extremely basic version, 2.4.xx only
+ * v0.0.2 - Updated, works with 2.5.62 and 2.4.20;
+ *           - added pressure-threshold modules param code from
+ *              Alex Perry <[EMAIL PROTECTED]>
+ */
+
+#define DRIVER_VERSION "v0.0.2"
+#define DRIVER_AUTHOR "Josh Myer <[EMAIL PROTECTED]>"
+#define DRIVER_DESC "USB KB Gear JamStudio Tablet driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+#define USB_VENDOR_ID_KBGEAR   0x084e
+
+static int       kb_pressure_click = 0x10;
+MODULE_PARM     (kb_pressure_click,"i");
+MODULE_PARM_DESC(kb_pressure_click,
+                "pressure threshold for clicks");
+
+struct kbtab {
+       signed char *data;
+       dma_addr_t data_dma;
+       struct input_dev dev;
+       struct usb_device *usbdev;
+       struct urb *irq;
+       int open;
+       int x, y;
+       int button;
+       int pressure;
+       __u32 serial[2];
+       char phys[32];
+};
+
+static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
+{
+       struct kbtab *kbtab = urb->context;
+       unsigned char *data = kbtab->data;
+       struct input_dev *dev = &kbtab->dev;
+       int retval;
+
+       switch (urb->status) {
+       case 0:
+               /* success */
+               break;
+       case -ECONNRESET:
+       case -ENOENT:
+       case -ESHUTDOWN:
+               /* this urb is terminated, clean up */
+               dbg("%s - urb shutting down with status: %d", __FUNCTION__, 
urb->status);
+               return;
+       default:
+               dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+               goto exit;
+       }
+
+       kbtab->x = (data[2] << 8) + data[1];
+       kbtab->y = (data[4] << 8) + data[3];
+
+       kbtab->pressure = (data[5]);
+
+       input_report_key(dev, BTN_TOOL_PEN, 1);
+
+       input_report_abs(dev, ABS_X, kbtab->x);
+       input_report_abs(dev, ABS_Y, kbtab->y);
+       /*input_report_abs(dev, ABS_PRESSURE, kbtab->pressure);*/
+
+       /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
+       input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
+       
+       input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0);
+       
+       input_sync(dev);
+
+ exit:
+       retval = usb_submit_urb (urb, GFP_ATOMIC);
+       if (retval)
+               err ("%s - usb_submit_urb failed with result %d",
+                    __FUNCTION__, retval);
+}
+
+struct usb_device_id kbtab_ids[] = {
+       { USB_DEVICE(USB_VENDOR_ID_KBGEAR, 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, GFP_KERNEL))
+               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 int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+       struct usb_device *dev = interface_to_usbdev(intf);
+       struct usb_endpoint_descriptor *endpoint;
+       struct kbtab *kbtab;
+       char path[64];
+
+       if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL)))
+               return -ENOMEM;
+       memset(kbtab, 0, sizeof(struct kbtab));
+
+       kbtab->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &kbtab->data_dma);
+       if (!kbtab->data) {
+               kfree(kbtab);
+               return -ENOMEM;
+       }
+
+       kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
+       if (!kbtab->irq) {
+               usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+               kfree(kbtab);
+               return -ENOMEM;
+       }
+
+       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_TOOL_PEN) | BIT(BTN_TOUCH);
+
+       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;
+
+       usb_make_path(dev, path, 64);
+       sprintf(kbtab->phys, "%s/input0", path);
+
+       kbtab->dev.name = "KB Gear Tablet";
+       kbtab->dev.phys = kbtab->phys;
+       kbtab->dev.id.bustype = BUS_USB;
+       kbtab->dev.id.vendor = dev->descriptor.idVendor;
+       kbtab->dev.id.product = dev->descriptor.idProduct;
+       kbtab->dev.id.version = dev->descriptor.bcdDevice;
+       kbtab->usbdev = dev;
+
+       endpoint = &intf->altsetting[0].endpoint[0].desc;
+
+       usb_fill_int_urb(kbtab->irq, dev,
+                        usb_rcvintpipe(dev, endpoint->bEndpointAddress),
+                        kbtab->data, 8,
+                        kbtab_irq, kbtab, endpoint->bInterval);
+       kbtab->irq->transfer_dma = kbtab->data_dma;
+       kbtab->irq->transfer_flags |= URB_NO_DMA_MAP;
+
+       input_register_device(&kbtab->dev);
+
+       printk(KERN_INFO "input: KB Gear Tablet on %s\n",  path);
+
+       usb_set_intfdata(intf, kbtab);
+
+       return 0;
+}
+
+static void kbtab_disconnect(struct usb_interface *intf)
+{
+       struct kbtab *kbtab = usb_get_intfdata (intf);
+
+       usb_set_intfdata(intf, NULL);
+       if (kbtab) {
+               usb_unlink_urb(kbtab->irq);
+               input_unregister_device(&kbtab->dev);
+               usb_free_urb(kbtab->irq);
+               usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, 
kbtab->data_dma);
+               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_DESC);
+       return 0;
+}
+
+static void __exit kbtab_exit(void)
+{
+       usb_deregister(&kbtab_driver);
+}
+
+module_init(kbtab_init);
+module_exit(kbtab_exit);

Reply via email to