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);