diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2011-12-02 14:12:36 -0500 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy@goop.org> | 2012-01-08 02:30:37 -0500 |
commit | bbc21cfd55858d7c3e55bfaa91fa934b0b13ad4d (patch) | |
tree | 8b0495e337bd64c8677c218d01bb3cc2e6211663 | |
parent | ef5251993c3597a88b893fe22ee830092dff35f9 (diff) |
hid-input/battery: add quirks for battery
Some devices always report percentage, despite having 0/255 as their
min/max, so add a quirk for them.
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 41 | ||||
-rw-r--r-- | include/linux/hid.h | 2 |
3 files changed, 40 insertions, 5 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c0ef2b49a00c..aa4a30b7c6af 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1157,7 +1157,7 @@ static bool hid_match_one_id(struct hid_device *hdev, | |||
1157 | (id->product == HID_ANY_ID || id->product == hdev->product); | 1157 | (id->product == HID_ANY_ID || id->product == hdev->product); |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | static const struct hid_device_id *hid_match_id(struct hid_device *hdev, | 1160 | const struct hid_device_id *hid_match_id(struct hid_device *hdev, |
1161 | const struct hid_device_id *id) | 1161 | const struct hid_device_id *id) |
1162 | { | 1162 | { |
1163 | for (; id->bus; id++) | 1163 | for (; id->bus; id++) |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index b108ce71583f..69dec476883a 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
33 | #include <linux/hid-debug.h> | 33 | #include <linux/hid-debug.h> |
34 | 34 | ||
35 | #include "hid-ids.h" | ||
36 | |||
35 | #define unk KEY_UNKNOWN | 37 | #define unk KEY_UNKNOWN |
36 | 38 | ||
37 | static const unsigned char hid_keyboard[256] = { | 39 | static const unsigned char hid_keyboard[256] = { |
@@ -280,6 +282,28 @@ static enum power_supply_property hidinput_battery_props[] = { | |||
280 | POWER_SUPPLY_PROP_STATUS | 282 | POWER_SUPPLY_PROP_STATUS |
281 | }; | 283 | }; |
282 | 284 | ||
285 | #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ | ||
286 | |||
287 | static const struct hid_device_id hid_battery_quirks[] = { | ||
288 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), | ||
289 | HID_BATTERY_QUIRK_PERCENT }, | ||
290 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD), | ||
291 | HID_BATTERY_QUIRK_PERCENT }, | ||
292 | {} | ||
293 | }; | ||
294 | |||
295 | static unsigned find_battery_quirk(struct hid_device *hdev) | ||
296 | { | ||
297 | unsigned quirks = 0; | ||
298 | const struct hid_device_id *match; | ||
299 | |||
300 | match = hid_match_id(hdev, hid_battery_quirks); | ||
301 | if (match != NULL) | ||
302 | quirks = match->driver_data; | ||
303 | |||
304 | return quirks; | ||
305 | } | ||
306 | |||
283 | static int hidinput_get_battery_property(struct power_supply *psy, | 307 | static int hidinput_get_battery_property(struct power_supply *psy, |
284 | enum power_supply_property prop, | 308 | enum power_supply_property prop, |
285 | union power_supply_propval *val) | 309 | union power_supply_propval *val) |
@@ -304,10 +328,11 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
304 | break; | 328 | break; |
305 | } | 329 | } |
306 | 330 | ||
307 | /* store the returned value */ | 331 | if (dev->battery_min < dev->battery_max && |
308 | /* I'm not calculating this using the logical_minimum and maximum */ | 332 | buf[1] >= dev->battery_min && |
309 | /* because my device returns 0-100 even though the min and max are 0-255 */ | 333 | buf[1] <= dev->battery_max) |
310 | val->intval = buf[1]; | 334 | val->intval = (100 * (buf[1] - dev->battery_min)) / |
335 | (dev->battery_max - dev->battery_min); | ||
311 | break; | 336 | break; |
312 | 337 | ||
313 | case POWER_SUPPLY_PROP_MODEL_NAME: | 338 | case POWER_SUPPLY_PROP_MODEL_NAME: |
@@ -330,6 +355,7 @@ static void hidinput_setup_battery(struct hid_device *dev, unsigned id, s32 min, | |||
330 | { | 355 | { |
331 | struct power_supply *battery = &dev->battery; | 356 | struct power_supply *battery = &dev->battery; |
332 | int ret; | 357 | int ret; |
358 | unsigned quirks; | ||
333 | 359 | ||
334 | if (battery->name != NULL) | 360 | if (battery->name != NULL) |
335 | return; /* already initialized? */ | 361 | return; /* already initialized? */ |
@@ -344,6 +370,13 @@ static void hidinput_setup_battery(struct hid_device *dev, unsigned id, s32 min, | |||
344 | battery->use_for_apm = 0; | 370 | battery->use_for_apm = 0; |
345 | battery->get_property = hidinput_get_battery_property; | 371 | battery->get_property = hidinput_get_battery_property; |
346 | 372 | ||
373 | quirks = find_battery_quirk(dev); | ||
374 | |||
375 | if (quirks & HID_BATTERY_QUIRK_PERCENT) { | ||
376 | min = 0; | ||
377 | max = 100; | ||
378 | } | ||
379 | |||
347 | dev->battery_min = min; | 380 | dev->battery_min = min; |
348 | dev->battery_max = max; | 381 | dev->battery_max = max; |
349 | dev->battery_report_id = id; | 382 | dev->battery_report_id = id; |
diff --git a/include/linux/hid.h b/include/linux/hid.h index b5df198d87a5..fa772c86fa2c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -735,6 +735,8 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); | |||
735 | int hid_check_keys_pressed(struct hid_device *hid); | 735 | int hid_check_keys_pressed(struct hid_device *hid); |
736 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); | 736 | int hid_connect(struct hid_device *hid, unsigned int connect_mask); |
737 | void hid_disconnect(struct hid_device *hid); | 737 | void hid_disconnect(struct hid_device *hid); |
738 | const struct hid_device_id *hid_match_id(struct hid_device *hdev, | ||
739 | const struct hid_device_id *id); | ||
738 | 740 | ||
739 | /** | 741 | /** |
740 | * hid_map_usage - map usage input bits | 742 | * hid_map_usage - map usage input bits |