1
0
forked from drath/libratbag

hidpp20: implement 8060 adjustable report rate

The bitmask in the 8060 report is for ms between reports. We could do all, but
really we only care about a few resolutions, anything else is too niche to
bother with.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer
2017-10-17 13:43:53 +10:00
committed by Benjamin Tissoires
parent cb4be02a56
commit f69b4d53f6
3 changed files with 100 additions and 5 deletions

View File

@@ -55,6 +55,7 @@
#define HIDPP_CAP_COLOR_LED_EFFECTS_8070 (1 << 5)
#define HIDPP_CAP_ONBOARD_PROFILES_8100 (1 << 6)
#define HIDPP_CAP_LED_SW_CONTROL_1300 (1 << 7)
#define HIDPP_CAP_ADJUSTIBLE_REPORT_RATE_8060 (1 << 8)
struct hidpp20drv_data {
struct hidpp20_device *dev;
@@ -66,6 +67,9 @@ struct hidpp20drv_data {
struct hidpp20_profiles *profiles;
union hidpp20_generic_led_zone_info led_infos;
unsigned int report_rates[4];
unsigned int num_report_rates;
unsigned int num_profiles;
unsigned int num_resolutions;
unsigned int num_buttons;
@@ -637,6 +641,37 @@ hidpp20drv_read_resolution_dpi_2201(struct ratbag_device *device)
return 0;
}
static int
hidpp20drv_read_report_rate_8060(struct ratbag_device *device)
{
struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
struct ratbag *ratbag = device->ratbag;
uint8_t bitflags_ms;
int nrates = 0;
int rc;
rc = hidpp20_adjustable_report_rate_get_report_rate_list(drv_data->dev,
&bitflags_ms);
if (rc < 0)
return rc;
/* We only care about 'standard' rates */
if (bitflags_ms & 0x80)
drv_data->report_rates[nrates++] = 125;
if (bitflags_ms & 0x8)
drv_data->report_rates[nrates++] = 250;
if (bitflags_ms & 0x2)
drv_data->report_rates[nrates++] = 500;
if (bitflags_ms & 0x1)
drv_data->report_rates[nrates++] = 1000;
drv_data->num_report_rates = nrates;
log_debug(ratbag, "device has %d report rates\n", nrates);
return 0;
}
static int
hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
{
@@ -669,7 +704,6 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
ratbag_profile_for_each_resolution(profile, res) {
struct hidpp20_sensor *sensor;
unsigned int rate = 500; /* let's assume that one is just present */
/* We only look at the first sensor. Multiple
* sensors is too niche to care about right now */
@@ -680,8 +714,6 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
ratbag_resolution_set_dpi_list_from_range(res,
sensor->dpi_min,
sensor->dpi_max);
ratbag_resolution_set_report_rate_list(res, &rate, 1);
/* FIXME: we mark all resolutions as active because
* they are from different sensors */
res->is_active = true;
@@ -690,6 +722,19 @@ hidpp20drv_read_resolution_dpi(struct ratbag_profile *profile)
return 0;
}
if (drv_data->capabilities & HIDPP_CAP_ADJUSTIBLE_REPORT_RATE_8060) {
struct ratbag_resolution *res;
rc = hidpp20drv_read_report_rate_8060(device);
if (rc < 0)
return rc;
ratbag_profile_for_each_resolution(profile, res)
ratbag_resolution_set_report_rate_list(res,
drv_data->report_rates,
drv_data->num_report_rates);
}
return 0;
}
@@ -868,7 +913,6 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile)
ratbag_profile_for_each_resolution(profile, res) {
struct hidpp20_sensor *sensor;
unsigned int rate = p->report_rate;
/* We only look at the first sensor. Multiple
* sensors is too niche to care about right now */
@@ -891,7 +935,9 @@ hidpp20drv_read_profile_8100(struct ratbag_profile *profile)
ratbag_resolution_set_dpi_list_from_range(res,
sensor->dpi_min,
sensor->dpi_max);
ratbag_resolution_set_report_rate_list(res, &rate, 1);
ratbag_resolution_set_report_rate_list(res,
drv_data->report_rates,
drv_data->num_report_rates);
}
}
@@ -995,6 +1041,14 @@ hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
}
case HIDPP_PAGE_ADJUSTABLE_REPORT_RATE: {
log_debug(ratbag, "device has adjustable report rate\n");
/* we read the profile once to get the correct number of
* supported report rates. */
rc = hidpp20drv_read_report_rate_8060(device);
if (rc < 0)
return 0; /* this is not a hard failure */
drv_data->capabilities |= HIDPP_CAP_ADJUSTIBLE_REPORT_RATE_8060;
break;
}
case HIDPP_PAGE_COLOR_LED_EFFECTS: {

View File

@@ -1317,6 +1317,40 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
return 0;
}
/* -------------------------------------------------------------------------- */
/* 0x8060 - Adjustable Report Rate */
/* -------------------------------------------------------------------------- */
#define CMD_ADJUSTABLE_REPORT_RATE_GET_REPORT_RATE_LIST 0x00
int hidpp20_adjustable_report_rate_get_report_rate_list(struct hidpp20_device *device,
uint8_t *bitflags_ms)
{
uint8_t feature_index;
int rc;
union hidpp20_message msg = {
.msg.report_id = REPORT_ID_LONG,
.msg.device_idx = device->index,
.msg.address = CMD_ADJUSTABLE_REPORT_RATE_GET_REPORT_RATE_LIST,
.msg.parameters[0] = 0,
};
feature_index = hidpp_root_get_feature_idx(device,
HIDPP_PAGE_ADJUSTABLE_REPORT_RATE);
if (feature_index == 0)
return -ENOTSUP;
msg.msg.sub_id = feature_index;
rc = hidpp20_request_command(device, &msg);
if (rc)
return rc;
*bitflags_ms = msg.msg.parameters[0];
return 0;
}
/* -------------------------------------------------------------------------- */
/* 0x8100 - Onboard Profiles */
/* -------------------------------------------------------------------------- */

View File

@@ -376,6 +376,13 @@ int hidpp20_adjustable_dpi_set_sensor_dpi(struct hidpp20_device *device,
#define HIDPP_PAGE_ADJUSTABLE_REPORT_RATE 0x8060
/**
* set the bitmap_ms to the supported report rates. Bits enabled reflect a
* supported report rate, where bit 0 equals 1ms, bit 1 2ms, bit 2 3ms, etc.
*/
int hidpp20_adjustable_report_rate_get_report_rate_list(struct hidpp20_device *device,
uint8_t *bitflags_ms);
/* -------------------------------------------------------------------------- */
/* 0x8070v4 - Color LED effects */
/* -------------------------------------------------------------------------- */