aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2011-12-09 03:10:28 -0500
committerJeremy Fitzhardinge <jeremy@goop.org>2012-01-08 02:31:25 -0500
commit652aa6a9ac4a5f8d3e1fa3f6466646519e83c01e (patch)
treef5e08d9b5fc1634574cc713b66d96ebf1ff4c530 /drivers
parentce63920b395f1476e2d28cca16a56919289f0b62 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-input.c27
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
287static const struct hid_device_id hid_battery_quirks[] = { 288static 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;