Merge git://git.infradead.org/users/cbou/battery-urgent
[platform/adaptation/renesas_rcar/renesas_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  */
13
14 /*
15  * This program is free software; you can redistribute it and/or modify it
16  * under the terms of the GNU General Public License as published by the Free
17  * Software Foundation; either version 2 of the License, or (at your option)
18  * any later version.
19  */
20
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23 #include <linux/device.h>
24 #include <linux/hid.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
27 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
28 #include <linux/power_supply.h>
29 #endif
30
31 #include "hid-ids.h"
32
33 struct wacom_data {
34         __u16 tool;
35         unsigned char butstate;
36         unsigned char high_speed;
37 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
38         int battery_capacity;
39         struct power_supply battery;
40         struct power_supply ac;
41 #endif
42 };
43
44 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
45 /*percent of battery capacity, 0 means AC online*/
46 static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
47
48 static enum power_supply_property wacom_battery_props[] = {
49         POWER_SUPPLY_PROP_PRESENT,
50         POWER_SUPPLY_PROP_CAPACITY,
51         POWER_SUPPLY_PROP_SCOPE,
52 };
53
54 static enum power_supply_property wacom_ac_props[] = {
55         POWER_SUPPLY_PROP_PRESENT,
56         POWER_SUPPLY_PROP_ONLINE,
57         POWER_SUPPLY_PROP_SCOPE,
58 };
59
60 static int wacom_battery_get_property(struct power_supply *psy,
61                                 enum power_supply_property psp,
62                                 union power_supply_propval *val)
63 {
64         struct wacom_data *wdata = container_of(psy,
65                                         struct wacom_data, battery);
66         int power_state = batcap[wdata->battery_capacity];
67         int ret = 0;
68
69         switch (psp) {
70         case POWER_SUPPLY_PROP_PRESENT:
71                 val->intval = 1;
72                 break;
73         case POWER_SUPPLY_PROP_SCOPE:
74                 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
75                 break;
76         case POWER_SUPPLY_PROP_CAPACITY:
77                 /* show 100% battery capacity when charging */
78                 if (power_state == 0)
79                         val->intval = 100;
80                 else
81                         val->intval = power_state;
82                 break;
83         default:
84                 ret = -EINVAL;
85                 break;
86         }
87         return ret;
88 }
89
90 static int wacom_ac_get_property(struct power_supply *psy,
91                                 enum power_supply_property psp,
92                                 union power_supply_propval *val)
93 {
94         struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
95         int power_state = batcap[wdata->battery_capacity];
96         int ret = 0;
97
98         switch (psp) {
99         case POWER_SUPPLY_PROP_PRESENT:
100                 /* fall through */
101         case POWER_SUPPLY_PROP_ONLINE:
102                 if (power_state == 0)
103                         val->intval = 1;
104                 else
105                         val->intval = 0;
106                 break;
107         case POWER_SUPPLY_PROP_SCOPE:
108                 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
109                 break;
110         default:
111                 ret = -EINVAL;
112                 break;
113         }
114         return ret;
115 }
116 #endif
117
118 static void wacom_poke(struct hid_device *hdev, u8 speed)
119 {
120         struct wacom_data *wdata = hid_get_drvdata(hdev);
121         int limit, ret;
122         char rep_data[2];
123
124         rep_data[0] = 0x03 ; rep_data[1] = 0x00;
125         limit = 3;
126         do {
127                 ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
128                                 HID_FEATURE_REPORT);
129         } while (ret < 0 && limit-- > 0);
130
131         if (ret >= 0) {
132                 if (speed == 0)
133                         rep_data[0] = 0x05;
134                 else
135                         rep_data[0] = 0x06;
136
137                 rep_data[1] = 0x00;
138                 limit = 3;
139                 do {
140                         ret = hdev->hid_output_raw_report(hdev, rep_data, 2,
141                                         HID_FEATURE_REPORT);
142                 } while (ret < 0 && limit-- > 0);
143
144                 if (ret >= 0) {
145                         wdata->high_speed = speed;
146                         return;
147                 }
148         }
149
150         /*
151          * Note that if the raw queries fail, it's not a hard failure and it
152          * is safe to continue
153          */
154         hid_warn(hdev, "failed to poke device, command %d, err %d\n",
155                  rep_data[0], ret);
156         return;
157 }
158
159 static ssize_t wacom_show_speed(struct device *dev,
160                                 struct device_attribute
161                                 *attr, char *buf)
162 {
163         struct wacom_data *wdata = dev_get_drvdata(dev);
164
165         return snprintf(buf, PAGE_SIZE, "%i\n", wdata->high_speed);
166 }
167
168 static ssize_t wacom_store_speed(struct device *dev,
169                                 struct device_attribute *attr,
170                                 const char *buf, size_t count)
171 {
172         struct hid_device *hdev = container_of(dev, struct hid_device, dev);
173         int new_speed;
174
175         if (sscanf(buf, "%1d", &new_speed ) != 1)
176                 return -EINVAL;
177
178         if (new_speed == 0 || new_speed == 1) {
179                 wacom_poke(hdev, new_speed);
180                 return strnlen(buf, PAGE_SIZE);
181         } else
182                 return -EINVAL;
183 }
184
185 static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP,
186                 wacom_show_speed, wacom_store_speed);
187
188 static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
189                 u8 *raw_data, int size)
190 {
191         struct wacom_data *wdata = hid_get_drvdata(hdev);
192         struct hid_input *hidinput;
193         struct input_dev *input;
194         unsigned char *data = (unsigned char *) raw_data;
195         int tool, x, y, rw;
196
197         if (!(hdev->claimed & HID_CLAIMED_INPUT))
198                 return 0;
199
200         tool = 0;
201         hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
202         input = hidinput->input;
203
204         /* Check if this is a tablet report */
205         if (data[0] != 0x03)
206                 return 0;
207
208         /* Get X & Y positions */
209         x = le16_to_cpu(*(__le16 *) &data[2]);
210         y = le16_to_cpu(*(__le16 *) &data[4]);
211
212         /* Get current tool identifier */
213         if (data[1] & 0x90) { /* If pen is in the in/active area */
214                 switch ((data[1] >> 5) & 3) {
215                 case 0: /* Pen */
216                         tool = BTN_TOOL_PEN;
217                         break;
218
219                 case 1: /* Rubber */
220                         tool = BTN_TOOL_RUBBER;
221                         break;
222
223                 case 2: /* Mouse with wheel */
224                 case 3: /* Mouse without wheel */
225                         tool = BTN_TOOL_MOUSE;
226                         break;
227                 }
228
229                 /* Reset tool if out of active tablet area */
230                 if (!(data[1] & 0x10))
231                         tool = 0;
232         }
233
234         /* If tool changed, notify input subsystem */
235         if (wdata->tool != tool) {
236                 if (wdata->tool) {
237                         /* Completely reset old tool state */
238                         if (wdata->tool == BTN_TOOL_MOUSE) {
239                                 input_report_key(input, BTN_LEFT, 0);
240                                 input_report_key(input, BTN_RIGHT, 0);
241                                 input_report_key(input, BTN_MIDDLE, 0);
242                                 input_report_abs(input, ABS_DISTANCE,
243                                         input_abs_get_max(input, ABS_DISTANCE));
244                         } else {
245                                 input_report_key(input, BTN_TOUCH, 0);
246                                 input_report_key(input, BTN_STYLUS, 0);
247                                 input_report_key(input, BTN_STYLUS2, 0);
248                                 input_report_abs(input, ABS_PRESSURE, 0);
249                         }
250                         input_report_key(input, wdata->tool, 0);
251                         input_sync(input);
252                 }
253                 wdata->tool = tool;
254                 if (tool)
255                         input_report_key(input, tool, 1);
256         }
257
258         if (tool) {
259                 input_report_abs(input, ABS_X, x);
260                 input_report_abs(input, ABS_Y, y);
261
262                 switch ((data[1] >> 5) & 3) {
263                 case 2: /* Mouse with wheel */
264                         input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
265                         rw = (data[6] & 0x01) ? -1 :
266                                 (data[6] & 0x02) ? 1 : 0;
267                         input_report_rel(input, REL_WHEEL, rw);
268                         /* fall through */
269
270                 case 3: /* Mouse without wheel */
271                         input_report_key(input, BTN_LEFT, data[1] & 0x01);
272                         input_report_key(input, BTN_RIGHT, data[1] & 0x02);
273                         /* Compute distance between mouse and tablet */
274                         rw = 44 - (data[6] >> 2);
275                         if (rw < 0)
276                                 rw = 0;
277                         else if (rw > 31)
278                                 rw = 31;
279                         input_report_abs(input, ABS_DISTANCE, rw);
280                         break;
281
282                 default:
283                         input_report_abs(input, ABS_PRESSURE,
284                                         data[6] | (((__u16) (data[1] & 0x08)) << 5));
285                         input_report_key(input, BTN_TOUCH, data[1] & 0x01);
286                         input_report_key(input, BTN_STYLUS, data[1] & 0x02);
287                         input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
288                         break;
289                 }
290
291                 input_sync(input);
292         }
293
294         /* Report the state of the two buttons at the top of the tablet
295          * as two extra fingerpad keys (buttons 4 & 5). */
296         rw = data[7] & 0x03;
297         if (rw != wdata->butstate) {
298                 wdata->butstate = rw;
299                 input_report_key(input, BTN_0, rw & 0x02);
300                 input_report_key(input, BTN_1, rw & 0x01);
301                 input_report_key(input, BTN_TOOL_FINGER, 0xf0);
302                 input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
303                 input_sync(input);
304         }
305
306 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
307         /* Store current battery capacity */
308         rw = (data[7] >> 2 & 0x07);
309         if (rw != wdata->battery_capacity)
310                 wdata->battery_capacity = rw;
311 #endif
312         return 1;
313 }
314
315 static int wacom_input_mapped(struct hid_device *hdev, struct hid_input *hi,
316         struct hid_field *field, struct hid_usage *usage, unsigned long **bit,
317                                                                 int *max)
318 {
319         struct input_dev *input = hi->input;
320
321         __set_bit(INPUT_PROP_POINTER, input->propbit);
322
323         /* Basics */
324         input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
325
326         __set_bit(REL_WHEEL, input->relbit);
327
328         __set_bit(BTN_TOOL_PEN, input->keybit);
329         __set_bit(BTN_TOUCH, input->keybit);
330         __set_bit(BTN_STYLUS, input->keybit);
331         __set_bit(BTN_STYLUS2, input->keybit);
332         __set_bit(BTN_LEFT, input->keybit);
333         __set_bit(BTN_RIGHT, input->keybit);
334         __set_bit(BTN_MIDDLE, input->keybit);
335
336         /* Pad */
337         input->evbit[0] |= BIT(EV_MSC);
338
339         __set_bit(MSC_SERIAL, input->mscbit);
340
341         __set_bit(BTN_0, input->keybit);
342         __set_bit(BTN_1, input->keybit);
343         __set_bit(BTN_TOOL_FINGER, input->keybit);
344
345         /* Distance, rubber and mouse */
346         __set_bit(BTN_TOOL_RUBBER, input->keybit);
347         __set_bit(BTN_TOOL_MOUSE, input->keybit);
348
349         input_set_abs_params(input, ABS_X, 0, 16704, 4, 0);
350         input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0);
351         input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0);
352         input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
353
354         return 0;
355 }
356
357 static int wacom_probe(struct hid_device *hdev,
358                 const struct hid_device_id *id)
359 {
360         struct wacom_data *wdata;
361         int ret;
362
363         wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
364         if (wdata == NULL) {
365                 hid_err(hdev, "can't alloc wacom descriptor\n");
366                 return -ENOMEM;
367         }
368
369         hid_set_drvdata(hdev, wdata);
370
371         /* Parse the HID report now */
372         ret = hid_parse(hdev);
373         if (ret) {
374                 hid_err(hdev, "parse failed\n");
375                 goto err_free;
376         }
377
378         ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
379         if (ret) {
380                 hid_err(hdev, "hw start failed\n");
381                 goto err_free;
382         }
383
384         ret = device_create_file(&hdev->dev, &dev_attr_speed);
385         if (ret)
386                 hid_warn(hdev,
387                          "can't create sysfs speed attribute err: %d\n", ret);
388
389         /* Set Wacom mode 2 with high reporting speed */
390         wacom_poke(hdev, 1);
391
392 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
393         wdata->battery.properties = wacom_battery_props;
394         wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
395         wdata->battery.get_property = wacom_battery_get_property;
396         wdata->battery.name = "wacom_battery";
397         wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
398         wdata->battery.use_for_apm = 0;
399
400         power_supply_powers(&wdata->battery, &hdev->dev);
401
402         ret = power_supply_register(&hdev->dev, &wdata->battery);
403         if (ret) {
404                 hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
405                          ret);
406                 goto err_battery;
407         }
408
409         wdata->ac.properties = wacom_ac_props;
410         wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
411         wdata->ac.get_property = wacom_ac_get_property;
412         wdata->ac.name = "wacom_ac";
413         wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
414         wdata->ac.use_for_apm = 0;
415
416         power_supply_powers(&wdata->battery, &hdev->dev);
417
418         ret = power_supply_register(&hdev->dev, &wdata->ac);
419         if (ret) {
420                 hid_warn(hdev,
421                          "can't create ac battery attribute, err: %d\n", ret);
422                 goto err_ac;
423         }
424 #endif
425         return 0;
426
427 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
428 err_ac:
429         power_supply_unregister(&wdata->battery);
430 err_battery:
431         device_remove_file(&hdev->dev, &dev_attr_speed);
432         hid_hw_stop(hdev);
433 #endif
434 err_free:
435         kfree(wdata);
436         return ret;
437 }
438
439 static void wacom_remove(struct hid_device *hdev)
440 {
441 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
442         struct wacom_data *wdata = hid_get_drvdata(hdev);
443 #endif
444         device_remove_file(&hdev->dev, &dev_attr_speed);
445         hid_hw_stop(hdev);
446
447 #ifdef CONFIG_HID_WACOM_POWER_SUPPLY
448         power_supply_unregister(&wdata->battery);
449         power_supply_unregister(&wdata->ac);
450 #endif
451         kfree(hid_get_drvdata(hdev));
452 }
453
454 static const struct hid_device_id wacom_devices[] = {
455         { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
456
457         { }
458 };
459 MODULE_DEVICE_TABLE(hid, wacom_devices);
460
461 static struct hid_driver wacom_driver = {
462         .name = "wacom",
463         .id_table = wacom_devices,
464         .probe = wacom_probe,
465         .remove = wacom_remove,
466         .raw_event = wacom_raw_event,
467         .input_mapped = wacom_input_mapped,
468 };
469
470 static int __init wacom_init(void)
471 {
472         int ret;
473
474         ret = hid_register_driver(&wacom_driver);
475         if (ret)
476                 pr_err("can't register wacom driver\n");
477         return ret;
478 }
479
480 static void __exit wacom_exit(void)
481 {
482         hid_unregister_driver(&wacom_driver);
483 }
484
485 module_init(wacom_init);
486 module_exit(wacom_exit);
487 MODULE_LICENSE("GPL");
488