diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2011-12-09 03:10:28 -0500 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy@goop.org> | 2012-01-08 02:31:25 -0500 |
commit | 652aa6a9ac4a5f8d3e1fa3f6466646519e83c01e (patch) | |
tree | f5e08d9b5fc1634574cc713b66d96ebf1ff4c530 | |
parent | ce63920b395f1476e2d28cca16a56919289f0b62 (diff) |
hid-input/battery: add FEATURE quirk
Apple keyboards require a FEATURE report to query the battery state,
even though they list as an input. Without this, it returns an error.
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
-rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 27 |
2 files changed, 18 insertions, 10 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 06ce996b8b65..b63beb8e67d5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -124,6 +124,7 @@ | |||
124 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 | 124 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 |
125 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a | 125 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a |
126 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b | 126 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b |
127 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 | ||
127 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 | 128 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 |
128 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 129 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
129 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 130 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 48785db10e87..0f1250d10ea1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -283,12 +283,12 @@ static enum power_supply_property hidinput_battery_props[] = { | |||
283 | }; | 283 | }; |
284 | 284 | ||
285 | #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ | 285 | #define HID_BATTERY_QUIRK_PERCENT (1 << 0) /* always reports percent */ |
286 | #define HID_BATTERY_QUIRK_FEATURE (1 << 1) /* ask for feature report */ | ||
286 | 287 | ||
287 | static const struct hid_device_id hid_battery_quirks[] = { | 288 | static const struct hid_device_id hid_battery_quirks[] = { |
288 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), | 289 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
289 | HID_BATTERY_QUIRK_PERCENT }, | 290 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
290 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD), | 291 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
291 | HID_BATTERY_QUIRK_PERCENT }, | ||
292 | {} | 292 | {} |
293 | }; | 293 | }; |
294 | 294 | ||
@@ -310,7 +310,6 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
310 | { | 310 | { |
311 | struct hid_device *dev = container_of(psy, struct hid_device, battery); | 311 | struct hid_device *dev = container_of(psy, struct hid_device, battery); |
312 | int ret = 0; | 312 | int ret = 0; |
313 | int ret_rep; | ||
314 | __u8 buf[2] = {}; | 313 | __u8 buf[2] = {}; |
315 | 314 | ||
316 | switch (prop) { | 315 | switch (prop) { |
@@ -320,11 +319,13 @@ static int hidinput_get_battery_property(struct power_supply *psy, | |||
320 | break; | 319 | break; |
321 | 320 | ||
322 | case POWER_SUPPLY_PROP_CAPACITY: | 321 | case POWER_SUPPLY_PROP_CAPACITY: |
323 | ret_rep = dev->hid_get_raw_report(dev, dev->battery_report_id, | 322 | ret = dev->hid_get_raw_report(dev, dev->battery_report_id, |
324 | buf, sizeof(buf), | 323 | buf, sizeof(buf), |
325 | dev->battery_report_type); | 324 | dev->battery_report_type); |
326 | if (ret_rep != 2) { | 325 | |
327 | ret = -EINVAL; | 326 | if (ret != 2) { |
327 | if (ret >= 0) | ||
328 | ret = -EINVAL; | ||
328 | break; | 329 | break; |
329 | } | 330 | } |
330 | 331 | ||
@@ -376,6 +377,9 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, | |||
376 | 377 | ||
377 | quirks = find_battery_quirk(dev); | 378 | quirks = find_battery_quirk(dev); |
378 | 379 | ||
380 | hid_dbg(dev, "device %x:%x:%x %d quirks %d\n", | ||
381 | dev->bus, dev->vendor, dev->product, dev->version, quirks); | ||
382 | |||
379 | min = field->logical_minimum; | 383 | min = field->logical_minimum; |
380 | max = field->logical_maximum; | 384 | max = field->logical_maximum; |
381 | 385 | ||
@@ -384,6 +388,9 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, | |||
384 | max = 100; | 388 | max = 100; |
385 | } | 389 | } |
386 | 390 | ||
391 | if (quirks & HID_BATTERY_QUIRK_FEATURE) | ||
392 | report_type = HID_FEATURE_REPORT; | ||
393 | |||
387 | dev->battery_min = min; | 394 | dev->battery_min = min; |
388 | dev->battery_max = max; | 395 | dev->battery_max = max; |
389 | dev->battery_report_type = report_type; | 396 | dev->battery_report_type = report_type; |