1
0
forked from drath/libratbag

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 <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2015-10-12 10:47:45 +10:00
parent bc7c48ecc0
commit 633c5cb106
2 changed files with 44 additions and 14 deletions

View File

@@ -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;

View File

@@ -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];
};