diff options
| author | Przemo Firszt <przemo@firszt.eu> | 2010-03-15 15:16:23 -0400 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2010-03-16 06:55:43 -0400 |
| commit | 59d2334ac9f4255f5f8f3e4e1bf41653e0bba99e (patch) | |
| tree | ea12f472f551f7d0875a0dd61ae336fd91157497 | |
| parent | 4da361b69102cdffe73006771eae7504d2cb8736 (diff) | |
HID: expose wacom pen tablet battery through power_supply class
This patch exposes wacom pen tablet battery capacity and ac state thru
power_supply class is sysfs.
Signed-off-by: Przemo Firszt <przemo@firszt.eu>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
| -rw-r--r-- | drivers/hid/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/hid/hid-wacom.c | 127 |
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 | ||
| 360 | config 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 | |||
| 360 | config HID_ZEROPLUS | 368 | config 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 | ||
| 27 | struct wacom_data { | 30 | struct 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*/ | ||
| 42 | static unsigned short batcap[8] = { 1, 15, 25, 35, 50, 70, 100, 0 }; | ||
| 43 | |||
| 44 | static enum power_supply_property wacom_battery_props[] = { | ||
| 45 | POWER_SUPPLY_PROP_PRESENT, | ||
| 46 | POWER_SUPPLY_PROP_CAPACITY | ||
| 47 | }; | ||
| 48 | |||
| 49 | static enum power_supply_property wacom_ac_props[] = { | ||
| 50 | POWER_SUPPLY_PROP_PRESENT, | ||
| 51 | POWER_SUPPLY_PROP_ONLINE | ||
| 52 | }; | ||
| 53 | |||
| 54 | static 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 | |||
| 81 | static 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 | |||
| 32 | static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, | 106 | static 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 | |||
| 326 | move_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 | ||
| 251 | static void wacom_remove(struct hid_device *hdev) | 370 | static 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 | ||
