]>
Commit | Line | Data |
---|---|---|
3bea733a | 1 | /* |
4104d13f | 2 | * drivers/input/tablet/wacom_sys.c |
3bea733a PC |
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 | ||
20 | static 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 | ||
30 | static 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 | ||
40 | static struct input_dev * get_input_dev(struct wacom_combo *wcombo) | |
41 | { | |
42 | return wcombo->wacom->dev; | |
43 | } | |
44 | ||
54c9b226 | 45 | static void wacom_sys_irq(struct urb *urb) |
3bea733a PC |
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 */ | |
ea3e6c59 | 59 | dbg("%s - urb shutting down with status: %d", __func__, urb->status); |
3bea733a PC |
60 | return; |
61 | default: | |
ea3e6c59 | 62 | dbg("%s - nonzero urb status received: %d", __func__, urb->status); |
3bea733a PC |
63 | goto exit; |
64 | } | |
65 | ||
66 | wcombo.wacom = wacom; | |
67 | wcombo.urb = urb; | |
3bea733a PC |
68 | |
69 | if (wacom_wac_irq(wacom->wacom_wac, (void *)&wcombo)) | |
70 | input_sync(get_input_dev(&wcombo)); | |
71 | ||
72 | exit: | |
e7224094 | 73 | usb_mark_last_busy(wacom->usbdev); |
3bea733a PC |
74 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
75 | if (retval) | |
76 | err ("%s - usb_submit_urb failed with result %d", | |
ea3e6c59 | 77 | __func__, retval); |
3bea733a PC |
78 | } |
79 | ||
80 | void wacom_report_key(void *wcombo, unsigned int key_type, int key_data) | |
81 | { | |
82 | input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data); | |
83 | return; | |
84 | } | |
85 | ||
86 | void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data) | |
87 | { | |
88 | input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data); | |
89 | return; | |
90 | } | |
91 | ||
92 | void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data) | |
93 | { | |
94 | input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data); | |
95 | return; | |
96 | } | |
97 | ||
98 | void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value) | |
99 | { | |
100 | input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value); | |
101 | return; | |
102 | } | |
103 | ||
104 | __u16 wacom_be16_to_cpu(unsigned char *data) | |
105 | { | |
106 | __u16 value; | |
107 | value = be16_to_cpu(*(__be16 *) data); | |
108 | return value; | |
109 | } | |
110 | ||
111 | __u16 wacom_le16_to_cpu(unsigned char *data) | |
112 | { | |
113 | __u16 value; | |
8d32e3ae | 114 | value = le16_to_cpu(*(__le16 *) data); |
3bea733a PC |
115 | return value; |
116 | } | |
117 | ||
3bea733a PC |
118 | void wacom_input_sync(void *wcombo) |
119 | { | |
120 | input_sync(get_input_dev((struct wacom_combo *)wcombo)); | |
121 | return; | |
122 | } | |
123 | ||
124 | static int wacom_open(struct input_dev *dev) | |
125 | { | |
7791bdae | 126 | struct wacom *wacom = input_get_drvdata(dev); |
3bea733a | 127 | |
e7224094 ON |
128 | mutex_lock(&wacom->lock); |
129 | ||
3bea733a | 130 | wacom->irq->dev = wacom->usbdev; |
e7224094 ON |
131 | |
132 | if (usb_autopm_get_interface(wacom->intf) < 0) { | |
133 | mutex_unlock(&wacom->lock); | |
3bea733a | 134 | return -EIO; |
e7224094 ON |
135 | } |
136 | ||
137 | if (usb_submit_urb(wacom->irq, GFP_KERNEL)) { | |
138 | usb_autopm_put_interface(wacom->intf); | |
139 | mutex_unlock(&wacom->lock); | |
140 | return -EIO; | |
141 | } | |
142 | ||
143 | wacom->open = 1; | |
144 | wacom->intf->needs_remote_wakeup = 1; | |
3bea733a | 145 | |
e7224094 | 146 | mutex_unlock(&wacom->lock); |
3bea733a PC |
147 | return 0; |
148 | } | |
149 | ||
150 | static void wacom_close(struct input_dev *dev) | |
151 | { | |
7791bdae | 152 | struct wacom *wacom = input_get_drvdata(dev); |
3bea733a | 153 | |
e7224094 | 154 | mutex_lock(&wacom->lock); |
3bea733a | 155 | usb_kill_urb(wacom->irq); |
e7224094 ON |
156 | wacom->open = 0; |
157 | wacom->intf->needs_remote_wakeup = 0; | |
158 | mutex_unlock(&wacom->lock); | |
3bea733a PC |
159 | } |
160 | ||
7ecfbfd3 PC |
161 | void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
162 | { | |
7b19ada2 JS |
163 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) | |
164 | BIT_MASK(BTN_5); | |
7ecfbfd3 PC |
165 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
166 | } | |
167 | ||
3bea733a PC |
168 | void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
169 | { | |
7b19ada2 JS |
170 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); |
171 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | |
172 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | |
173 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | | |
174 | BIT_MASK(BTN_4); | |
3bea733a PC |
175 | } |
176 | ||
177 | void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |
178 | { | |
7b19ada2 JS |
179 | input_dev->evbit[0] |= BIT_MASK(EV_REL); |
180 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); | |
181 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | |
182 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | |
183 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | |
184 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); | |
3bea733a PC |
185 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); |
186 | } | |
187 | ||
8d32e3ae | 188 | void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
3bea733a | 189 | { |
7b19ada2 JS |
190 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); |
191 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | | |
192 | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); | |
071e0a2a | 193 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
0e1763f5 | 194 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
8d32e3ae PC |
195 | } |
196 | ||
197 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |
198 | { | |
7b19ada2 JS |
199 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) | |
200 | BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); | |
071e0a2a | 201 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
3bea733a PC |
202 | } |
203 | ||
0e1763f5 PC |
204 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
205 | { | |
206 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); | |
207 | } | |
208 | ||
3bea733a PC |
209 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
210 | { | |
7b19ada2 JS |
211 | input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); |
212 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | |
213 | input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); | |
214 | input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | | |
215 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | | |
216 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | |
217 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | |
218 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | | |
219 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | | |
220 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); | |
3bea733a PC |
221 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); |
222 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); | |
223 | input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); | |
224 | input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); | |
225 | input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0); | |
226 | input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0); | |
227 | } | |
228 | ||
229 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |
230 | { | |
7b19ada2 JS |
231 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) | |
232 | BIT_MASK(BTN_TOOL_RUBBER); | |
3bea733a PC |
233 | } |
234 | ||
235 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |
236 | { | |
7b19ada2 | 237 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); |
3bea733a PC |
238 | } |
239 | ||
240 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | |
241 | { | |
242 | struct usb_device *dev = interface_to_usbdev(intf); | |
243 | struct usb_endpoint_descriptor *endpoint; | |
244 | struct wacom *wacom; | |
245 | struct wacom_wac *wacom_wac; | |
246 | struct input_dev *input_dev; | |
5014186d | 247 | int error = -ENOMEM; |
3bea733a PC |
248 | char rep_data[2], limit = 0; |
249 | ||
250 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | |
251 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); | |
252 | input_dev = input_allocate_device(); | |
253 | if (!wacom || !input_dev || !wacom_wac) | |
254 | goto fail1; | |
255 | ||
256 | wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); | |
257 | if (!wacom_wac->data) | |
258 | goto fail1; | |
259 | ||
260 | wacom->irq = usb_alloc_urb(0, GFP_KERNEL); | |
261 | if (!wacom->irq) | |
262 | goto fail2; | |
263 | ||
264 | wacom->usbdev = dev; | |
265 | wacom->dev = input_dev; | |
e7224094 ON |
266 | wacom->intf = intf; |
267 | mutex_init(&wacom->lock); | |
3bea733a PC |
268 | usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); |
269 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | |
270 | ||
271 | wacom_wac->features = get_wacom_feature(id); | |
2920349d | 272 | BUG_ON(wacom_wac->features->pktlen > 10); |
3bea733a PC |
273 | |
274 | input_dev->name = wacom_wac->features->name; | |
275 | wacom->wacom_wac = wacom_wac; | |
276 | usb_to_input_id(dev, &input_dev->id); | |
277 | ||
c0f82d57 | 278 | input_dev->dev.parent = &intf->dev; |
7791bdae DT |
279 | |
280 | input_set_drvdata(input_dev, wacom); | |
281 | ||
3bea733a PC |
282 | input_dev->open = wacom_open; |
283 | input_dev->close = wacom_close; | |
284 | ||
7b19ada2 JS |
285 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
286 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | |
287 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); | |
3bea733a PC |
288 | input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); |
289 | input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); | |
290 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); | |
7b19ada2 | 291 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
3bea733a PC |
292 | |
293 | wacom_init_input_dev(input_dev, wacom_wac); | |
294 | ||
295 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | |
296 | ||
297 | usb_fill_int_urb(wacom->irq, dev, | |
298 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | |
299 | wacom_wac->data, wacom_wac->features->pktlen, | |
8d32e3ae | 300 | wacom_sys_irq, wacom, endpoint->bInterval); |
3bea733a PC |
301 | wacom->irq->transfer_dma = wacom->data_dma; |
302 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | |
303 | ||
5014186d DT |
304 | error = input_register_device(wacom->dev); |
305 | if (error) | |
306 | goto fail3; | |
3bea733a PC |
307 | |
308 | /* Ask the tablet to report tablet data. Repeat until it succeeds */ | |
309 | do { | |
310 | rep_data[0] = 2; | |
311 | rep_data[1] = 2; | |
312 | usb_set_report(intf, 3, 2, rep_data, 2); | |
313 | usb_get_report(intf, 3, 2, rep_data, 2); | |
314 | } while (rep_data[1] != 2 && limit++ < 5); | |
315 | ||
316 | usb_set_intfdata(intf, wacom); | |
317 | return 0; | |
318 | ||
5014186d DT |
319 | fail3: usb_free_urb(wacom->irq); |
320 | fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); | |
321 | fail1: input_free_device(input_dev); | |
3bea733a PC |
322 | kfree(wacom); |
323 | kfree(wacom_wac); | |
5014186d | 324 | return error; |
3bea733a PC |
325 | } |
326 | ||
327 | static void wacom_disconnect(struct usb_interface *intf) | |
328 | { | |
e7224094 | 329 | struct wacom *wacom = usb_get_intfdata(intf); |
3bea733a PC |
330 | |
331 | usb_set_intfdata(intf, NULL); | |
e7224094 ON |
332 | |
333 | usb_kill_urb(wacom->irq); | |
334 | input_unregister_device(wacom->dev); | |
335 | usb_free_urb(wacom->irq); | |
336 | usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma); | |
337 | kfree(wacom->wacom_wac); | |
338 | kfree(wacom); | |
339 | } | |
340 | ||
341 | static int wacom_suspend(struct usb_interface *intf, pm_message_t message) | |
342 | { | |
343 | struct wacom *wacom = usb_get_intfdata(intf); | |
344 | ||
345 | mutex_lock(&wacom->lock); | |
346 | usb_kill_urb(wacom->irq); | |
347 | mutex_unlock(&wacom->lock); | |
348 | ||
349 | return 0; | |
350 | } | |
351 | ||
352 | static int wacom_resume(struct usb_interface *intf) | |
353 | { | |
354 | struct wacom *wacom = usb_get_intfdata(intf); | |
355 | int rv; | |
356 | ||
357 | mutex_lock(&wacom->lock); | |
358 | if (wacom->open) | |
359 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | |
360 | else | |
361 | rv = 0; | |
362 | mutex_unlock(&wacom->lock); | |
363 | ||
364 | return rv; | |
365 | } | |
366 | ||
367 | static int wacom_reset_resume(struct usb_interface *intf) | |
368 | { | |
369 | return wacom_resume(intf); | |
3bea733a PC |
370 | } |
371 | ||
372 | static struct usb_driver wacom_driver = { | |
373 | .name = "wacom", | |
374 | .probe = wacom_probe, | |
375 | .disconnect = wacom_disconnect, | |
e7224094 ON |
376 | .suspend = wacom_suspend, |
377 | .resume = wacom_resume, | |
378 | .reset_resume = wacom_reset_resume, | |
379 | .supports_autosuspend = 1, | |
3bea733a PC |
380 | }; |
381 | ||
382 | static int __init wacom_init(void) | |
383 | { | |
384 | int result; | |
385 | wacom_driver.id_table = get_device_table(); | |
386 | result = usb_register(&wacom_driver); | |
387 | if (result == 0) | |
388 | info(DRIVER_VERSION ":" DRIVER_DESC); | |
389 | return result; | |
390 | } | |
391 | ||
392 | static void __exit wacom_exit(void) | |
393 | { | |
394 | usb_deregister(&wacom_driver); | |
395 | } | |
396 | ||
397 | module_init(wacom_init); | |
398 | module_exit(wacom_exit); |