mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
hidpp10: implement enable/disable profiles
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
committed by
Peter Hutterer
parent
d5ccaed457
commit
ced958f135
102
src/hidpp10.c
102
src/hidpp10.c
@@ -714,6 +714,71 @@ hidpp10_get_dpi_value(struct hidpp10_device *dev, uint8_t raw_value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp10_write_profile_directory(struct hidpp10_device *dev)
|
||||
{
|
||||
unsigned int i, index;
|
||||
int res;
|
||||
uint8_t bytes[HIDPP10_PAGE_SIZE];
|
||||
struct hidpp10_directory *directory = (struct hidpp10_directory *)bytes;
|
||||
uint16_t crc;
|
||||
|
||||
if (dev->profile_type == HIDPP10_PROFILE_UNKNOWN) {
|
||||
hidpp_log_debug(&dev->base, "no profile type given\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(bytes, 0xff, sizeof(bytes));
|
||||
|
||||
index = 0;
|
||||
for (i = 0; i < dev->profile_count; i++) {
|
||||
if (!dev->profiles[i].enabled)
|
||||
continue;
|
||||
|
||||
directory[index].page = dev->profiles[i].page;
|
||||
directory[index].offset = dev->profiles[i].offset;
|
||||
directory[index].led_mask = ((0b111 << index) >> 2) & 0b111;
|
||||
++index;
|
||||
}
|
||||
|
||||
crc = hidpp_crc_ccitt(bytes, HIDPP10_PAGE_SIZE - 2);
|
||||
hidpp_set_unaligned_be_u16(&bytes[HIDPP10_PAGE_SIZE - 2], crc);
|
||||
|
||||
res = hidpp10_send_hot_payload(dev,
|
||||
0x00, 0x0000, /* destination: RAM */
|
||||
bytes,
|
||||
HIDPP10_PAGE_SIZE / 2);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = hidpp10_erase_memory(dev, 0x01);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = hidpp10_write_flash(dev,
|
||||
0x00, 0x0000,
|
||||
0x01, 0x0000,
|
||||
HIDPP10_PAGE_SIZE / 2);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = hidpp10_send_hot_payload(dev,
|
||||
0x00, 0x0000, /* destination: RAM */
|
||||
bytes + HIDPP10_PAGE_SIZE / 2,
|
||||
HIDPP10_PAGE_SIZE / 2);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = hidpp10_write_flash(dev,
|
||||
0x00, 0x0000,
|
||||
0x01, HIDPP10_PAGE_SIZE / 2,
|
||||
HIDPP10_PAGE_SIZE / 2);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hidpp10_read_profile_directory(struct hidpp10_device *dev)
|
||||
{
|
||||
@@ -1422,8 +1487,20 @@ hidpp10_read_profile(struct hidpp10_device *dev, uint8_t number)
|
||||
}
|
||||
|
||||
profile = &dev->profiles[number];
|
||||
if (!profile->enabled)
|
||||
return 0;
|
||||
if (!profile->page) {
|
||||
unsigned long pages = 0xffff;
|
||||
unsigned int i;
|
||||
|
||||
/* pages 0 and 1 are ROM and directory so they are reserved */
|
||||
long_clear_bit(&pages, 0);
|
||||
long_clear_bit(&pages, 1);
|
||||
|
||||
for (i = 0; i < dev->profile_count; i++)
|
||||
long_clear_bit(&pages, dev->profiles[i].page);
|
||||
|
||||
page = ffsl(pages) - 1;
|
||||
profile->page = page;
|
||||
}
|
||||
|
||||
switch (dev->profile_type) {
|
||||
case HIDPP10_PROFILE_G500:
|
||||
@@ -1448,9 +1525,10 @@ hidpp10_read_profile(struct hidpp10_device *dev, uint8_t number)
|
||||
* if the CRC is wrong, the mouse still handles the
|
||||
* profile. Warn the user.
|
||||
*/
|
||||
hidpp_log_info(&dev->base,
|
||||
"Profile %d has a wrong CRC, assuming valid.\n",
|
||||
number);
|
||||
if (profile->enabled)
|
||||
hidpp_log_info(&dev->base,
|
||||
"Profile %d has a wrong CRC, assuming valid.\n",
|
||||
number);
|
||||
res = 0;
|
||||
}
|
||||
if (res)
|
||||
@@ -1635,7 +1713,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_p
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* we do not support not enabled profiles just now */
|
||||
/* something went wrong */
|
||||
if (!profile->page)
|
||||
return -ENOTSUP;
|
||||
|
||||
@@ -1692,7 +1770,7 @@ hidpp10_set_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_p
|
||||
break;
|
||||
case HIDPP10_PROFILE_G700:
|
||||
p700->default_dpi_mode = profile->default_dpi_mode;
|
||||
p700->usb_refresh_rate = 1000 / profile->refresh_rate;
|
||||
p700->usb_refresh_rate = profile->refresh_rate ? 1000 / profile->refresh_rate : 0;
|
||||
|
||||
hidpp10_write_dpi_modes_8_dual(dev, profile, p700->dpi_modes, PROFILE_NUM_DPI_MODES);
|
||||
hidpp10_write_buttons(dev, profile, buttons, PROFILE_NUM_BUTTONS);
|
||||
@@ -1734,6 +1812,13 @@ hidpp10_set_profile(struct hidpp10_device *dev, uint8_t number, struct hidpp10_p
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
if (profile->enabled != dev->profiles[number].enabled) {
|
||||
dev->profiles[number].enabled = profile->enabled;
|
||||
res = hidpp10_write_profile_directory(dev);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
res = hidpp10_send_hot_payload(dev,
|
||||
0x00, 0x0000, /* destination: RAM */
|
||||
page_data,
|
||||
@@ -2102,6 +2187,9 @@ hidpp10_get_usb_refresh_rate(struct hidpp10_device *dev,
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (!refresh.msg.parameters[0])
|
||||
return -EINVAL;
|
||||
|
||||
*rate = 1000/refresh.msg.parameters[0];
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user