mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 15:14:38 +01:00
hidpp20: Implement feature 0x8070: LED effects
This commit is contained in:
committed by
Peter Hutterer
parent
4d6390ea66
commit
6414f7901f
@@ -138,6 +138,21 @@ static const struct hidpp20_1b04_physical_mapping hidpp20_1b04_physical_mapping[
|
||||
BUTTON_PHYS_MAPPING(221, "LedToggle" , RATBAG_BUTTON_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
struct hidpp20_8070_location_mapping {
|
||||
uint16_t value;
|
||||
const char *name;
|
||||
enum ratbag_led_type type;
|
||||
};
|
||||
|
||||
#define LED_LOC_MAPPING(v_, n_, t_) \
|
||||
{ v_, n_, t_ }
|
||||
|
||||
static const struct hidpp20_8070_location_mapping hidpp20_8070_location_mapping[] = {
|
||||
LED_LOC_MAPPING(0, "None", RATBAG_LED_TYPE_UNKNOWN),
|
||||
LED_LOC_MAPPING(256, "Logo LED", RATBAG_LED_TYPE_LOGO),
|
||||
LED_LOC_MAPPING(512, "Side LED", RATBAG_LED_TYPE_SIDE),
|
||||
};
|
||||
|
||||
const struct ratbag_button_action *
|
||||
hidpp20_1b04_get_logical_mapping(uint16_t value)
|
||||
{
|
||||
@@ -203,6 +218,32 @@ hidpp20_1b04_get_physical_mapping_name(uint16_t value)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
enum ratbag_led_type
|
||||
hidpp20_8070_get_location_mapping(uint16_t value)
|
||||
{
|
||||
const struct hidpp20_8070_location_mapping *map;
|
||||
|
||||
ARRAY_FOR_EACH(hidpp20_8070_location_mapping, map) {
|
||||
if (map->value == value)
|
||||
return map->type;
|
||||
}
|
||||
|
||||
return RATBAG_LED_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
const char *
|
||||
hidpp20_8070_get_location_mapping_name(uint16_t value)
|
||||
{
|
||||
const struct hidpp20_8070_location_mapping *map;
|
||||
|
||||
ARRAY_FOR_EACH(hidpp20_8070_location_mapping, map) {
|
||||
if (map->value == value)
|
||||
return map->name;
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
int
|
||||
hidpp_write_command(struct hidpp_device *dev, uint8_t *cmd, int size)
|
||||
{
|
||||
|
||||
@@ -106,6 +106,12 @@ hidpp20_1b04_get_physical_mapping_name(uint16_t value);
|
||||
enum ratbag_button_type
|
||||
hidpp20_1b04_get_physical_mapping(uint16_t value);
|
||||
|
||||
enum ratbag_led_type
|
||||
hidpp20_8070_get_location_mapping(uint16_t value);
|
||||
|
||||
const char *
|
||||
hidpp20_8070_get_location_mapping_name(uint16_t value);
|
||||
|
||||
const char *
|
||||
hidpp20_1b04_get_logical_mapping_name(uint16_t value);
|
||||
|
||||
|
||||
112
src/hidpp20.c
112
src/hidpp20.c
@@ -500,6 +500,118 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x8070 - Color LED effects */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define CMD_COLOR_LED_EFFECTS_GET_INFO 0x00
|
||||
#define CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO 0x10
|
||||
|
||||
static int
|
||||
hidpp20_color_led_zones_get_count(struct hidpp20_device *device, uint8_t reg)
|
||||
{
|
||||
int rc;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_SHORT,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.address = CMD_COLOR_LED_EFFECTS_GET_INFO,
|
||||
};
|
||||
struct hidpp20_color_led_info *info;
|
||||
uint8_t feature_index;
|
||||
|
||||
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;
|
||||
|
||||
info = (struct hidpp20_color_led_info *)msg.msg.parameters;
|
||||
|
||||
return info->zone_count;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_info(struct hidpp20_device *device,
|
||||
uint8_t reg,
|
||||
struct hidpp20_color_led_zone_info *info)
|
||||
{
|
||||
int rc;
|
||||
struct hidpp20_color_led_zone_info *msg_info;
|
||||
union hidpp20_message msg = {
|
||||
.msg.report_id = REPORT_ID_LONG,
|
||||
.msg.device_idx = device->index,
|
||||
.msg.sub_id = reg,
|
||||
.msg.address = CMD_COLOR_LED_EFFECTS_GET_ZONE_INFO,
|
||||
.msg.parameters[0] = info->index,
|
||||
};
|
||||
|
||||
rc = hidpp20_request_command(device, &msg);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
msg_info = (struct hidpp20_color_led_zone_info *)msg.msg.parameters;
|
||||
info->location = msg_info->location;
|
||||
info->num_effects = msg_info->num_effects;
|
||||
info->persistency_caps = msg_info->persistency_caps;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_infos(struct hidpp20_device *device,
|
||||
struct hidpp20_color_led_zone_info **infos_list)
|
||||
{
|
||||
uint8_t feature_index;
|
||||
struct hidpp20_color_led_zone_info *i_list, *info;
|
||||
uint8_t num_infos;
|
||||
unsigned i;
|
||||
int rc;
|
||||
|
||||
feature_index = hidpp_root_get_feature_idx(device,
|
||||
HIDPP_PAGE_COLOR_LED_EFFECTS);
|
||||
if (feature_index == 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
rc = hidpp20_color_led_zones_get_count(device, feature_index);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
num_infos = rc;
|
||||
if (num_infos == 0) {
|
||||
*infos_list = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
i_list = zalloc(num_infos * sizeof(struct hidpp20_color_led_zone_info));
|
||||
|
||||
for (i = 0; i < num_infos; i++) {
|
||||
info = &i_list[i];
|
||||
info->index = i;
|
||||
rc = hidpp20_color_led_effects_get_zone_info(device, feature_index, info);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
hidpp_log_raw(&device->base,
|
||||
"led_info %d: location: %d type %s num_effects: %d persistency_caps: 0x%02x\n",
|
||||
info->index,
|
||||
info->location,
|
||||
hidpp20_8070_get_location_mapping_name(info->location),
|
||||
info->num_effects,
|
||||
info->persistency_caps);
|
||||
}
|
||||
|
||||
*infos_list = i_list;
|
||||
return num_infos;
|
||||
err:
|
||||
free(i_list);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x1b04: Special keys and mouse buttons */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@@ -265,6 +265,41 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
|
||||
|
||||
#define HIDPP_PAGE_COLOR_LED_EFFECTS 0x8070
|
||||
|
||||
|
||||
struct hidpp20_color_led_info;
|
||||
|
||||
struct hidpp20_color_led_zone_info;
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_info(struct hidpp20_device *device,
|
||||
uint8_t reg, struct hidpp20_color_led_zone_info *info);
|
||||
|
||||
int
|
||||
hidpp20_color_led_effects_get_zone_infos(struct hidpp20_device *device,
|
||||
struct hidpp20_color_led_zone_info **infos_list);
|
||||
|
||||
enum hidpp20_color_led_location {
|
||||
HIDPP20_COLOR_LED_LOCATION_UNDEFINED = 0,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY,
|
||||
HIDPP20_COLOR_LED_LOCATION_LOGO,
|
||||
HIDPP20_COLOR_LED_LOCATION_LEFT,
|
||||
HIDPP20_COLOR_LED_LOCATION_RIGHT,
|
||||
HIDPP20_COLOR_LED_LOCATION_COMBINED,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_1,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_2,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_3,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_4,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_5,
|
||||
HIDPP20_COLOR_LED_LOCATION_PRIMARY_6,
|
||||
};
|
||||
|
||||
enum hidpp20_color_led_persistency {
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_UNSUPPORTED,
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_ON,
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_OFF,
|
||||
HIDPP20_COLOR_LED_PERSISTENCY_ON_OFF,
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 0x8100 - Onboard Profiles */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -325,6 +360,23 @@ union hidpp20_button_binding {
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(union hidpp20_button_binding) == 4, "Invalid size");
|
||||
|
||||
struct hidpp20_color_led_info {
|
||||
uint8_t zone_count;
|
||||
/* we don't care about NV capabilities for libratbag, they just
|
||||
* indicate sale demo effects */
|
||||
uint16_t nv_caps;
|
||||
uint16_t ext_caps;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct hidpp20_color_led_info) == 5, "Invalid size");
|
||||
|
||||
struct hidpp20_color_led_zone_info {
|
||||
uint8_t index;
|
||||
uint16_t location;
|
||||
uint8_t num_effects;
|
||||
uint8_t persistency_caps;
|
||||
} __attribute__((packed));
|
||||
_Static_assert(sizeof(struct hidpp20_color_led_zone_info) == 5, "Invalid size");
|
||||
|
||||
struct hidpp20_color {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
|
||||
@@ -1317,6 +1317,16 @@ ratbag_button_set_button(struct ratbag_button *button,
|
||||
enum ratbag_button_action_special
|
||||
ratbag_button_get_special(struct ratbag_button *button);
|
||||
|
||||
/**
|
||||
* @ingroup led
|
||||
*
|
||||
* LED types, usually based on their physical location
|
||||
*/
|
||||
enum ratbag_led_type {
|
||||
RATBAG_LED_TYPE_UNKNOWN = -1,
|
||||
RATBAG_LED_TYPE_LOGO = 0,
|
||||
RATBAG_LED_TYPE_SIDE
|
||||
};
|
||||
/**
|
||||
* @ingroup button
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user