From fd0e12c5353fd90fd9682ef7485905aa4d0a7ca1 Mon Sep 17 00:00:00 2001 From: darkymtp Date: Sat, 23 Dec 2023 11:37:32 +0100 Subject: [PATCH] Add support for Logitech G Pro X 2 --- README.md | 2 ++ src/device_registry.c | 4 ++- src/devices/CMakeLists.txt | 2 ++ src/devices/logitech_gpro_x2.c | 54 ++++++++++++++++++++++++++++++++++ src/devices/logitech_gpro_x2.h | 3 ++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/devices/logitech_gpro_x2.c create mode 100644 src/devices/logitech_gpro_x2.h diff --git a/README.md b/README.md index e92e182..97e2bfa 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ talking. This differs from a simple loopback via PulseAudio as you won't have an - Sidetone, Battery, Inactive time - Logitech G PRO - Sidetone, Battery, Inactive time +- Logitech G PRO X 2 + - Sidetone, Inactive time - Logitech Zone Wired/Zone 750 - Sidetone, Voice prompts, Rotate to mute - Roccat Elo 7.1 Air diff --git a/src/device_registry.c b/src/device_registry.c index 0cf1758..279d629 100644 --- a/src/device_registry.c +++ b/src/device_registry.c @@ -10,6 +10,7 @@ #include "devices/logitech_g633_g933_935.h" #include "devices/logitech_g930.h" #include "devices/logitech_gpro.h" +#include "devices/logitech_gpro_x2.h" #include "devices/logitech_zone_wired.h" #include "devices/roccat_elo_7_1_air.h" #include "devices/roccat_elo_7_1_usb.h" @@ -23,7 +24,7 @@ #include -#define NUMDEVICES 20 +#define NUMDEVICES 21 // array of pointers to device static struct device*(devicelist[NUMDEVICES]); @@ -50,6 +51,7 @@ void init_devices() arctis_nova_7_init(&devicelist[17]); calphaw_init(&devicelist[18]); arctis_nova_pro_wireless_init(&devicelist[19]); + gpro_x2_init(&devicelist[20]); } int get_device(struct device* device_found, uint16_t idVendor, uint16_t idProduct) diff --git a/src/devices/CMakeLists.txt b/src/devices/CMakeLists.txt index 2673bf2..427cd73 100644 --- a/src/devices/CMakeLists.txt +++ b/src/devices/CMakeLists.txt @@ -39,4 +39,6 @@ set(SOURCE_FILES ${SOURCE_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/logitech_gpro.h ${CMAKE_CURRENT_SOURCE_DIR}/logitech_zone_wired.c ${CMAKE_CURRENT_SOURCE_DIR}/logitech_zone_wired.h + ${CMAKE_CURRENT_SOURCE_DIR}/logitech_gpro_x2.c + ${CMAKE_CURRENT_SOURCE_DIR}/logitech_gpro_x2.h PARENT_SCOPE) diff --git a/src/devices/logitech_gpro_x2.c b/src/devices/logitech_gpro_x2.c new file mode 100644 index 0000000..e840bca --- /dev/null +++ b/src/devices/logitech_gpro_x2.c @@ -0,0 +1,54 @@ +#include + +#include +#include +#include + +#include "../device.h" +#include "../utility.h" +#include "logitech.h" + +static struct device device_gpro_x2; + +#define ID_LOGITECH_PRO_X2 0x0af7 + +static const uint16_t PRODUCT_IDS[] = { + ID_LOGITECH_PRO_X2, +}; + +static int gpro_x2_send_sidetone(hid_device* device_handle, uint8_t num); +static int gpro_x2_send_inactive_time(hid_device* device_handle, uint8_t num); + +void gpro_x2_init(struct device** device) +{ + device_gpro_x2.idVendor = VENDOR_LOGITECH; + device_gpro_x2.idProductsSupported = PRODUCT_IDS; + device_gpro_x2.numIdProducts = sizeof(PRODUCT_IDS) / sizeof(PRODUCT_IDS[0]); + + strncpy(device_gpro_x2.device_name, "Logitech G PRO X 2", sizeof(device_gpro_x2.device_name)); + + device_gpro_x2.capabilities = B(CAP_SIDETONE) | B(CAP_INACTIVE_TIME); + device_gpro_x2.capability_details[CAP_SIDETONE] = (struct capability_detail) { .usagepage = 0xffa0, .usageid = 0x1, .interface = 3 }; + device_gpro_x2.capability_details[CAP_INACTIVE_TIME] = (struct capability_detail) { .usagepage = 0xffa0, .usageid = 0x1, .interface = 3 }; + + device_gpro_x2.send_sidetone = &gpro_x2_send_sidetone; + device_gpro_x2.send_inactive_time = &gpro_x2_send_inactive_time; + + *device = &device_gpro_x2; +} + +static int gpro_x2_send_sidetone(hid_device* device_handle, uint8_t num) +{ + num = map(num, 0, 128, 0, 100); + + uint8_t sidetone_data[12] = { 0x51, 0x0a, 0x00, 0x03, 0x1b, 0x00, 0x05, 0x00, 0x07, 0x1b, 0x01, num }; + + return hid_write(device_handle, sidetone_data, sizeof(sidetone_data) / sizeof(sidetone_data[0])); +} + +static int gpro_x2_send_inactive_time(hid_device* device_handle, uint8_t num) +{ + uint8_t inactive_time_data[11] = { 0x51, 0x09, 0x00, 0x03, 0x1c, 0x00, 0x04, 0x00, 0x06, 0x1d, num }; + + return hid_write(device_handle, inactive_time_data, sizeof(inactive_time_data) / sizeof(inactive_time_data[0])); +} \ No newline at end of file diff --git a/src/devices/logitech_gpro_x2.h b/src/devices/logitech_gpro_x2.h new file mode 100644 index 0000000..21652ac --- /dev/null +++ b/src/devices/logitech_gpro_x2.h @@ -0,0 +1,3 @@ +#pragma once + +void gpro_x2_init(struct device** device);