hidpp20: first parsing of feature 0x8070 - onboard profiles

This commit is contained in:
Ilya Guterman
2016-12-16 05:15:31 +02:00
committed by Peter Hutterer
parent d1e42ac56c
commit 7d241642f9
2 changed files with 83 additions and 0 deletions

View File

@@ -1289,6 +1289,7 @@ hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
profiles->num_rom_profiles = info->profile_count_oob;
profiles->num_buttons = msg.msg.parameters[5] <= 16 ? msg.msg.parameters[5] : 16;
profiles->num_modes = HIDPP20_DPI_COUNT;
profiles->num_leds = HIDPP20_LED_COUNT;
profiles->has_g_shift = (info->mechanical_layout & 0x03) == 2;
profiles->has_dpi_shift = ((info->mechanical_layout & 0x0c) >> 2) == 2;
switch(info->various_info & 0x07) {
@@ -1776,6 +1777,30 @@ hidpp20_buttons_from_cpu(struct hidpp20_profile *profile,
}
}
static void
hidpp20_onboard_profile_read_led(struct hidpp20_led *led,
struct hidpp20_internal_led internal_led)
{
uint16_t rate = 0;
uint8_t brightness = 0;
switch (internal_led.mode) {
case HIDPP20_LED_CYCLE:
rate = internal_led.effect.cycle.rate;
brightness = internal_led.effect.cycle.brightness;
break;
case HIDPP20_LED_BREATHING:
rate = internal_led.effect.breath.rate;
brightness = internal_led.effect.breath.brightness;
break;
}
led->mode = (enum hidpp20_led_mode)internal_led.mode;
led->color = internal_led.color;
led->rate = rate;
led->brightness = brightness;
}
int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
unsigned int index,
struct hidpp20_profiles *profiles_list)
@@ -1804,6 +1829,9 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
profile->dpi[i] = hidpp_get_unaligned_le_u16(&data[2 * i + 3]);
}
for (i = 0; i < profiles_list->num_leds; i++)
hidpp20_onboard_profile_read_led(&profile->leds[i], pdata.profile.leds[i]);
hidpp20_buttons_to_cpu(device, profile, pdata.profile.buttons, profiles_list->num_buttons);
memcpy(profile->name, pdata.profile.name.txt, sizeof(profile->name));
@@ -1821,6 +1849,33 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
return 0;
}
static void
hidpp20_onboard_write_profile_led(struct hidpp20_internal_led *internal_led,
struct hidpp20_led *led)
{
uint16_t rate = led->rate;
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 = rate;
internal_led->effect.cycle.brightness = brightness;
break;
case HIDPP20_LED_BREATHING:
internal_led->effect.breath.rate = rate;
internal_led->effect.breath.brightness = brightness;
break;
case HIDPP20_LED_ON:
case HIDPP20_LED_OFF:
break;
}
}
int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
unsigned int index,
struct hidpp20_profiles *profiles_list)
@@ -1853,6 +1908,9 @@ int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
pdata.profile.dpi[i] = hidpp_cpu_to_le_u16(profile->dpi[i]);
}
for (i = 0; i < profiles_list->num_leds; i++)
hidpp20_onboard_write_profile_led(&pdata.profile.leds[i], &profile->leds[i]);
hidpp20_buttons_from_cpu(profile, pdata.profile.buttons, profiles_list->num_buttons);
memcpy(pdata.profile.name.txt, profile->name, sizeof(profile->name));

View File

@@ -117,6 +117,13 @@ 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.
*
@@ -276,6 +283,7 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
#define HIDPP20_MODIFIER_KEY_SHIFT 0x02
#define HIDPP20_DPI_COUNT 5
#define HIDPP20_LED_COUNT 2
union hidpp20_button_binding {
struct {
@@ -324,6 +332,12 @@ struct hidpp20_color {
} __attribute__((packed));
_Static_assert(sizeof(struct hidpp20_color) == 3, "Invalid size");
enum hidpp20_led_type {
HIDPP20_LED_UNKNOWN = -1,
HIDPP20_LED_LOGO = 0,
HIDPP20_LED_SIDE,
};
struct hidpp20_internal_led {
uint8_t mode; /* 00 - off; 01 - on; 03 - cycle; 0a - breath */
struct hidpp20_color color;
@@ -347,6 +361,15 @@ _Static_assert(sizeof(struct hidpp20_led_cycle) == 7, "Invalid size");
_Static_assert(sizeof(struct hidpp20_led_breath) == 7, "Invalid size");
_Static_assert(sizeof(struct hidpp20_internal_led) == 11, "Invalid size");
typedef uint8_t percent_t;
struct hidpp20_led {
enum hidpp20_led_mode mode;
struct hidpp20_color color;
uint16_t rate;
percent_t brightness;
};
#define HIDPP20_MACRO_NOOP 0x01
#define HIDPP20_MACRO_DELAY 0x40
#define HIDPP20_MACRO_KEY_PRESS 0x43
@@ -388,6 +411,7 @@ struct hidpp20_profile {
uint16_t dpi[HIDPP20_DPI_COUNT];
union hidpp20_button_binding buttons[32];
union hidpp20_macro_data *macros[32];
struct hidpp20_led leds[32];
};
struct hidpp20_profiles {
@@ -395,6 +419,7 @@ struct hidpp20_profiles {
uint8_t num_rom_profiles;
uint8_t num_buttons;
uint8_t num_modes;
uint8_t num_leds;
uint8_t has_g_shift;
uint8_t has_dpi_shift;
uint8_t corded;