From fe8c850fe4f833ddac4a52f28ddf4298b31df120 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 11 Dec 2015 15:35:22 +0100 Subject: [PATCH] hidpp10: implement set current profile Signed-off-by: Benjamin Tissoires --- src/driver-hidpp10.c | 5 +++- src/hidpp10.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ src/hidpp10.h | 3 +++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/driver-hidpp10.c b/src/driver-hidpp10.c index 4c7f57e1..b6cb3732 100644 --- a/src/driver-hidpp10.c +++ b/src/driver-hidpp10.c @@ -194,7 +194,10 @@ hidpp10drv_has_capability(const struct ratbag_device *device, static int hidpp10drv_set_current_profile(struct ratbag_device *device, unsigned int index) { - return -ENOTSUP; + struct hidpp10drv_data *drv_data = ratbag_get_drv_data(device); + struct hidpp10_device *hidpp10 = drv_data->dev; + + return hidpp10_set_current_profile(hidpp10, index); } static int diff --git a/src/hidpp10.c b/src/hidpp10.c index d1be5165..0857c9d6 100644 --- a/src/hidpp10.c +++ b/src/hidpp10.c @@ -760,6 +760,60 @@ hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile) return -ENAVAIL; } +static int +hidpp10_set_internal_current_profile(struct hidpp10_device *dev, + int16_t current_profile, + uint8_t profile_type) +{ + unsigned idx = dev->index; + union hidpp10_message profile = CMD_PROFILE(idx, SET_REGISTER_REQ); + int8_t page, offset; + struct hidpp10_directory directory[16]; /* completely random profile count */ + int count = 0; + + hidpp_log_raw(&dev->base, "Fetching the profiles' directory\n"); + + count = hidpp10_get_profile_directory(dev, directory, + ARRAY_LENGTH(directory)); + if (count < 0) + return count; + + hidpp_log_raw(&dev->base, "Setting current profile\n"); + + profile.msg.parameters[0] = profile_type; + + switch (profile_type) { + case PROFILE_TYPE_INDEX: + if (current_profile > count) + return -EINVAL; + profile.msg.parameters[1] = current_profile & 0xFF; + break; + case PROFILE_TYPE_ADDRESS: + page = current_profile >> 8; + offset = current_profile & 0xFF; + profile.msg.parameters[1] = page; + profile.msg.parameters[2] = offset; + break; + case PROFILE_TYPE_FACTORY: + break; + default: + hidpp_log_error(&dev->base, + "Unexpected value: %02x\n", + profile_type); + return -EINVAL; + } + + return hidpp10_request_command(dev, &profile); +} + +int +hidpp10_set_current_profile(struct hidpp10_device *dev, int16_t current_profile) +{ + return hidpp10_set_internal_current_profile(dev, + current_profile, + PROFILE_TYPE_INDEX); +} + static void hidpp10_fill_dpi_modes_8(struct hidpp10_device *dev, struct hidpp10_profile *profile, diff --git a/src/hidpp10.h b/src/hidpp10.h index 5e19665f..3570763e 100644 --- a/src/hidpp10.h +++ b/src/hidpp10.h @@ -435,6 +435,9 @@ hidpp10_get_profile_directory(struct hidpp10_device *dev, int hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile); +int +hidpp10_set_current_profile(struct hidpp10_device *dev, int16_t current_profile); + int hidpp10_get_profile(struct hidpp10_device *dev, int8_t number, struct hidpp10_profile *profile);