mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
hidpp20: check if crcs are valid once on plug
To check if device is using ROM or Flash settings. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
@@ -684,22 +684,6 @@ hidpp20drv_read_color_leds(struct ratbag_device *device)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp20drv_read_onboard_profile(struct ratbag_device *device, unsigned index)
|
||||
{
|
||||
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
|
||||
int rc;
|
||||
|
||||
if (!(drv_data->capabilities & HIDPP_CAP_ONBOARD_PROFILES_8100))
|
||||
return 0;
|
||||
|
||||
rc = hidpp20_onboard_profiles_read(drv_data->dev, index, drv_data->profiles);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index)
|
||||
{
|
||||
@@ -712,8 +696,6 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile, unsigned int index)
|
||||
|
||||
profile->is_enabled = drv_data->profiles->profiles[index].enabled;
|
||||
|
||||
hidpp20drv_read_onboard_profile(device, profile->index);
|
||||
|
||||
profile->is_active = false;
|
||||
if ((int)index == hidpp20drv_current_profile(device))
|
||||
profile->is_active = true;
|
||||
|
||||
@@ -1941,13 +1941,16 @@ hidpp20_onboard_profiles_read_led(struct hidpp20_led *led,
|
||||
led->brightness = brightness;
|
||||
}
|
||||
|
||||
int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
struct hidpp20_profiles *profiles_list)
|
||||
static int
|
||||
hidpp20_onboard_profiles_parse_profile(struct hidpp20_device *device,
|
||||
struct hidpp20_profiles *profiles_list,
|
||||
unsigned index,
|
||||
bool check_crc)
|
||||
{
|
||||
union hidpp20_internal_profile *pdata;
|
||||
_cleanup_free_ uint8_t *data = NULL;
|
||||
struct hidpp20_profile *profile = &profiles_list->profiles[index];
|
||||
uint16_t sector = index + 1;
|
||||
_cleanup_free_ uint8_t *data = NULL;
|
||||
unsigned i;
|
||||
int rc;
|
||||
|
||||
@@ -1957,14 +1960,21 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
data = hidpp20_onboard_profiles_allocate_sector(profiles_list);
|
||||
pdata = (union hidpp20_internal_profile *)data;
|
||||
|
||||
rc = hidpp20_onboard_profiles_find_and_read_profile(device,
|
||||
index,
|
||||
profiles_list->sector_size,
|
||||
data,
|
||||
profiles_list->num_rom_profiles);
|
||||
if (rc != 0)
|
||||
rc = hidpp20_onboard_profiles_read_sector(device,
|
||||
sector,
|
||||
profiles_list->sector_size,
|
||||
data);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (check_crc) {
|
||||
if (!hidpp20_onboard_profiles_is_sector_valid(device,
|
||||
profiles_list->sector_size,
|
||||
data)) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
profile->report_rate = 1000 / max(1, pdata->profile.report_rate);
|
||||
profile->default_dpi = pdata->profile.default_dpi;
|
||||
profile->switched_dpi = pdata->profile.switched_dpi;
|
||||
@@ -1993,22 +2003,37 @@ int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
|
||||
struct hidpp20_profiles *profiles)
|
||||
static int
|
||||
hidpp20_onboard_profiles_parse(struct hidpp20_device *device,
|
||||
struct hidpp20_profiles *profiles,
|
||||
uint16_t dict_address,
|
||||
bool check_crc)
|
||||
{
|
||||
unsigned i;
|
||||
int rc;
|
||||
_cleanup_free_ uint8_t *data = NULL;
|
||||
int rc;
|
||||
unsigned i;
|
||||
|
||||
assert(profiles);
|
||||
for (i = 0; i < profiles->num_profiles; i++) {
|
||||
profiles->profiles[i].index = 0;
|
||||
profiles->profiles[i].enabled = 0;
|
||||
}
|
||||
|
||||
data = hidpp20_onboard_profiles_allocate_sector(profiles);
|
||||
|
||||
rc = hidpp20_onboard_profiles_read_sector(device, 0, profiles->sector_size, data);
|
||||
rc = hidpp20_onboard_profiles_read_sector(device,
|
||||
dict_address,
|
||||
profiles->sector_size,
|
||||
data);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (check_crc) {
|
||||
if (!hidpp20_onboard_profiles_is_sector_valid(device,
|
||||
profiles->sector_size,
|
||||
data)) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < profiles->num_profiles; i++) {
|
||||
uint8_t *d = data + 4 * i;
|
||||
|
||||
@@ -2017,8 +2042,48 @@ hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
|
||||
|
||||
profiles->profiles[i].index = d[1];
|
||||
profiles->profiles[i].enabled = !!d[2];
|
||||
|
||||
rc = hidpp20_onboard_profiles_parse_profile(device,
|
||||
profiles,
|
||||
i,
|
||||
check_crc);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
hidpp20_onboard_profiles_initialize(struct hidpp20_device *device,
|
||||
struct hidpp20_profiles *profiles)
|
||||
{
|
||||
int rc;
|
||||
|
||||
assert(profiles);
|
||||
|
||||
rc = hidpp20_onboard_profiles_parse(device, profiles, 0x0000, true);
|
||||
if (rc == 0)
|
||||
return profiles->num_profiles;
|
||||
|
||||
if (rc != -EAGAIN) {
|
||||
/* something went wrong */
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* One of the used sector has a bad crc, the device is using the ROM
|
||||
* profiles.
|
||||
*/
|
||||
|
||||
hidpp_log_debug(&device->base, "device is using ROM settings\n");
|
||||
|
||||
rc = hidpp20_onboard_profiles_parse(device, profiles, 0x0100, false);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
hidpp_log_debug(&device->base, "ROM settings loaded\n");
|
||||
|
||||
return profiles->num_profiles;
|
||||
}
|
||||
|
||||
|
||||
@@ -573,16 +573,6 @@ int
|
||||
hidpp20_onboard_profiles_set_current_dpi_index(struct hidpp20_device *device,
|
||||
uint8_t index);
|
||||
|
||||
/**
|
||||
* parse a given profile from the mouse and fill in the right profile in
|
||||
* profiles_list.
|
||||
*
|
||||
* return 0 or a negative error.
|
||||
*/
|
||||
int hidpp20_onboard_profiles_read(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
struct hidpp20_profiles *profiles_list);
|
||||
|
||||
int hidpp20_onboard_profiles_write(struct hidpp20_device *device,
|
||||
unsigned int index,
|
||||
struct hidpp20_profiles *profiles_list);
|
||||
|
||||
Reference in New Issue
Block a user