aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/Kconfig5
-rw-r--r--drivers/hid/hid-input.c110
-rw-r--r--include/linux/hid.h16
3 files changed, 131 insertions, 0 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 22a4a051f221..3a97f1fab243 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -31,6 +31,11 @@ config HID
31 31
32 If unsure, say Y. 32 If unsure, say Y.
33 33
34config HID_BATTERY_STRENGTH
35 bool
36 depends on POWER_SUPPLY
37 default y
38
34config HIDRAW 39config HIDRAW
35 bool "/dev/hidraw raw HID device support" 40 bool "/dev/hidraw raw HID device support"
36 depends on HID 41 depends on HID
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 6e3252651ce3..2d96b782b203 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -271,6 +271,97 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
271 return logical_extents / physical_extents; 271 return logical_extents / physical_extents;
272} 272}
273 273
274#ifdef CONFIG_HID_BATTERY_STRENGTH
275static enum power_supply_property hidinput_battery_props[] = {
276 POWER_SUPPLY_PROP_PRESENT,
277 POWER_SUPPLY_PROP_ONLINE,
278 POWER_SUPPLY_PROP_CAPACITY,
279 POWER_SUPPLY_PROP_MODEL_NAME,
280};
281
282static int hidinput_get_battery_property(struct power_supply *psy,
283 enum power_supply_property prop,
284 union power_supply_propval *val)
285{
286 struct hid_device *dev = container_of(psy, struct hid_device, battery);
287 int ret = 0;
288
289 switch (prop) {
290 case POWER_SUPPLY_PROP_PRESENT:
291 case POWER_SUPPLY_PROP_ONLINE:
292 val->intval = 1;
293 break;
294
295 case POWER_SUPPLY_PROP_CAPACITY:
296 if (dev->battery_min < dev->battery_max &&
297 dev->battery_val >= dev->battery_min &&
298 dev->battery_val <= dev->battery_max)
299 val->intval = (100 * (dev->battery_val - dev->battery_min)) /
300 (dev->battery_max - dev->battery_min);
301 else
302 ret = -EINVAL;
303 break;
304
305 case POWER_SUPPLY_PROP_MODEL_NAME:
306 val->strval = dev->name;
307 break;
308
309 default:
310 ret = -EINVAL;
311 break;
312 }
313
314 return ret;
315}
316
317static void hidinput_setup_battery(struct hid_device *dev, s32 min, s32 max)
318{
319 struct power_supply *battery = &dev->battery;
320 int ret;
321
322 if (battery->name != NULL)
323 return; /* already initialized? */
324
325 battery->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq);
326 if (battery->name == NULL)
327 return;
328
329 battery->type = POWER_SUPPLY_TYPE_BATTERY;
330 battery->properties = hidinput_battery_props;
331 battery->num_properties = ARRAY_SIZE(hidinput_battery_props);
332 battery->use_for_apm = 0;
333 battery->get_property = hidinput_get_battery_property;
334
335 dev->battery_min = min;
336 dev->battery_max = max;
337
338 ret = power_supply_register(&dev->dev, battery);
339 if (ret != 0) {
340 hid_warn(dev, "can't register power supply: %d\n", ret);
341 kfree(battery->name);
342 battery->name = NULL;
343 }
344}
345
346static void hidinput_cleanup_battery(struct hid_device *dev)
347{
348 if (!dev->battery.name)
349 return;
350
351 power_supply_unregister(&dev->battery);
352 kfree(dev->battery.name);
353 dev->battery.name = NULL;
354}
355#else /* !CONFIG_HID_BATTERY_STRENGTH */
356static void hidinput_setup_battery(struct hid_device *dev, s32 min, s32 max)
357{
358}
359
360static void hidinput_cleanup_battery(struct hid_device *dev)
361{
362}
363#endif /* CONFIG_HID_BATTERY_STRENGTH */
364
274static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, 365static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
275 struct hid_usage *usage) 366 struct hid_usage *usage)
276{ 367{
@@ -629,6 +720,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
629 } 720 }
630 break; 721 break;
631 722
723 case HID_UP_GENDEVCTRLS:
724 if ((usage->hid & HID_USAGE) == 0x20) { /* Battery Strength */
725 hidinput_setup_battery(device,
726 field->logical_minimum,
727 field->logical_maximum);
728 goto ignore;
729 } else
730 goto unknown;
731 break;
732
632 case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ 733 case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */
633 set_bit(EV_REP, input->evbit); 734 set_bit(EV_REP, input->evbit);
634 switch (usage->hid & HID_USAGE) { 735 switch (usage->hid & HID_USAGE) {
@@ -760,6 +861,13 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
760 861
761 input = field->hidinput->input; 862 input = field->hidinput->input;
762 863
864 if (usage->hid == HID_DC_BATTERYSTRENGTH) {
865 hid->battery_val = value;
866 hid_dbg(hid, "battery value is %d (range %d-%d)\n",
867 value, hid->battery_min, hid->battery_max);
868 return;
869 }
870
763 if (!usage->type) 871 if (!usage->type)
764 return; 872 return;
765 873
@@ -1016,6 +1124,8 @@ void hidinput_disconnect(struct hid_device *hid)
1016{ 1124{
1017 struct hid_input *hidinput, *next; 1125 struct hid_input *hidinput, *next;
1018 1126
1127 hidinput_cleanup_battery(hid);
1128
1019 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { 1129 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
1020 list_del(&hidinput->list); 1130 list_del(&hidinput->list);
1021 input_unregister_device(hidinput->input); 1131 input_unregister_device(hidinput->input);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index deed5f9a1e1c..7f344c3da767 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -72,6 +72,7 @@
72#include <linux/workqueue.h> 72#include <linux/workqueue.h>
73#include <linux/input.h> 73#include <linux/input.h>
74#include <linux/semaphore.h> 74#include <linux/semaphore.h>
75#include <linux/power_supply.h>
75 76
76/* 77/*
77 * We parse each description item into this structure. Short items data 78 * We parse each description item into this structure. Short items data
@@ -190,6 +191,7 @@ struct hid_item {
190#define HID_UP_UNDEFINED 0x00000000 191#define HID_UP_UNDEFINED 0x00000000
191#define HID_UP_GENDESK 0x00010000 192#define HID_UP_GENDESK 0x00010000
192#define HID_UP_SIMULATION 0x00020000 193#define HID_UP_SIMULATION 0x00020000
194#define HID_UP_GENDEVCTRLS 0x00060000
193#define HID_UP_KEYBOARD 0x00070000 195#define HID_UP_KEYBOARD 0x00070000
194#define HID_UP_LED 0x00080000 196#define HID_UP_LED 0x00080000
195#define HID_UP_BUTTON 0x00090000 197#define HID_UP_BUTTON 0x00090000
@@ -239,6 +241,8 @@ struct hid_item {
239#define HID_GD_RIGHT 0x00010092 241#define HID_GD_RIGHT 0x00010092
240#define HID_GD_LEFT 0x00010093 242#define HID_GD_LEFT 0x00010093
241 243
244#define HID_DC_BATTERYSTRENGTH 0x00060020
245
242#define HID_DG_DIGITIZER 0x000d0001 246#define HID_DG_DIGITIZER 0x000d0001
243#define HID_DG_PEN 0x000d0002 247#define HID_DG_PEN 0x000d0002
244#define HID_DG_LIGHTPEN 0x000d0003 248#define HID_DG_LIGHTPEN 0x000d0003
@@ -482,6 +486,18 @@ struct hid_device { /* device report descriptor */
482 struct hid_driver *driver; 486 struct hid_driver *driver;
483 struct hid_ll_driver *ll_driver; 487 struct hid_ll_driver *ll_driver;
484 488
489#ifdef CONFIG_HID_BATTERY_STRENGTH
490 /*
491 * Power supply information for HID devices which report
492 * battery strength. power_supply is registered iff
493 * battery.name is non-NULL.
494 */
495 struct power_supply battery;
496 __s32 battery_min;
497 __s32 battery_max;
498 __s32 battery_val;
499#endif
500
485 unsigned int status; /* see STAT flags above */ 501 unsigned int status; /* see STAT flags above */
486 unsigned claimed; /* Claimed by hidinput, hiddev? */ 502 unsigned claimed; /* Claimed by hidinput, hiddev? */
487 unsigned quirks; /* Various quirks the device can pull on us */ 503 unsigned quirks; /* Various quirks the device can pull on us */