diff --git a/src/hidpp10.c b/src/hidpp10.c index 2eaed646..38b3ee4d 100644 --- a/src/hidpp10.c +++ b/src/hidpp10.c @@ -325,6 +325,47 @@ hidpp10_set_individual_feature(struct hidpp10_device *dev, return res; } +/* -------------------------------------------------------------------------- */ +/* 0x07: Battery status */ +/* -------------------------------------------------------------------------- */ +#define __CMD_BATTERY_STATUS 0x07 + +#define CMD_BATTERY_STATUS(idx, sub) { \ + .msg = { \ + .report_id = REPORT_ID_SHORT, \ + .device_idx = idx, \ + .sub_id = sub, \ + .address = __CMD_BATTERY_STATUS, \ + .parameters = {0x00, 0x00, 0x00 }, \ + } \ +} + +int +hidpp10_get_battery_status(struct hidpp10_device *dev, + enum hidpp10_battery_level *level, + enum hidpp10_battery_charge_state *charge_state, + uint8_t *low_threshold_in_percent) +{ + unsigned idx = dev->index; + union hidpp10_message battery = CMD_BATTERY_STATUS(idx, GET_REGISTER_REQ); + int res; + + res = hidpp10_request_command(dev, &battery); + + *level = battery.msg.parameters[0]; + *charge_state = battery.msg.parameters[1]; + *low_threshold_in_percent = battery.msg.parameters[2]; + + if (*low_threshold_in_percent >= 7) { + /* reserved value, we just silently truncate it to 0 */ + *low_threshold_in_percent = 0; + } + + *low_threshold_in_percent *= 5; /* in 5% increments */ + + return res; +} + /* -------------------------------------------------------------------------- */ /* 0x0F: Profile queries */ /* -------------------------------------------------------------------------- */ diff --git a/src/hidpp10.h b/src/hidpp10.h index 494290a8..ebbc5aee 100644 --- a/src/hidpp10.h +++ b/src/hidpp10.h @@ -108,6 +108,41 @@ hidpp10_set_individual_feature(struct hidpp10_device *dev, uint8_t feature_bit_r0, uint8_t feature_bit_r2); +/* -------------------------------------------------------------------------- */ +/* 0x07: Battery Status */ +/* -------------------------------------------------------------------------- */ + +enum hidpp10_battery_level { + HIDPP10_BATTERY_LEVEL_UNKNOWN = 0x00, + HIDPP10_BATTERY_LEVEL_CRITICAL = 0x01, + HIDPP10_BATTERY_LEVEL_CRITICAL_LEGACY = 0x02, + HIDPP10_BATTERY_LEVEL_LOW = 0x03, + HIDPP10_BATTERY_LEVEL_LOW_LEGACY = 0x04, + HIDPP10_BATTERY_LEVEL_GOOD = 0x05, + HIDPP10_BATTERY_LEVEL_GOOD_LEGACY = 0x06, + HIDPP10_BATTERY_LEVEL_FULL_LEGACY = 0x07, + /* 0x08..0xFF ... reserved */ +}; + +enum hidpp10_battery_charge_state { + HIDPP10_BATTERY_CHARGE_STATE_NOT_CHARGING = 0x00, + /* 0x01 ... 0x1F ... reserved (not charging) */ + HIDPP10_BATTERY_CHARGE_STATE_UNKNOWN = 0x20, + HIDPP10_BATTERY_CHARGE_STATE_CHARGING = 0x21, + HIDPP10_BATTERY_CHARGE_STATE_CHARGING_COMPLETE = 0x22, + HIDPP10_BATTERY_CHARGE_STATE_CHARGING_ERROR = 0x23, + HIDPP10_BATTERY_CHARGE_STATE_CHARGING_FAST = 0x24, + HIDPP10_BATTERY_CHARGE_STATE_CHARGING_SLOW = 0x25, + HIDPP10_BATTERY_CHARGE_STATE_TOPPING_CHARGE = 0x26, + /* 0x27 .. 0xff ... reserved */ +}; + +int +hidpp10_get_battery_status(struct hidpp10_device *dev, + enum hidpp10_battery_level *level, + enum hidpp10_battery_charge_state *charge_state, + uint8_t *low_threshold_in_percent); + /* -------------------------------------------------------------------------- */ /* 0x0F: Profile queries */ /* -------------------------------------------------------------------------- */