Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.14 232 lines 5.6 kB view raw
1#include <linux/kernel.h> 2#include <linux/slab.h> 3#include <linux/input.h> 4#include <linux/module.h> 5#include <linux/init.h> 6#include <linux/usb.h> 7#include <linux/usb_input.h> 8#include <asm/unaligned.h> 9#include <asm/byteorder.h> 10 11/* 12 * Version Information 13 * v0.0.1 - Original, extremely basic version, 2.4.xx only 14 * v0.0.2 - Updated, works with 2.5.62 and 2.4.20; 15 * - added pressure-threshold modules param code from 16 * Alex Perry <alex.perry@ieee.org> 17 */ 18 19#define DRIVER_VERSION "v0.0.2" 20#define DRIVER_AUTHOR "Josh Myer <josh@joshisanerd.com>" 21#define DRIVER_DESC "USB KB Gear JamStudio Tablet driver" 22#define DRIVER_LICENSE "GPL" 23 24MODULE_AUTHOR(DRIVER_AUTHOR); 25MODULE_DESCRIPTION(DRIVER_DESC); 26MODULE_LICENSE(DRIVER_LICENSE); 27 28#define USB_VENDOR_ID_KBGEAR 0x084e 29 30static int kb_pressure_click = 0x10; 31module_param(kb_pressure_click, int, 0); 32MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks"); 33 34struct kbtab { 35 signed char *data; 36 dma_addr_t data_dma; 37 struct input_dev dev; 38 struct usb_device *usbdev; 39 struct urb *irq; 40 int x, y; 41 int button; 42 int pressure; 43 __u32 serial[2]; 44 char phys[32]; 45}; 46 47static void kbtab_irq(struct urb *urb, struct pt_regs *regs) 48{ 49 struct kbtab *kbtab = urb->context; 50 unsigned char *data = kbtab->data; 51 struct input_dev *dev = &kbtab->dev; 52 int retval; 53 54 switch (urb->status) { 55 case 0: 56 /* success */ 57 break; 58 case -ECONNRESET: 59 case -ENOENT: 60 case -ESHUTDOWN: 61 /* this urb is terminated, clean up */ 62 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 63 return; 64 default: 65 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 66 goto exit; 67 } 68 69 kbtab->x = le16_to_cpu(get_unaligned((__le16 *) &data[1])); 70 kbtab->y = le16_to_cpu(get_unaligned((__le16 *) &data[3])); 71 72 kbtab->pressure = (data[5]); 73 74 input_report_key(dev, BTN_TOOL_PEN, 1); 75 76 input_report_abs(dev, ABS_X, kbtab->x); 77 input_report_abs(dev, ABS_Y, kbtab->y); 78 79 /*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/ 80 input_report_key(dev, BTN_RIGHT, data[0] & 0x02); 81 82 if (-1 == kb_pressure_click) { 83 input_report_abs(dev, ABS_PRESSURE, kbtab->pressure); 84 } else { 85 input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0); 86 }; 87 88 input_sync(dev); 89 90 exit: 91 retval = usb_submit_urb (urb, GFP_ATOMIC); 92 if (retval) 93 err ("%s - usb_submit_urb failed with result %d", 94 __FUNCTION__, retval); 95} 96 97static struct usb_device_id kbtab_ids[] = { 98 { USB_DEVICE(USB_VENDOR_ID_KBGEAR, 0x1001), .driver_info = 0 }, 99 { } 100}; 101 102MODULE_DEVICE_TABLE(usb, kbtab_ids); 103 104static int kbtab_open(struct input_dev *dev) 105{ 106 struct kbtab *kbtab = dev->private; 107 108 kbtab->irq->dev = kbtab->usbdev; 109 if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) 110 return -EIO; 111 112 return 0; 113} 114 115static void kbtab_close(struct input_dev *dev) 116{ 117 struct kbtab *kbtab = dev->private; 118 119 usb_kill_urb(kbtab->irq); 120} 121 122static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id) 123{ 124 struct usb_device *dev = interface_to_usbdev(intf); 125 struct usb_endpoint_descriptor *endpoint; 126 struct kbtab *kbtab; 127 char path[64]; 128 129 if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL))) 130 return -ENOMEM; 131 memset(kbtab, 0, sizeof(struct kbtab)); 132 133 kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma); 134 if (!kbtab->data) { 135 kfree(kbtab); 136 return -ENOMEM; 137 } 138 139 kbtab->irq = usb_alloc_urb(0, GFP_KERNEL); 140 if (!kbtab->irq) { 141 usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); 142 kfree(kbtab); 143 return -ENOMEM; 144 } 145 146 kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); 147 kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); 148 149 kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); 150 151 kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH); 152 153 kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL); 154 155 kbtab->dev.absmax[ABS_X] = 0x2000; 156 kbtab->dev.absmax[ABS_Y] = 0x1750; 157 kbtab->dev.absmax[ABS_PRESSURE] = 0xff; 158 159 kbtab->dev.absfuzz[ABS_X] = 4; 160 kbtab->dev.absfuzz[ABS_Y] = 4; 161 162 kbtab->dev.private = kbtab; 163 kbtab->dev.open = kbtab_open; 164 kbtab->dev.close = kbtab_close; 165 166 usb_make_path(dev, path, 64); 167 sprintf(kbtab->phys, "%s/input0", path); 168 169 kbtab->dev.name = "KB Gear Tablet"; 170 kbtab->dev.phys = kbtab->phys; 171 usb_to_input_id(dev, &kbtab->dev.id); 172 kbtab->dev.dev = &intf->dev; 173 kbtab->usbdev = dev; 174 175 endpoint = &intf->cur_altsetting->endpoint[0].desc; 176 177 usb_fill_int_urb(kbtab->irq, dev, 178 usb_rcvintpipe(dev, endpoint->bEndpointAddress), 179 kbtab->data, 8, 180 kbtab_irq, kbtab, endpoint->bInterval); 181 kbtab->irq->transfer_dma = kbtab->data_dma; 182 kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 183 184 input_register_device(&kbtab->dev); 185 186 printk(KERN_INFO "input: KB Gear Tablet on %s\n", path); 187 188 usb_set_intfdata(intf, kbtab); 189 190 return 0; 191} 192 193static void kbtab_disconnect(struct usb_interface *intf) 194{ 195 struct kbtab *kbtab = usb_get_intfdata (intf); 196 197 usb_set_intfdata(intf, NULL); 198 if (kbtab) { 199 usb_kill_urb(kbtab->irq); 200 input_unregister_device(&kbtab->dev); 201 usb_free_urb(kbtab->irq); 202 usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma); 203 kfree(kbtab); 204 } 205} 206 207static struct usb_driver kbtab_driver = { 208 .owner = THIS_MODULE, 209 .name = "kbtab", 210 .probe = kbtab_probe, 211 .disconnect = kbtab_disconnect, 212 .id_table = kbtab_ids, 213}; 214 215static int __init kbtab_init(void) 216{ 217 int retval; 218 retval = usb_register(&kbtab_driver); 219 if (retval) 220 goto out; 221 info(DRIVER_VERSION ":" DRIVER_DESC); 222out: 223 return retval; 224} 225 226static void __exit kbtab_exit(void) 227{ 228 usb_deregister(&kbtab_driver); 229} 230 231module_init(kbtab_init); 232module_exit(kbtab_exit);