Merge git://git.jan-o-sch.net/btrfs-unstable into for-linus
[pandora-kernel.git] / drivers / hid / hid-wacom.c
1 /*
2  *  Bluetooth Wacom Tablet support
3  *
4  *  Copyright (c) 1999 Andreas Gal
5  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7  *  Copyright (c) 2006-2007 Jiri Kosina
8  *  Copyright (c) 2007 Paul Walmsley
9  *  Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
10  *  Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru>
11  *  Copyright (c) 2009 Bastien Nocera <hadess@hadess.net>
12  *  Copyright (c) 2011 Przemysław Firszt <przemo@firszt.eu>
13  */
14
15 /*
16  * This program is free software; you can redistribute it and/or modify it
17  * under the terms of the GNU General Public License as published by the Free
18  * Software Foundation; either version 2 of the License, or (at your option)
19  * any later version.
20  */
21
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
24 #include <linux/device.h>
25 #include <linux/hid.h>
26 #include <linux/module.h>
27 #include <linux/slab.h>
28 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
29 #include <linux/power_supply.h>
30 #endif
31
32 #include "hid-ids.h"
33
34 struct wacom_data {
35         __u16 tool;
36         unsigned char butstate;
37         __u8 features;
38         unsigned char high_speed;
39 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
40         int battery_capacity;
41         struct power_supply battery;
42         struct power_supply ac;
43 #endif
44 };
45
46 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
47 /*percent of battery capacity, 0 means AC online*/
48 static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
49
50 static enum power_supply_property wacom_battery_props[] = {
51         POWER_SUPPLY_PROP_PRESENT,
52         POWER_SUPPLY_PROP_CAPACITY,
53         POWER_SUPPLY_PROP_SCOPE,
54 };
55
56 static enum power_supply_property wacom_ac_props[] = {
57         POWER_SUPPLY_PROP_PRESENT,
58         POWER_SUPPLY_PROP_ONLINE,
59         POWER_SUPPLY_PROP_SCOPE,
60 };
61
62 static int wacom_battery_get_property(struct power_supply *psy,
63                                 enum power_supply_property psp,
64                                 union power_supply_propval *val)
65 {
66         struct wacom_data *wdata = container_of(psy,
67                                         struct wacom_data, battery);
68         int power_state = batcap[wdata->battery_capacity];
69         int ret = 0;
70
71         switch (psp) {
72         case POWER_SUPPLY_PROP_PRESENT:
73                 val->intval = 1;
74                 break;
75         case POWER_SUPPLY_PROP_SCOPE:
76                 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
77                 break;
78         case POWER_SUPPLY_PROP_CAPACITY:
79                 /* show 100% battery capacity when charging */
80                 if (power_state == 0)
81                         val->intval = 100;
82                 else
83                         val->intval = power_state;
84                 break;
85         default:
86                 ret = -EINVAL;
87                 break;
88         }
89         return ret;
90 }
91
92 static int wacom_ac_get_property(struct power_supply *psy,
93                                 enum power_supply_property psp,
94                                 union power_supply_propval *val)
95 {
96         struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
97         int power_state = batcap[wdata->battery_capacity];
98         int ret = 0;
99
100         switch (psp) {
101         case POWER_SUPPLY_PROP_PRESENT:
102                 /* fall through */
103         case POWER_SUPPLY_PROP_ONLINE:
104                 if (power_state == 0)
105                         val->intval = 1;
106                 else
107                         val->intval = 0;
108                 break;
109         case POWER_SUPPLY_PROP_SCOPE:
110                 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
111                 break;
112         default:
113                 ret = -EINVAL;
114                 break;
115         }
116         return ret;
117 }
118 #endif
119
120 static void wacom_set_features(struct hid_device *hdev)
121 {
122         int ret;
123         __u8 rep_data[2];
124
125         /*set high speed, tablet mode*/
126         rep_data[0] = 0x03;
127         rep_data[1] = 0x20;
128         ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
129                                 HID_FEATURE_REPORT);
130         return;
131 }
132
133 static void wacom_poke(struct hid_device *hdev, u8 speed)
134 {
135         struct wacom_data *wdata = hid_get_drvdata(hdev);
136         int limit, ret;
137         char rep_data[2];
138
139         rep_data[0] = 0x03 ; rep_data[1] = 0x00;
140         limit = 3;
141         do {
142                 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
143                                 HID_FEATURE_REPORT);
144         } while (ret < 0 && limit-- > 0);
145
146         if (ret >= 0) {
147                 if (speed == 0)
148                         rep_data[0] = 0x05;
149                 else
150                         rep_data[0] = 0x06;
151
152                 rep_data[1] = 0x00;
153                 limit = 3;
154                 do {
155                         ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
156                                         HID_FEATURE_REPORT);
157                 } while (ret < 0 && limit-- > 0);
158
159                 if (ret >= 0) {
160                         wdata->high_speed = speed;
161                         return;
162                 }
163         }
164
165         /*
166          * Note that if the raw queries fail, it's not a hard failure and it
167          * is safe to continue
168          */
169         hid_warn(hdev, "failed to poke device, command %d, err %d\n",
170                  rep_data[0], ret);
171         return;
172 }
173
174 static ssize_t wacom_show_speed(struct device *dev,
175                                 struct device_attribute
176                                 *attr, char *buf)
177 {
178         struct wacom_data *wdata = dev_get_drvdata(dev);
179
180         return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
181 }
182
183 static ssize_t wacom_store_speed(struct device *dev,
184                                 struct device_attribute *attr,
185                                 const char *buf, size_t count)
186 {
187         struct hid_device *hdev = container_of(dev, struct hid_device, dev);
188         int new_speed;
189
190         if (sscanf(buf, "%1d", &new_speed ) != 1)
191                 return -EINVAL;
192
193         if (new_speed == 0 || new_speed == 1) {
194                 wacom_poke(hdev, new_speed);
195                 return strnlen(buf, PAGE_SIZE);
196         } else
197                 return -EINVAL;
198 }
199
200 static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
201                 wacom_show_speed, wacom_store_speed);
202
203 static int wacom_gr_parse_report(struct hid_device *hdev,
204                         struct wacom_data *wdata,
205                         struct input_dev *input, unsigned char *data)
206 {
207         int tool, x, y, rw;
208
209         tool = 0;
210         /* Get X & Y positions */
211         x = le16_to_cpu(*(__le16 *) &data[2]);
212         y = le16_to_cpu(*(__le16 *) &data[4]);
213
214         /* Get current tool identifier */
215         if (data[1] & 0x90) { /* If pen is in the in/active area */
216                 switch ((data[1] >> 5) & 3) {
217                 case 0: /* Pen */
218                         tool = BTN_TOOL_PEN;
219                         break;
220
221                 case 1: /* Rubber */
222                         tool = BTN_TOOL_RUBBER;
223                         break;
224
225                 case 2: /* Mouse with wheel */
226                 case 3: /* Mouse without wheel */
227                         tool = BTN_TOOL_MOUSE;
228                         break;
229                 }
230
231                 /* Reset tool if out of active tablet area */
232                 if (!(data[1] & 0x10))
233                         tool = 0;
234         }
235
236         /* If tool changed, notify input subsystem */
237         if (wdata->tool != tool) {
238                 if (wdata->tool) {
239                         /* Completely reset old tool state */
240                         if (wdata->tool == BTN_TOOL_MOUSE) {
241                                 input_report_key(input, BTN_LEFT, 0);
242                                 input_report_key(input, BTN_RIGHT, 0);
243                                 input_report_key(input, BTN_MIDDLE, 0);
244                                 input_report_abs(input, ABS_DISTANCE,
245                                         input_abs_get_max(input, ABS_DISTANCE));
246                         } else {
247                                 input_report_key(input, BTN_TOUCH, 0);
248                                 input_report_key(input, BTN_STYLUS, 0);
249                                 input_report_key(input, BTN_STYLUS2, 0);
250                                 input_report_abs(input, ABS_PRESSURE, 0);
251                         }
252                         input_report_key(input, wdata->tool, 0);
253                         input_sync(input);
254                 }
255                 wdata->tool = tool;
256                 if (tool)
257                         input_report_key(input, tool, 1);
258         }
259
260         if (tool) {
261                 input_report_abs(input, ABS_X, x);
262                 input_report_abs(input, ABS_Y, y);
263
264                 switch ((data[1] >> 5) & 3) {
265                 case 2: /* Mouse with wheel */
266                         input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
267                         rw = (data[6] & 0x01) ? -1 :
268                                 (data[6] & 0x02) ? 1 : 0;
269                         input_report_rel(input, REL_WHEEL, rw);
270                         /* fall through */
271
272                 case 3: /* Mouse without wheel */
273                         input_report_key(input, BTN_LEFT, data[1] & 0x01);
274                         input_report_key(input, BTN_RIGHT, data[1] & 0x02);
275                         /* Compute distance between mouse and tablet */
276                         rw = 44 - (data[6] >> 2);
277                         if (rw < 0)
278                                 rw = 0;
279                         else if (rw > 31)
280                                 rw = 31;
281                         input_report_abs(input, ABS_DISTANCE, rw);
282                         break;
283
284                 default:
285                         input_report_abs(input, ABS_PRESSURE,
286                                         data[6] | (((__u16) (data[1] & 0x08)) << 5));
287                         input_report_key(input, BTN_TOUCH, data[1] & 0x01);
288                         input_report_key(input, BTN_STYLUS, data[1] & 0x02);
289                         input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
290                         break;
291                 }
292
293                 input_sync(input);
294         }
295
296         /* Report the state of the two buttons at the top of the tablet
297          * as two extra fingerpad keys (buttons 4 & 5). */
298         rw = data[7] & 0x03;
299         if (rw != wdata->butstate) {
300                 wdata->butstate = rw;
301                 input_report_key(input, BTN_0, rw & 0x02);
302                 input_report_key(input, BTN_1, rw & 0x01);
303                 input_report_key(input, BTN_TOOL_FINGER, 0xf0);
304                 input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
305                 input_sync(input);
306         }
307
308 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
309         /* Store current battery capacity */
310         rw = (data[7] >> 2 & 0x07);
311         if (rw != wdata->battery_capacity)
312                 wdata->battery_capacity = rw;
313 #endif
314         return 1;
315 }
316
317 static void wacom_i4_parse_pen_report(struct wacom_data *wdata,
318                         struct input_dev *input, unsigned char *data)
319 {
320         __u16 x, y, pressure;
321         __u32 id;
322
323         switch (data[1]) {
324         case 0x80: /* Out of proximity report */
325                 wdata->tool = 0;
326                 input_report_key(input, BTN_TOUCH, 0);
327                 input_report_abs(input, ABS_PRESSURE, 0);
328                 input_report_key(input, wdata->tool, 0);
329                 input_sync(input);
330                 break;
331         case 0xC2: /* Tool report */
332                 id = ((data[2] << 4) | (data[3] >> 4) |
333                         ((data[7] & 0x0f) << 20) |
334                         ((data[8] & 0xf0) << 12)) & 0xfffff;
335
336                 switch (id) {
337                 case 0x802:
338                         wdata->tool = BTN_TOOL_PEN;
339                         break;
340                 case 0x80A:
341                         wdata->tool = BTN_TOOL_RUBBER;
342                         break;
343                 }
344                 break;
345         default: /* Position/pressure report */
346                 x = data[2] << 9 | data[3] << 1 | ((data[9] & 0x02) >> 1);
347                 y = data[4] << 9 | data[5] << 1 | (data[9] & 0x01);
348                 pressure = (data[6] << 3) | ((data[7] & 0xC0) >> 5)
349                         | (data[1] & 0x01);
350
351                 input_report_key(input, BTN_TOUCH, pressure > 1);
352
353                 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
354                 input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
355                 input_report_key(input, wdata->tool, 1);
356                 input_report_abs(input, ABS_X, x);
357                 input_report_abs(input, ABS_Y, y);
358                 input_report_abs(input, ABS_PRESSURE, pressure);
359                 input_sync(input);
360                 break;
361         }
362
363         return;
364 }
365
366 static void wacom_i4_parse_report(struct hid_device *hdev,
367                         struct wacom_data *wdata,
368                         struct input_dev *input, unsigned char *data)
369 {
370         switch (data[0]) {
371         case 0x00: /* Empty report */
372                 break;
373         case 0x02: /* Pen report */
374                 wacom_i4_parse_pen_report(wdata, input, data);
375                 break;
376         case 0x03: /* Features Report */
377                 wdata->features = data[2];
378                 break;
379         case 0x0C: /* Button report */
380                 break;
381         default:
382                 hid_err(hdev, "Unknown report: %d,%d\n", data[0], data[1]);
383                 break;
384         }
385 }
386
387 static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
388                 u8 *raw_data, int size)
389 {
390         struct wacom_data *wdata = hid_get_drvdata(hdev);
391         struct hid_input *hidinput;
392         struct input_dev *input;
393         unsigned char *data = (unsigned char *) raw_data;
394         int i;
395
396         if (!(hdev->claimed & HID_CLAIMED_INPUT))
397                 return 0;
398
399         hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
400         input = hidinput->input;
401
402         /* Check if this is a tablet report */
403         if (data[0] != 0x03)
404                 return 0;
405
406         switch (hdev->product) {
407         case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
408                 return wacom_gr_parse_report(hdev, wdata, input, data);
409                 break;
410         case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
411                 i = 1;
412
413                 switch (data[0]) {
414                 case 0x04:
415                         wacom_i4_parse_report(hdev, wdata, input, data + i);
416                         i += 10;
417                         /* fall through */
418                 case 0x03:
419                         wacom_i4_parse_report(hdev, wdata, input, data + i);
420                         i += 10;
421                         wacom_i4_parse_report(hdev, wdata, input, data + i);
422                         break;
423                 default:
424                         hid_err(hdev, "Unknown report: %d,%d size:%d\n",
425                                         data[0], data[1], size);
426                         return 0;
427                 }
428         }
429         return 1;
430 }
431
432 static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
433         struct hid_field *field, struct hid_usage *usage, unsigned long **bit,
434                                                                 int *max)
435 {
436         struct input_dev *input = hi->input;
437
438         __set_bit(INPUT_PROP_POINTER, input->propbit);
439
440         /* Basics */
441         input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
442
443         __set_bit(REL_WHEEL, input->relbit);
444
445         __set_bit(BTN_TOOL_PEN, input->keybit);
446         __set_bit(BTN_TOUCH, input->keybit);
447         __set_bit(BTN_STYLUS, input->keybit);
448         __set_bit(BTN_STYLUS2, input->keybit);
449         __set_bit(BTN_LEFT, input->keybit);
450         __set_bit(BTN_RIGHT, input->keybit);
451         __set_bit(BTN_MIDDLE, input->keybit);
452
453         /* Pad */
454         input->evbit[0] |= BIT(EV_MSC);
455
456         __set_bit(MSC_SERIAL, input->mscbit);
457
458         __set_bit(BTN_0, input->keybit);
459         __set_bit(BTN_1, input->keybit);
460         __set_bit(BTN_TOOL_FINGER, input->keybit);
461
462         /* Distance, rubber and mouse */
463         __set_bit(BTN_TOOL_RUBBER, input->keybit);
464         __set_bit(BTN_TOOL_MOUSE, input->keybit);
465
466         switch (hdev->product) {
467         case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
468                 input_set_abs_params(input, ABS_X, 0, 16704, 4, 0);
469                 input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0);
470                 input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0);
471                 input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
472                 break;
473         case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
474                 input_set_abs_params(input, ABS_X, 0, 40640, 4, 0);
475                 input_set_abs_params(input, ABS_Y, 0, 25400, 4, 0);
476                 input_set_abs_params(input, ABS_PRESSURE, 0, 2047, 0, 0);
477                 break;
478         }
479
480         return 0;
481 }
482
483 static int wacom_probe(struct hid_device *hdev,
484                 const struct hid_device_id *id)
485 {
486         struct wacom_data *wdata;
487         int ret;
488
489         wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
490         if (wdata == NULL) {
491                 hid_err(hdev, "can't alloc wacom descriptor\n");
492                 return -ENOMEM;
493         }
494
495         hid_set_drvdata(hdev, wdata);
496
497         /* Parse the HID report now */
498         ret = hid_parse(hdev);
499         if (ret) {
500                 hid_err(hdev, "parse failed\n");
501                 goto err_free;
502         }
503
504         ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
505         if (ret) {
506                 hid_err(hdev, "hw start failed\n");
507                 goto err_free;
508         }
509
510         ret = device_create_file(&hdev->dev, &dev_attr_speed);
511         if (ret)
512                 hid_warn(hdev,
513                          "can't create sysfs speed attribute err: %d\n", ret);
514
515         switch (hdev->product) {
516         case USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH:
517                 /* Set Wacom mode 2 with high reporting speed */
518                 wacom_poke(hdev, 1);
519                 break;
520         case USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH:
521                 wdata->features = 0;
522                 wacom_set_features(hdev);
523                 break;
524         }
525
526 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
527         wdata->battery.properties = wacom_battery_props;
528         wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
529         wdata->battery.get_property = wacom_battery_get_property;
530         wdata->battery.name = "wacom_battery";
531         wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
532         wdata->battery.use_for_apm = 0;
533
534
535         ret = power_supply_register(&hdev->dev, &wdata->battery);
536         if (ret) {
537                 hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
538                          ret);
539                 goto err_battery;
540         }
541
542         power_supply_powers(&wdata->battery, &hdev->dev);
543
544         wdata->ac.properties = wacom_ac_props;
545         wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
546         wdata->ac.get_property = wacom_ac_get_property;
547         wdata->ac.name = "wacom_ac";
548         wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
549         wdata->ac.use_for_apm = 0;
550
551         ret = power_supply_register(&hdev->dev, &wdata->ac);
552         if (ret) {
553                 hid_warn(hdev,
554                          "can't create ac battery attribute, err: %d\n", ret);
555                 goto err_ac;
556         }
557
558         power_supply_powers(&wdata->ac, &hdev->dev);
559 #endif
560         return 0;
561
562 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
563 err_ac:
564         power_supply_unregister(&wdata->battery);
565 err_battery:
566         device_remove_file(&hdev->dev, &dev_attr_speed);
567         hid_hw_stop(hdev);
568 #endif
569 err_free:
570         kfree(wdata);
571         return ret;
572 }
573
574 static void wacom_remove(struct hid_device *hdev)
575 {
576 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
577         struct wacom_data *wdata = hid_get_drvdata(hdev);
578 #endif
579         device_remove_file(&hdev->dev, &dev_attr_speed);
580         hid_hw_stop(hdev);
581
582 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
583         power_supply_unregister(&wdata->battery);
584         power_supply_unregister(&wdata->ac);
585 #endif
586         kfree(hid_get_drvdata(hdev));
587 }
588
589 static const struct hid_device_id wacom_devices[] = {
590         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
591         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH) },
592
593         { }
594 };
595 MODULE_DEVICE_TABLE(hid, wacom_devices);
596
597 static struct hid_driver wacom_driver = {
598         .name = "wacom",
599         .id_table = wacom_devices,
600         .probe = wacom_probe,
601         .remove = wacom_remove,
602         .raw_event = wacom_raw_event,
603         .input_mapped = wacom_input_mapped,
604 };
605
606 static int __init wacom_init(void)
607 {
608         int ret;
609
610         ret = hid_register_driver(&wacom_driver);
611         if (ret)
612                 pr_err("can't register wacom driver\n");
613         return ret;
614 }
615
616 static void __exit wacom_exit(void)
617 {
618         hid_unregister_driver(&wacom_driver);
619 }
620
621 module_init(wacom_init);
622 module_exit(wacom_exit);
623 MODULE_LICENSE("GPL");
624