aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig8
-rw-r--r--drivers/hid/hid-wacom.c127
2 files changed, 135 insertions, 0 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 71d4c0703629..8e1b505b5bf2 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -357,6 +357,14 @@ config HID_WACOM
357 ---help--- 357 ---help---
358 Support for Wacom Graphire Bluetooth tablet. 358 Support for Wacom Graphire Bluetooth tablet.
359 359
360config HID_WACOM_POWER_SUPPLY
361 bool "Wacom Bluetooth devices power supply status support"
362 depends on HID_WACOM
363 select POWER_SUPPLY
364 ---help---
365 Say Y here if you want to enable power supply status monitoring for
366 Wacom Bluetooth devices.
367
360config HID_ZEROPLUS 368config HID_ZEROPLUS
361 tristate "Zeroplus based game controller support" if EMBEDDED 369 tristate "Zeroplus based game controller support" if EMBEDDED
362 depends on USB_HID 370 depends on USB_HID
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 8d3b46f5d149..4d2d2a2e1a5f 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -21,14 +21,88 @@
21#include <linux/device.h> 21#include <linux/device.h>
22#include <linux/hid.h> 22#include <linux/hid.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
25#include <linux/power_supply.h>
26#endif
24 27
25#include "hid-ids.h" 28#include "hid-ids.h"
26 29
27struct wacom_data { 30struct wacom_data {
28 __u16 tool; 31 __u16 tool;
29 unsigned char butstate; 32 unsigned char butstate;
33#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
34 int battery_capacity;
35 struct power_supply battery;
36 struct power_supply ac;
37#endif
30}; 38};
31 39
40#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
41/*percent of battery capacity, 0 means AC online*/
42static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 };
43
44static enum power_supply_property wacom_battery_props[] = {
45 POWER_SUPPLY_PROP_PRESENT,
46 POWER_SUPPLY_PROP_CAPACITY
47};
48
49static enum power_supply_property wacom_ac_props[] = {
50 POWER_SUPPLY_PROP_PRESENT,
51 POWER_SUPPLY_PROP_ONLINE
52};
53
54static int wacom_battery_get_property(struct power_supply *psy,
55 enum power_supply_property psp,
56 union power_supply_propval *val)
57{
58 struct wacom_data *wdata = container_of(psy,
59 struct wacom_data, battery);
60 int power_state = batcap[wdata->battery_capacity];
61 int ret = 0;
62
63 switch (psp) {
64 case POWER_SUPPLY_PROP_PRESENT:
65 val->intval = 1;
66 break;
67 case POWER_SUPPLY_PROP_CAPACITY:
68 /* show 100% battery capacity when charging */
69 if (power_state == 0)
70 val->intval = 100;
71 else
72 val->intval = power_state;
73 break;
74 default:
75 ret = -EINVAL;
76 break;
77 }
78 return ret;
79}
80
81static int wacom_ac_get_property(struct power_supply *psy,
82 enum power_supply_property psp,
83 union power_supply_propval *val)
84{
85 struct wacom_data *wdata = container_of(psy, struct wacom_data, ac);
86 int power_state = batcap[wdata->battery_capacity];
87 int ret = 0;
88
89 switch (psp) {
90 case POWER_SUPPLY_PROP_PRESENT:
91 /* fall through */
92 case POWER_SUPPLY_PROP_ONLINE:
93 if (power_state == 0)
94 val->intval = 1;
95 else
96 val->intval = 0;
97 break;
98 default:
99 ret = -EINVAL;
100 break;
101 }
102 return ret;
103}
104#endif
105
32static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, 106static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
33 u8 *raw_data, int size) 107 u8 *raw_data, int size)
34{ 108{
@@ -147,6 +221,12 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
147 input_sync(input); 221 input_sync(input);
148 } 222 }
149 223
224#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
225 /* Store current battery capacity */
226 rw = (data[7] >> 2 & 0x07);
227 if (rw != wdata->battery_capacity)
228 wdata->battery_capacity = rw;
229#endif
150 return 1; 230 return 1;
151} 231}
152 232
@@ -206,6 +286,45 @@ static int wacom_probe(struct hid_device *hdev,
206 if (ret < 0) 286 if (ret < 0)
207 dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret); 287 dev_warn(&hdev->dev, "failed to poke device #2, %d\n", ret);
208 288
289#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
290 wdata->battery.properties = wacom_battery_props;
291 wdata->battery.num_properties = ARRAY_SIZE(wacom_battery_props);
292 wdata->battery.get_property = wacom_battery_get_property;
293 wdata->battery.name = "wacom_battery";
294 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
295 wdata->battery.use_for_apm = 0;
296
297 ret = power_supply_register(&hdev->dev, &wdata->battery);
298 if (ret) {
299 dev_warn(&hdev->dev,
300 "can't create sysfs battery attribute, err: %d\n", ret);
301 /*
302 * battery attribute is not critical for the tablet, but if it
303 * failed then there is no need to create ac attribute
304 */
305 goto move_on;
306 }
307
308 wdata->ac.properties = wacom_ac_props;
309 wdata->ac.num_properties = ARRAY_SIZE(wacom_ac_props);
310 wdata->ac.get_property = wacom_ac_get_property;
311 wdata->ac.name = "wacom_ac";
312 wdata->ac.type = POWER_SUPPLY_TYPE_MAINS;
313 wdata->ac.use_for_apm = 0;
314
315 ret = power_supply_register(&hdev->dev, &wdata->ac);
316 if (ret) {
317 dev_warn(&hdev->dev,
318 "can't create ac battery attribute, err: %d\n", ret);
319 /*
320 * ac attribute is not critical for the tablet, but if it
321 * failed then we don't want to battery attribute to exist
322 */
323 power_supply_unregister(&wdata->battery);
324 }
325
326move_on:
327#endif
209 hidinput = list_entry(hdev->inputs.next, struct hid_input, list); 328 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
210 input = hidinput->input; 329 input = hidinput->input;
211 330
@@ -250,7 +369,15 @@ err_free:
250 369
251static void wacom_remove(struct hid_device *hdev) 370static void wacom_remove(struct hid_device *hdev)
252{ 371{
372#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
373 struct wacom_data *wdata = hid_get_drvdata(hdev);
374#endif
253 hid_hw_stop(hdev); 375 hid_hw_stop(hdev);
376
377#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
378 power_supply_unregister(&wdata->battery);
379 power_supply_unregister(&wdata->ac);
380#endif
254 kfree(hid_get_drvdata(hdev)); 381 kfree(hid_get_drvdata(hdev));
255} 382}
256 383