diff --git a/src/driver-hidpp20.c b/src/driver-hidpp20.c index 2588a25f..6322382c 100644 --- a/src/driver-hidpp20.c +++ b/src/driver-hidpp20.c @@ -278,7 +278,7 @@ hidpp20drv_read_led(struct ratbag_led *led) led->color.red = h_led->color.red; led->color.green = h_led->color.green; led->color.blue = h_led->color.blue; - led->hz = h_led->rate; + led->hz = h_led->period; /* FIXME: should be ceil(1000.0 / h_led->period), but that would be very small */ led->brightness = h_led->brightness * 255 / 100; } @@ -421,7 +421,7 @@ hidpp20drv_update_led(struct ratbag_led *led) h_led->color.red = led->color.red; h_led->color.green = led->color.green; h_led->color.blue = led->color.blue; - h_led->rate = led->hz; + h_led->period = led->hz; /* FIXME: should be 1000 / led->hz, but that would be very small */ h_led->brightness = led->brightness * 100 / 255; return RATBAG_SUCCESS; diff --git a/src/hidpp20.c b/src/hidpp20.c index e658033f..cdd0b39a 100644 --- a/src/hidpp20.c +++ b/src/hidpp20.c @@ -1896,28 +1896,33 @@ static void hidpp20_onboard_profiles_read_led(struct hidpp20_led *led, struct hidpp20_internal_led internal_led) { - uint16_t rate = 0; + uint16_t period = 0; uint8_t brightness = 0; led->mode = (enum hidpp20_led_mode)internal_led.mode; switch (led->mode) { case HIDPP20_LED_CYCLE: - rate = hidpp_be_u16_to_cpu(internal_led.effect.cycle.rate); - brightness = internal_led.effect.cycle.brightness; + period = hidpp_be_u16_to_cpu(internal_led.effect.cycle.period_or_speed); + brightness = internal_led.effect.cycle.intensity; + if (brightness == 0) + brightness = 100; break; case HIDPP20_LED_BREATHING: - rate = hidpp_be_u16_to_cpu(internal_led.effect.breath.rate); - brightness = internal_led.effect.breath.brightness; + period = hidpp_be_u16_to_cpu(internal_led.effect.breath.period_or_speed); + brightness = internal_led.effect.breath.intensity; + if (brightness == 0) + brightness = 100; + led->color = internal_led.effect.breath.color; break; case HIDPP20_LED_ON: + led->color = internal_led.effect.fixed.color; break; case HIDPP20_LED_OFF: break; } - led->color = internal_led.color; - led->rate = rate; + led->period = period; led->brightness = brightness; } @@ -1973,24 +1978,35 @@ static void hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led, struct hidpp20_led *led) { - uint16_t rate = led->rate; + uint16_t period = led->period; uint8_t brightness = led->brightness; internal_led->mode = (uint8_t)led->mode; - internal_led->color.red = led->color.red; - internal_led->color.blue = led->color.blue; - internal_led->color.green = led->color.green; switch (led->mode) { case HIDPP20_LED_CYCLE: - internal_led->effect.cycle.rate = hidpp_cpu_to_be_u16(rate); - internal_led->effect.cycle.brightness = brightness; + internal_led->effect.cycle.period_or_speed = hidpp_cpu_to_be_u16(period); + if (brightness < 100) + internal_led->effect.cycle.intensity = brightness; + else + internal_led->effect.cycle.intensity = 0; break; case HIDPP20_LED_BREATHING: - internal_led->effect.breath.rate = hidpp_cpu_to_be_u16(rate); - internal_led->effect.breath.brightness = brightness; + internal_led->effect.breath.color.red = led->color.red; + internal_led->effect.breath.color.blue = led->color.blue; + internal_led->effect.breath.color.green = led->color.green; + internal_led->effect.breath.period_or_speed = hidpp_cpu_to_be_u16(period); + if (brightness < 100) + internal_led->effect.breath.intensity = brightness; + else + internal_led->effect.breath.intensity = 0; break; case HIDPP20_LED_ON: + internal_led->effect.fixed.color.red = led->color.red; + internal_led->effect.fixed.color.blue = led->color.blue; + internal_led->effect.fixed.color.green = led->color.green; + internal_led->effect.fixed.effect = 0; + break; case HIDPP20_LED_OFF: break; } diff --git a/src/hidpp20.h b/src/hidpp20.h index e8fe6717..7ab64df1 100644 --- a/src/hidpp20.h +++ b/src/hidpp20.h @@ -116,13 +116,6 @@ enum hidpp20_battery_status { BATTERY_STATUS_INVALID, }; -enum hidpp20_led_mode { - HIDPP20_LED_OFF = 0x00, - HIDPP20_LED_ON = 0x01, - HIDPP20_LED_CYCLE = 0x03, - HIDPP20_LED_BREATHING = 0x0a, -}; - /** * Retrieves the battery level status. * @@ -389,26 +382,46 @@ enum hidpp20_led_type { HIDPP20_LED_SIDE, }; +enum hidpp20_led_mode { + HIDPP20_LED_OFF = 0x00, + HIDPP20_LED_ON = 0x01, + HIDPP20_LED_CYCLE = 0x03, + HIDPP20_LED_BREATHING = 0x0a, +}; + +enum hidpp20_led_waveform { + HIDPP20_LED_WF_DEFAULT = 0x00, + HIDPP20_LED_WF_SINE = 0x01, + HIDPP20_LED_WF_SQUARE = 0x02, + HIDPP20_LED_WF_TRIANGLE = 0x03, + HIDPP20_LED_WF_SAWTOOTH = 0x04, + HIDPP20_LED_WF_SHARKFIN = 0x05, + HIDPP20_LED_WF_EXPONENTIAL = 0x06, +}; + struct hidpp20_internal_led { - uint8_t mode; /* 00 - off; 01 - on; 03 - cycle; 0a - breath */ - struct hidpp20_color color; + uint8_t mode; /* enum hidpp20_led_mode */ union { + struct hidpp20_led_fixed { + struct hidpp20_color color; + uint8_t effect; + } __attribute__((packed)) fixed; struct hidpp20_led_cycle { - uint16_t pad_1; - uint16_t rate; /* 16000 - 20000Hz */ - uint8_t brightness; /* 0 - 100 percent */ - uint16_t pad_2; + uint8_t unused[5]; + uint16_t period_or_speed; /* period in ms, speed is device dependent */ + uint8_t intensity; /* 1 - 100 percent, 0 means 100 */ } __attribute__((packed)) cycle; struct hidpp20_led_breath { - uint16_t rate; - uint8_t pad_1; - uint8_t brightness; - uint8_t pad_2; - uint16_t pad_3; + struct hidpp20_color color; + uint16_t period_or_speed; /* period in ms, speed is device dependent */ + uint8_t waveform; /* enum hidpp20_led_waveform */ + uint8_t intensity; /* 1 - 100 percent, 0 means 100 */ } __attribute__((packed)) breath; + uint8_t padding[10]; } __attribute__((packed)) effect; }; -_Static_assert(sizeof(struct hidpp20_led_cycle) == 7, "Invalid size"); +_Static_assert(sizeof(struct hidpp20_led_fixed) == 4, "Invalid size"); +_Static_assert(sizeof(struct hidpp20_led_cycle) == 8, "Invalid size"); _Static_assert(sizeof(struct hidpp20_led_breath) == 7, "Invalid size"); _Static_assert(sizeof(struct hidpp20_internal_led) == 11, "Invalid size"); @@ -417,7 +430,7 @@ typedef uint8_t percent_t; struct hidpp20_led { enum hidpp20_led_mode mode; struct hidpp20_color color; - uint16_t rate; + uint16_t period; percent_t brightness; };