Attached are 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.
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);