📄 wacom.c
字号:
static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs){ struct wacom *wacom = urb->context; unsigned char *data = wacom->data; struct input_dev *dev = &wacom->dev; unsigned int t; int idx; 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; } if (data[0] != 2) dbg("wacom_intuos_irq: received unknown report #%d", data[0]); input_regs(dev, regs); /* tool number */ idx = data[1] & 0x01; if ((data[1] & 0xfc) == 0xc0) { /* Enter report */ wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) + /* serial number of the tool */ ((__u32)data[4] << 20) + ((__u32)data[5] << 12) + ((__u32)data[6] << 4) + (data[7] >> 4); switch (((__u32)data[2] << 4) | (data[3] >> 4)) { case 0x812: case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL; break; /* Inking pen */ case 0x822: case 0x842: case 0x852: case 0x022: wacom->tool[idx] = BTN_TOOL_PEN; break; /* Pen */ case 0x832: case 0x032: wacom->tool[idx] = BTN_TOOL_BRUSH; break; /* Stroke pen */ case 0x007: case 0x09c: case 0x094: wacom->tool[idx] = BTN_TOOL_MOUSE; break; /* Mouse 4D and 2D */ case 0x096: wacom->tool[idx] = BTN_TOOL_LENS; break; /* Lens cursor */ case 0x82a: case 0x85a: case 0x91a: case 0xd1a: case 0x0fa: wacom->tool[idx] = BTN_TOOL_RUBBER; break; /* Eraser */ case 0xd12: case 0x912: case 0x112: wacom->tool[idx] = BTN_TOOL_AIRBRUSH; break; /* Airbrush */ default: wacom->tool[idx] = BTN_TOOL_PEN; break; /* Unknown tool */ } input_report_key(dev, wacom->tool[idx], 1); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); goto exit; } if ((data[1] & 0xfe) == 0x80) { /* Exit report */ input_report_key(dev, wacom->tool[idx], 0); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev); goto exit; } input_report_abs(dev, ABS_X, be16_to_cpu(*(u16 *) &data[2])); input_report_abs(dev, ABS_Y, be16_to_cpu(*(u16 *) &data[4])); input_report_abs(dev, ABS_DISTANCE, data[9]); if ((data[1] & 0xb8) == 0xa0) { /* general pen packet */ input_report_abs(dev, ABS_PRESSURE, t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); input_report_key(dev, BTN_STYLUS, data[1] & 2); input_report_key(dev, BTN_STYLUS2, data[1] & 4); input_report_key(dev, BTN_TOUCH, t > 10); } if ((data[1] & 0xbc) == 0xb4) { /* airbrush second packet */ input_report_abs(dev, ABS_WHEEL, ((__u32)data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(dev, ABS_TILT_X, ((data[7] << 1) & 0x7e) | (data[8] >> 7)); input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f); } if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { /* 4D mouse or Lens cursor packets */ if (data[1] & 0x02) { /* Rotation packet */ input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? ((__u32)data[6] << 3) | ((data[7] >> 5) & 7): (-(((__u32)data[6] << 3) | ((data[7] >> 5) & 7))) - 1); } else { if ((data[1] & 0x10) == 0) { /* 4D mouse packets */ input_report_key(dev, BTN_LEFT, data[8] & 0x01); input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); input_report_key(dev, BTN_RIGHT, data[8] & 0x04); input_report_key(dev, BTN_SIDE, data[8] & 0x20); input_report_key(dev, BTN_EXTRA, data[8] & 0x10); input_report_abs(dev, ABS_THROTTLE, -((data[8] & 0x08) ? ((__u32)data[6] << 2) | ((data[7] >> 6) & 3) : -((__u32)data[6] << 2) | ((data[7] >> 6) & 3))); } else { if (wacom->tool[idx] == BTN_TOOL_MOUSE) { /* 2D mouse packets */ input_report_key(dev, BTN_LEFT, data[8] & 0x04); input_report_key(dev, BTN_MIDDLE, data[8] & 0x08); input_report_key(dev, BTN_RIGHT, data[8] & 0x10); input_report_rel(dev, REL_WHEEL, (-(__u32)(data[8] & 0x01) + (__u32)((data[8] & 0x02) >> 1))); } else { /* Lens cursor packets */ input_report_key(dev, BTN_LEFT, data[8] & 0x01); input_report_key(dev, BTN_MIDDLE, data[8] & 0x02); input_report_key(dev, BTN_RIGHT, data[8] & 0x04); input_report_key(dev, BTN_SIDE, data[8] & 0x10); input_report_key(dev, BTN_EXTRA, data[8] & 0x08); } } } } input_report_key(dev, wacom->tool[idx], 1); input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]); input_sync(dev);exit: retval = usb_submit_urb (urb, GFP_ATOMIC); if (retval) err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval);}static struct wacom_features wacom_features[] = { { "Wacom Penpartner", 7, 5040, 3780, 255, 32, 0, wacom_penpartner_irq }, { "Wacom Graphire", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 32, 1, wacom_graphire_irq }, { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, 1, wacom_graphire_irq }, { "Wacom Graphire3", 8, 10208, 7424, 511, 32, 1, wacom_graphire_irq }, { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, 1, wacom_graphire_irq }, { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, { "Wacom PL400", 8, 5408, 4056, 255, 32, 3, wacom_pl_irq }, { "Wacom PL500", 8, 6144, 4608, 255, 32, 3, wacom_pl_irq }, { "Wacom PL600", 8, 6126, 4604, 255, 32, 3, wacom_pl_irq }, { "Wacom PL600SX", 8, 6260, 5016, 255, 32, 3, wacom_pl_irq }, { "Wacom PL550", 8, 6144, 4608, 511, 32, 3, wacom_pl_irq }, { "Wacom PL800", 8, 7220, 5780, 511, 32, 3, wacom_pl_irq }, { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq }, { "Wacom Volito", 8, 5104, 3712, 511, 32, 1, wacom_graphire_irq }, { "Wacom Cintiq Partner",8, 20480, 15360, 511, 32, 3, wacom_ptu_irq }, { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq }, { }};static struct usb_device_id wacom_ids[] = { { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x00) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x10) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x11) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x12) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x13) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x14) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x20) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x21) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x22) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x23) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x24) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x30) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x31) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x32) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x33) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x34) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x35) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x41) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x42) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x43) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x44) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x45) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x03) }, { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, { }};MODULE_DEVICE_TABLE(usb, wacom_ids);static int wacom_open(struct input_dev *dev){ struct wacom *wacom = dev->private; if (wacom->open++) return 0; wacom->irq->dev = wacom->usbdev; if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { wacom->open--; return -EIO; } return 0;}static void wacom_close(struct input_dev *dev){ struct wacom *wacom = dev->private; if (!--wacom->open) usb_unlink_urb(wacom->irq);}static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id){ struct usb_device *dev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; char rep_data[2] = {0x02, 0x02}; struct wacom *wacom; char path[64]; if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL))) return -ENOMEM; memset(wacom, 0, sizeof(struct wacom)); wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); if (!wacom->data) { kfree(wacom); return -ENOMEM; } wacom->irq = usb_alloc_urb(0, GFP_KERNEL); if (!wacom->irq) { usb_buffer_free(dev, 10, wacom->data, wacom->data_dma); kfree(wacom); return -ENOMEM; } wacom->features = wacom_features + (id - wacom_ids); wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); switch (wacom->features->type) { case 1: wacom->dev.evbit[0] |= BIT(EV_REL); wacom->dev.relbit[0] |= BIT(REL_WHEEL); wacom->dev.absbit[0] |= BIT(ABS_DISTANCE); wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); break; case 2: wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); wacom->dev.mscbit[0] |= BIT(MSC_SERIAL); wacom->dev.relbit[0] |= BIT(REL_WHEEL); wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE); break; case 3: wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2); break; } wacom->dev.absmax[ABS_X] = wacom->features->x_max; wacom->dev.absmax[ABS_Y] = wacom->features->y_max; wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max; wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max; wacom->dev.absmax[ABS_TILT_X] = 127; wacom->dev.absmax[ABS_TILT_Y] = 127; wacom->dev.absmax[ABS_WHEEL] = 1023; wacom->dev.absmin[ABS_RZ] = -900; wacom->dev.absmax[ABS_RZ] = 899; wacom->dev.absmin[ABS_THROTTLE] = -1023; wacom->dev.absmax[ABS_THROTTLE] = 1023; wacom->dev.absfuzz[ABS_X] = 4; wacom->dev.absfuzz[ABS_Y] = 4; wacom->dev.private = wacom; wacom->dev.open = wacom_open; wacom->dev.close = wacom_close; usb_make_path(dev, path, 64); sprintf(wacom->phys, "%s/input0", path); wacom->dev.name = wacom->features->name; wacom->dev.phys = wacom->phys; wacom->dev.id.bustype = BUS_USB; wacom->dev.id.vendor = dev->descriptor.idVendor; wacom->dev.id.product = dev->descriptor.idProduct; wacom->dev.id.version = dev->descriptor.bcdDevice; wacom->dev.dev = &intf->dev; wacom->usbdev = dev; endpoint = &intf->cur_altsetting->endpoint[0].desc; if (wacom->features->pktlen > 10) BUG(); usb_fill_int_urb(wacom->irq, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), wacom->data, wacom->features->pktlen, wacom->features->irq, wacom, endpoint->bInterval); wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; input_register_device(&wacom->dev); usb_set_report(intf, 3, 2, rep_data, 2); usb_set_report(intf, 3, 5, rep_data, 0); usb_set_report(intf, 3, 6, rep_data, 0); printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path); usb_set_intfdata(intf, wacom); return 0;}static void wacom_disconnect(struct usb_interface *intf){ struct wacom *wacom = usb_get_intfdata (intf); usb_set_intfdata(intf, NULL); if (wacom) { usb_unlink_urb(wacom->irq); input_unregister_device(&wacom->dev); usb_free_urb(wacom->irq); usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma); kfree(wacom); }}static struct usb_driver wacom_driver = { .owner = THIS_MODULE, .name = "wacom", .probe = wacom_probe, .disconnect = wacom_disconnect, .id_table = wacom_ids,};static int __init wacom_init(void){ int result = usb_register(&wacom_driver); if (result == 0) info(DRIVER_VERSION ":" DRIVER_DESC); return result;}static void __exit wacom_exit(void){ usb_deregister(&wacom_driver);}module_init(wacom_init);module_exit(wacom_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -