From 633c5cb106d8b3c5b7084ccd98e48740487b6269 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Oct 2015 10:47:45 +1000 Subject: [PATCH] hidpp10: extend handling of 0x51 LEDs First: there are 6 LEDs, not just 4. If the LEDs don't exist, the value is UNCHANGED on the read request. The value is more than a simple on/off, though at least the G500s only looks at the lower two bits, so heartbeat and slow off both translate into "on" and blink and slow on both translate to "off". There doesn't seem to be a detection mechanism for what a device really supports. Signed-off-by: Peter Hutterer --- src/hidpp10.c | 40 +++++++++++++++++++++++++++++----------- src/hidpp10.h | 18 +++++++++++++++--- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/hidpp10.c b/src/hidpp10.c index 0863ca56..02313269 100644 --- a/src/hidpp10.c +++ b/src/hidpp10.c @@ -627,10 +627,11 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_pr int hidpp10_get_led_status(struct hidpp10_device *dev, - bool led[4]) + enum hidpp10_led_status led[6]) { unsigned idx = dev->index; union hidpp10_message led_status = CMD_LED_STATUS(idx, GET_REGISTER_REQ); + uint8_t *status = led_status.msg.parameters; int res; log_raw(dev->ratbag_device->ratbag, "Fetching LED status\n"); @@ -639,30 +640,47 @@ hidpp10_get_led_status(struct hidpp10_device *dev, if (res) return res; - /* each led is 4-bits, 0x1 == off, 0x2 == on */ - led[0] = !!(led_status.msg.parameters[0] & 0x02); /* running man logo */ - led[1] = !!(led_status.msg.parameters[0] & 0x20); /* lowest */ - led[2] = !!(led_status.msg.parameters[1] & 0x02); /* middle */ - led[3] = !!(led_status.msg.parameters[1] & 0x20); /* highest */ + led[0] = status[0] & 0xF; + led[1] = (status[0] >> 4) & 0xF; + led[2] = status[1] & 0xF; + led[3] = (status[1] >> 4) & 0xF; + led[4] = status[2] & 0xF; + led[5] = (status[2] >> 4) & 0xF; return 0; } int hidpp10_set_led_status(struct hidpp10_device *dev, - const bool led[4]) + const enum hidpp10_led_status led[6]) { unsigned idx = dev->index; union hidpp10_message led_status = CMD_LED_STATUS(idx, SET_REGISTER_REQ); + uint8_t *status = led_status.msg.parameters; int res; + int i; log_raw(dev->ratbag_device->ratbag, "Setting LED status\n"); + for (i = 0; i < 6; i++) { + switch (led[i]) { + case HIDPP10_LED_STATUS_NO_CHANGE: + case HIDPP10_LED_STATUS_OFF: + case HIDPP10_LED_STATUS_ON: + case HIDPP10_LED_STATUS_BLINK: + case HIDPP10_LED_STATUS_HEARTBEAT: + case HIDPP10_LED_STATUS_SLOW_ON: + case HIDPP10_LED_STATUS_SLOW_OFF: + break; + default: + abort(); + } + } + /* each led is 4-bits, 0x1 == off, 0x2 == on */ - led_status.msg.parameters[0] |= led[0] ? 0x02 : 0x01; /* running man logo */ - led_status.msg.parameters[0] |= led[1] ? 0x20 : 0x10; /* lowest */ - led_status.msg.parameters[1] |= led[2] ? 0x02 : 0x01; /* middle */ - led_status.msg.parameters[1] |= led[3] ? 0x20 : 0x10; /* highest */ + status[0] = led[0] | (led[1] << 4); + status[1] = led[2] | (led[3] << 4); + status[2] = led[4] | (led[5] << 4); res = hidpp10_request_command(dev, &led_status); return res; diff --git a/src/hidpp10.h b/src/hidpp10.h index 20a7041d..62ca1455 100644 --- a/src/hidpp10.h +++ b/src/hidpp10.h @@ -208,12 +208,24 @@ hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, /* -------------------------------------------------------------------------- */ /* 0x51: LED Status */ /* -------------------------------------------------------------------------- */ + +enum hidpp10_led_status { + HIDPP10_LED_STATUS_NO_CHANGE = 0x0, /**< LED does not exist, or + should not change */ + HIDPP10_LED_STATUS_OFF = 0x1, + HIDPP10_LED_STATUS_ON = 0x2, + HIDPP10_LED_STATUS_BLINK = 0x3, + HIDPP10_LED_STATUS_HEARTBEAT = 0x4, + HIDPP10_LED_STATUS_SLOW_ON = 0x5, + HIDPP10_LED_STATUS_SLOW_OFF = 0x6, +}; + int hidpp10_get_led_status(struct hidpp10_device *dev, - bool led[4]); + enum hidpp10_led_status led[6]); int hidpp10_set_led_status(struct hidpp10_device *dev, - const bool led[4]); + const enum hidpp10_led_status led[6]); /* -------------------------------------------------------------------------- */ /* 0x54: LED Intensity */ @@ -306,7 +318,7 @@ struct hidpp10_device { uint8_t build; uint16_t xres, yres; uint16_t refresh_rate; - bool led[4]; + enum hidpp10_led_status led[6]; int8_t current_profile; struct hidpp10_profile profiles[HIDPP10_NUM_PROFILES]; };