hidpp20: enable 0x8070 (ColorLedEffects) standalone use

0x8071 is still missing but as of now we don't have any device that
needs it.

Signed-off-by: Filipe Laíns <lains@archlinux.org>
This commit is contained in:
Filipe Laíns
2020-01-23 20:37:56 +00:00
committed by Benjamin Tissoires
parent ba7c092ee2
commit b76fcdadde
3 changed files with 123 additions and 20 deletions

View File

@@ -69,6 +69,7 @@ struct hidpp20drv_data {
unsigned num_controls;
struct hidpp20_control_id *controls;
struct hidpp20_profiles *profiles;
struct hidpp20_led *leds;
union hidpp20_generic_led_zone_info led_infos;
unsigned int report_rates[4];
@@ -334,14 +335,20 @@ static void
hidpp20drv_read_led_8070(struct ratbag_led *led, struct hidpp20drv_data* drv_data)
{
struct hidpp20_profile *profile;
struct hidpp20_led *h_led;
struct hidpp20_led h_led_val;
struct hidpp20_led *h_led = &h_led_val;
struct hidpp20_color_led_zone_info* led_info;
struct hidpp20_color_led_info info;
int rc;
led_info = &drv_data->led_infos.color_leds_8070[led->index];
profile = &drv_data->profiles->profiles[led->profile->index];
h_led = &profile->leds[led->index];
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
profile = &drv_data->profiles->profiles[led->profile->index];
h_led = &profile->leds[led->index];
} else {
hidpp20_color_led_effects_get_zone_effect(drv_data->dev, led->index, h_led);
}
switch (h_led->mode) {
case HIDPP20_LED_ON:
@@ -691,11 +698,13 @@ hidpp20drv_update_led_8070_8071(struct ratbag_led *led, struct ratbag_profile* p
struct hidpp20drv_data *drv_data)
{
struct hidpp20_profile *h_profile;
struct hidpp20_led *h_led;
struct hidpp20_led h_led_val;
struct hidpp20_led *h_led = &h_led_val;
h_profile = &drv_data->profiles->profiles[profile->index];
h_led = &(h_profile->leds[led->index]);
if (drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) {
h_profile = &drv_data->profiles->profiles[profile->index];
h_led = &(h_profile->leds[led->index]);
}
if (!h_led)
return -EINVAL;
@@ -720,6 +729,13 @@ hidpp20drv_update_led_8070_8071(struct ratbag_led *led, struct ratbag_profile* p
h_led->period = led->ms;
h_led->brightness = led->brightness * 100 / 255;
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)) {
if (drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070)
hidpp20_color_led_effects_set_zone_effect(drv_data->dev,
led->index,
h_led_val);
}
return RATBAG_SUCCESS;
}
@@ -1237,17 +1253,11 @@ hidpp20drv_init_leds_8070_8071(struct ratbag_device *device)
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag *ratbag = device->ratbag;
/* we only support 0x8070/0x8071 via 0x8100 */
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100)) {
if (drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070) {
log_debug(ratbag, "disabling 0x8070 (Color Leds Effects) feature because the device doesn't have 0x8100 (Onboard Memory Profiles)\n");
drv_data->capabilities &= ~HIDPP_CAP_COLOR_LED_EFFECTS_8070;
}
if (drv_data->capabilities & HIDPP_CAP_RGB_EFFECTS_8071) {
log_debug(ratbag, "disabling 0x8071 (RGB Effects) feature because the device doesn't have 0x8100 (Onboard Memory Profiles)\n");
drv_data->capabilities &= ~HIDPP_CAP_RGB_EFFECTS_8071;
}
/* we only support 0x8071 via 0x8100 */
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100) &&
drv_data->capabilities & HIDPP_CAP_RGB_EFFECTS_8071) {
log_debug(ratbag, "disabling 0x8071 (RGB Effects) feature because the device doesn't have 0x8100 (Onboard Memory Profiles)\n");
drv_data->capabilities &= ~HIDPP_CAP_RGB_EFFECTS_8071;
}
if (drv_data->capabilities & HIDPP_CAP_COLOR_LED_EFFECTS_8070 ||
@@ -1612,6 +1622,7 @@ hidpp20drv_remove(struct ratbag_device *device)
free(drv_data->led_infos.color_leds_8070);
free(drv_data->controls);
free(drv_data->sensors);
free(drv_data->leds);
if (drv_data->dev)
hidpp20_device_destroy(drv_data->dev);
free(drv_data);

View File

@@ -868,6 +868,8 @@ err:
#define CMD_COLOR_LED_EFFECTS_GET_INFO 0x00
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO 0x10
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_EFFECT_INFO 0x20
#define CMD_COLOR_LED_EFFECTS_SET_ZONE_EFFECT 0x30
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_EFFECT 0xe0
int
hidpp20_color_led_effects_get_info(struct hidpp20_device *device,
@@ -1012,6 +1014,76 @@ hidpp20_color_led_effect_get_zone_effect_info(struct hidpp20_device *device,
return 0;
}
int
hidpp20_color_led_effects_set_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led led)
{
uint8_t feature_index;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_SHORT,
.msg.address = CMD_COLOR_LED_EFFECTS_SET_ZONE_EFFECT,
.msg.device_idx = device->index,
.msg.parameters[0] = zone_index,
.msg.parameters[12] = 1, /* write to RAM and flash */
};
int rc;
struct hidpp20_internal_led *internal_led = (struct hidpp20_internal_led*) &msg.msg.parameters[1];
hidpp20_onboard_profiles_write_led(internal_led, &led);
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_COLOR_LED_EFFECTS);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
return 0;
}
int
hidpp20_color_led_effects_get_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led *led)
{
uint8_t feature_index;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_SHORT,
.msg.address = CMD_COLOR_LED_EFFECTS_GET_ZONE_EFFECT,
.msg.device_idx = device->index,
.msg.parameters[0] = zone_index,
};
struct hidpp20_internal_led *internal_led;
int rc;
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_COLOR_LED_EFFECTS);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
if (msg.msg.parameters[0] != zone_index)
return -EPROTO;
internal_led = (struct hidpp20_internal_led*) &msg.msg.parameters[1];
hidpp20_onboard_profiles_read_led(led, *internal_led);
hidpp_log_debug(&device->base, "zone %u has effect %u\n", zone_index, led->mode);
return 0;
}
/* -------------------------------------------------------------------------- */
/* 0x8071: RGB Effects */
/* -------------------------------------------------------------------------- */
@@ -2566,7 +2638,7 @@ hidpp20_buttons_from_cpu(struct hidpp20_profile *profile,
}
}
static void
void
hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led)
{
@@ -2769,7 +2841,7 @@ read_profiles:
return profiles->num_profiles;
}
static void
void
hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led)
{

View File

@@ -501,6 +501,18 @@ hidpp20_rgb_effects_get_effect_info(struct hidpp20_device *device,
uint8_t effect_index,
struct hidpp20_rgb_effect_info *info);
struct hidpp20_led;
int
hidpp20_color_led_effects_set_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led led);
int
hidpp20_color_led_effects_get_zone_effect(struct hidpp20_device *device,
uint8_t zone_index,
struct hidpp20_led *led);
enum hidpp20_color_led_location {
HIDPP20_COLOR_LED_LOCATION_UNDEFINED = 0,
HIDPP20_COLOR_LED_LOCATION_PRIMARY,
@@ -925,6 +937,14 @@ hidpp20_onboard_profiles_allocate_sector(struct hidpp20_profiles *profiles)
return zalloc(profiles->sector_size);
}
void
hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led);
void
hidpp20_onboard_profiles_write_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led);
/* -------------------------------------------------------------------------- */
/* 0x8110 - Mouse Button Spy */
/* -------------------------------------------------------------------------- */