Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.23 324 lines 9.6 kB view raw
1/* 2 * drivers/input/tablet/wacom_sys.c 3 * 4 * USB Wacom Graphire and Wacom Intuos tablet support - system specific code 5 */ 6 7/* 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14#include "wacom.h" 15#include "wacom_wac.h" 16 17#define USB_REQ_GET_REPORT 0x01 18#define USB_REQ_SET_REPORT 0x09 19 20static int usb_get_report(struct usb_interface *intf, unsigned char type, 21 unsigned char id, void *buf, int size) 22{ 23 return usb_control_msg(interface_to_usbdev(intf), 24 usb_rcvctrlpipe(interface_to_usbdev(intf), 0), 25 USB_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 26 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 27 buf, size, 100); 28} 29 30static int usb_set_report(struct usb_interface *intf, unsigned char type, 31 unsigned char id, void *buf, int size) 32{ 33 return usb_control_msg(interface_to_usbdev(intf), 34 usb_sndctrlpipe(interface_to_usbdev(intf), 0), 35 USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 36 (type << 8) + id, intf->altsetting[0].desc.bInterfaceNumber, 37 buf, size, 1000); 38} 39 40static struct input_dev * get_input_dev(struct wacom_combo *wcombo) 41{ 42 return wcombo->wacom->dev; 43} 44 45static void wacom_sys_irq(struct urb *urb) 46{ 47 struct wacom *wacom = urb->context; 48 struct wacom_combo wcombo; 49 int retval; 50 51 switch (urb->status) { 52 case 0: 53 /* success */ 54 break; 55 case -ECONNRESET: 56 case -ENOENT: 57 case -ESHUTDOWN: 58 /* this urb is terminated, clean up */ 59 dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); 60 return; 61 default: 62 dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); 63 goto exit; 64 } 65 66 wcombo.wacom = wacom; 67 wcombo.urb = urb; 68 69 if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) 70 input_sync(get_input_dev(&wcombo)); 71 72 exit: 73 retval = usb_submit_urb (urb, GFP_ATOMIC); 74 if (retval) 75 err ("%s - usb_submit_urb failed with result %d", 76 __FUNCTION__, retval); 77} 78 79void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) 80{ 81 input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); 82 return; 83} 84 85void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) 86{ 87 input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); 88 return; 89} 90 91void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) 92{ 93 input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); 94 return; 95} 96 97void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) 98{ 99 input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); 100 return; 101} 102 103__u16 wacom_be16_to_cpu(unsigned char *data) 104{ 105 __u16 value; 106 value = be16_to_cpu(*(__be16 *) data); 107 return value; 108} 109 110__u16 wacom_le16_to_cpu(unsigned char *data) 111{ 112 __u16 value; 113 value = le16_to_cpu(*(__le16 *) data); 114 return value; 115} 116 117void wacom_input_sync(void *wcombo) 118{ 119 input_sync(get_input_dev((struct wacom_combo *)wcombo)); 120 return; 121} 122 123static int wacom_open(struct input_dev *dev) 124{ 125 struct wacom *wacom = input_get_drvdata(dev); 126 127 wacom->irq->dev = wacom->usbdev; 128 if (usb_submit_urb(wacom->irq, GFP_KERNEL)) 129 return -EIO; 130 131 return 0; 132} 133 134static void wacom_close(struct input_dev *dev) 135{ 136 struct wacom *wacom = input_get_drvdata(dev); 137 138 usb_kill_urb(wacom->irq); 139} 140 141void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 142{ 143 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5); 144 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); 145} 146 147void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 148{ 149 input_dev->evbit[0] |= BIT(EV_MSC); 150 input_dev->mscbit[0] |= BIT(MSC_SERIAL); 151 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); 152 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4); 153} 154 155void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 156{ 157 input_dev->evbit[0] |= BIT(EV_REL); 158 input_dev->relbit[0] |= BIT(REL_WHEEL); 159 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); 160 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); 161 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); 162} 163 164void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 165{ 166 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); 167 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); 168 input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); 169} 170 171void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 172{ 173 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); 174 input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); 175} 176 177void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 178{ 179 input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); 180 input_dev->mscbit[0] |= BIT(MSC_SERIAL); 181 input_dev->relbit[0] |= BIT(REL_WHEEL); 182 input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); 183 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) 184 | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); 185 input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); 186 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); 187 input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); 188 input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); 189 input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); 190 input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); 191} 192 193void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 194{ 195 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); 196} 197 198void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) 199{ 200 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); 201} 202 203static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) 204{ 205 struct usb_device *dev = interface_to_usbdev(intf); 206 struct usb_endpoint_descriptor *endpoint; 207 struct wacom *wacom; 208 struct wacom_wac *wacom_wac; 209 struct input_dev *input_dev; 210 int error = -ENOMEM; 211 char rep_data[2], limit = 0; 212 213 wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); 214 wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); 215 input_dev = input_allocate_device(); 216 if (!wacom || !input_dev || !wacom_wac) 217 goto fail1; 218 219 wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); 220 if (!wacom_wac->data) 221 goto fail1; 222 223 wacom->irq = usb_alloc_urb(0, GFP_KERNEL); 224 if (!wacom->irq) 225 goto fail2; 226 227 wacom->usbdev = dev; 228 wacom->dev = input_dev; 229 usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); 230 strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); 231 232 wacom_wac->features = get_wacom_feature(id); 233 BUG_ON(wacom_wac->features->pktlen > 10); 234 235 input_dev->name = wacom_wac->features->name; 236 wacom->wacom_wac = wacom_wac; 237 usb_to_input_id(dev, &input_dev->id); 238 239 input_dev->dev.parent = &intf->dev; 240 241 input_set_drvdata(input_dev, wacom); 242 243 input_dev->open = wacom_open; 244 input_dev->close = wacom_close; 245 246 input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); 247 input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); 248 input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); 249 input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); 250 input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); 251 input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); 252 253 wacom_init_input_dev(input_dev, wacom_wac); 254 255 endpoint = &intf->cur_altsetting->endpoint[0].desc; 256 257 usb_fill_int_urb(wacom->irq, dev, 258 usb_rcvintpipe(dev, endpoint->bEndpointAddress), 259 wacom_wac->data, wacom_wac->features->pktlen, 260 wacom_sys_irq, wacom, endpoint->bInterval); 261 wacom->irq->transfer_dma = wacom->data_dma; 262 wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 263 264 error = input_register_device(wacom->dev); 265 if (error) 266 goto fail3; 267 268 /* Ask the tablet to report tablet data. Repeat until it succeeds */ 269 do { 270 rep_data[0] = 2; 271 rep_data[1] = 2; 272 usb_set_report(intf, 3, 2, rep_data, 2); 273 usb_get_report(intf, 3, 2, rep_data, 2); 274 } while (rep_data[1] != 2 && limit++ < 5); 275 276 usb_set_intfdata(intf, wacom); 277 return 0; 278 279 fail3: usb_free_urb(wacom->irq); 280 fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); 281 fail1: input_free_device(input_dev); 282 kfree(wacom); 283 kfree(wacom_wac); 284 return error; 285} 286 287static void wacom_disconnect(struct usb_interface *intf) 288{ 289 struct wacom *wacom = usb_get_intfdata (intf); 290 291 usb_set_intfdata(intf, NULL); 292 if (wacom) { 293 usb_kill_urb(wacom->irq); 294 input_unregister_device(wacom->dev); 295 usb_free_urb(wacom->irq); 296 usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); 297 kfree(wacom->wacom_wac); 298 kfree(wacom); 299 } 300} 301 302static struct usb_driver wacom_driver = { 303 .name = "wacom", 304 .probe = wacom_probe, 305 .disconnect = wacom_disconnect, 306}; 307 308static int __init wacom_init(void) 309{ 310 int result; 311 wacom_driver.id_table = get_device_table(); 312 result = usb_register(&wacom_driver); 313 if (result == 0) 314 info(DRIVER_VERSION ":" DRIVER_DESC); 315 return result; 316} 317 318static void __exit wacom_exit(void) 319{ 320 usb_deregister(&wacom_driver); 321} 322 323module_init(wacom_init); 324module_exit(wacom_exit);