diff options
author | Peter Wu <lekensteyn@gmail.com> | 2013-08-06 22:34:27 +0200 |
---|---|---|
committer | Peter Wu <lekensteyn@gmail.com> | 2013-08-22 22:59:27 +0200 |
commit | 0cc7c672f995f9414dd9b6ce24512e047a7f5af1 (patch) | |
tree | 4179a55d201cd80a733daa42ede85aeb903b52ed | |
parent | 33da6d6f4d29d0231433dacb0a609efd3ca71108 (diff) | |
download | upower-0cc7c672f995f9414dd9b6ce24512e047a7f5af1.tar.gz |
hidpp: support battery register 0x07
The HID++ 1.0 Illuminated Keyboard K800 does not support the d7
register, instead is uses 07. Its observed behaviour is documented in
the ltunify repository[1].
[1]: https://git.lekensteyn.nl/ltunify/tree/registers.txt
Signed-off-by: Peter Wu <lekensteyn@gmail.com>
-rw-r--r-- | src/linux/hidpp-device.c | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c index 1d53bc6..579e88d 100644 --- a/src/linux/hidpp-device.c +++ b/src/linux/hidpp-device.c @@ -41,6 +41,7 @@ /* HID++ 1.0 */ #define HIDPP_READ_SHORT_REGISTER 0x81 #define HIDPP_READ_SHORT_REGISTER_BATTERY 0x0d +#define HIDPP_READ_SHORT_REGISTER_BATTERY_APPROX 0x07 #define HIDPP_READ_LONG_REGISTER 0x83 #define HIDPP_READ_LONG_REGISTER_DEVICE_TYPE 11 @@ -791,10 +792,61 @@ hidpp_device_refresh (HidppDevice *device, ret = hidpp_device_cmd (device, &msg, &msg, error); + if (!ret && hidpp_is_error(&msg, &error_code) && + error_code == HIDPP10_ERROR_CODE_INVALID_ADDRESS) { + g_error_free(*error); + *error = NULL; + + msg.type = HIDPP_MSG_TYPE_SHORT; + msg.device_idx = priv->device_idx; + msg.feature_idx = HIDPP_READ_SHORT_REGISTER; + msg.function_idx = HIDPP_READ_SHORT_REGISTER_BATTERY_APPROX; + memset(msg.s.params, 0, sizeof(msg.s.params)); + + ret = hidpp_device_cmd (device, + &msg, &msg, + error); + } if (!ret) goto out; - priv->batt_percentage = msg.s.params[0]; - priv->batt_status = HIDPP_DEVICE_BATT_STATUS_DISCHARGING; + if (msg.function_idx == HIDPP_READ_SHORT_REGISTER_BATTERY) { + priv->batt_percentage = msg.s.params[0]; + priv->batt_status = HIDPP_DEVICE_BATT_STATUS_DISCHARGING; + } else { + /* approximate battery levels */ + switch (msg.s.params[0]) { + case 1: /* 0 - 10 */ + priv->batt_percentage = 5; + break; + case 3: /* 11 - 30 */ + priv->batt_percentage = 20; + break; + case 5: /* 31 - 80 */ + priv->batt_percentage = 55; + break; + case 7: /* 81 - 100 */ + priv->batt_percentage = 90; + break; + default: + g_debug("Unknown battery percentage: %i", priv->batt_percentage); + break; + } + switch (msg.s.params[1]) { + case 0x00: + priv->batt_status = HIDPP_DEVICE_BATT_STATUS_DISCHARGING; + break; + case 0x22: + case 0x26: /* for notification, probably N/A for reg read */ + priv->batt_status = HIDPP_DEVICE_BATT_STATUS_CHARGED; + break; + case 0x25: + priv->batt_status = HIDPP_DEVICE_BATT_STATUS_CHARGING; + break; + default: + g_debug("Unknown battery status: 0x%02x", priv->batt_status); + break; + } + } } else if (priv->version == 2) { /* sent a SetLightMeasure report */ |