From 92f7fe7dc4bb8fa6f3485f8ff001b4e842543015 Mon Sep 17 00:00:00 2001 From: santeri3700 Date: Sat, 1 Aug 2020 21:19:13 +0300 Subject: [PATCH] Add support for Holtek USB Gaming Mouse --- .../HoltekController/HoltekA070Controller.cpp | 87 ++++++++++++++++++ .../HoltekController/HoltekA070Controller.h | 44 +++++++++ .../HoltekControllerDetect.cpp | 86 ++++++++++++++++++ RGBController/RGBController_HoltekA070.cpp | 90 +++++++++++++++++++ RGBController/RGBController_HoltekA070.h | 30 +++++++ 5 files changed, 337 insertions(+) create mode 100644 Controllers/HoltekController/HoltekA070Controller.cpp create mode 100644 Controllers/HoltekController/HoltekA070Controller.h create mode 100644 Controllers/HoltekController/HoltekControllerDetect.cpp create mode 100644 RGBController/RGBController_HoltekA070.cpp create mode 100644 RGBController/RGBController_HoltekA070.h diff --git a/Controllers/HoltekController/HoltekA070Controller.cpp b/Controllers/HoltekController/HoltekA070Controller.cpp new file mode 100644 index 00000000..ebf2fd94 --- /dev/null +++ b/Controllers/HoltekController/HoltekA070Controller.cpp @@ -0,0 +1,87 @@ +/*-----------------------------------------------*\ +| HoltekA070Controller.cpp | +| | +| Driver for Holtek USB Gaming Mouse [04d9:a070] | +| | +| Santeri Pikarinen (santeri3700) 8/01/2020 | +\*-----------------------------------------------*/ + +#include "HoltekA070Controller.h" + +#include + +HoltekA070Controller::HoltekA070Controller(hid_device* dev_handle) +{ + dev = dev_handle; +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void HoltekA070Controller::SendCustomColor + ( + unsigned char red, + unsigned char green, + unsigned char blue + ) +{ + char usb_buf[8]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up RGB Control packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x07; // PACKET SIZE? + usb_buf[0x01] = 0x0a; // SET RGB + usb_buf[0x02] = 0x00; // SAVE (does not work with SET RGB) + usb_buf[0x03] = red; // RED + usb_buf[0x04] = green; // GREEN + usb_buf[0x05] = blue; // BLUE + usb_buf[0x06] = 0x00; // PADDING? + usb_buf[0x07] = 0x00; // PADDING? + + // So far no saving function has been discovered for the "SET RGB" command. + // Such functionality might not even exist for the A070 series. + // The chosen RGB color will therefore reset after a power cycle. + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, (unsigned char *)usb_buf, sizeof(usb_buf)); +} + +void HoltekA070Controller::SendMode + ( + unsigned char mode + ) +{ + + char usb_buf[8]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up lighting mode control packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x07; // PACKET SIZE? + usb_buf[0x01] = 0x0b; // SET LIGHTING MODE + usb_buf[0x02] = 0x01; // SAVE + usb_buf[0x03] = mode; // MODE 01-04 + usb_buf[0x04] = 0x00; // PADDING? + usb_buf[0x05] = 0x00; // PADDING? + usb_buf[0x06] = 0x00; // PADDING? + usb_buf[0x07] = 0x00; // PADDING? + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_send_feature_report(dev, (unsigned char *)usb_buf, sizeof(usb_buf)); +} diff --git a/Controllers/HoltekController/HoltekA070Controller.h b/Controllers/HoltekController/HoltekA070Controller.h new file mode 100644 index 00000000..8bd6998c --- /dev/null +++ b/Controllers/HoltekController/HoltekA070Controller.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------*\ +| HoltekA070Controller.h | +| | +| Definitions and types for Holtek USB Gaming Mouse [04d9:a070] | +| | +| Santeri Pikarinen (santeri3700) 8/01/2020 | +\*---------------------------------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +enum +{ + HOLTEK_A070_MODE_STATIC = 0x01, + HOLTEK_A070_MODE_BREATHING_SLOW = 0x02, + HOLTEK_A070_MODE_BREATHING_MEDIUM = 0x03, + HOLTEK_A070_MODE_BREATHING_FAST = 0x04 +}; + +class HoltekA070Controller +{ +public: + HoltekA070Controller(hid_device* dev_handle); + ~HoltekA070Controller(); + + void SendCustomColor + ( + unsigned char red, + unsigned char green, + unsigned char blue + ); + + void SendMode + ( + unsigned char mode + ); + +private: + hid_device* dev; +}; diff --git a/Controllers/HoltekController/HoltekControllerDetect.cpp b/Controllers/HoltekController/HoltekControllerDetect.cpp new file mode 100644 index 00000000..8786ff89 --- /dev/null +++ b/Controllers/HoltekController/HoltekControllerDetect.cpp @@ -0,0 +1,86 @@ +#include "HoltekA070Controller.h" +#include "RGBController.h" +#include "RGBController_HoltekA070.h" +#include +#include + +/*-----------------------------------------------------*\ +| Holtek Semiconductor Inc. vendor ID | +\*-----------------------------------------------------*/ +#define HOLTEK_VID 0x04D9 +/*-----------------------------------------------------*\ +| Mouse product IDs | +\*-----------------------------------------------------*/ +#define HOLTEK_A070_PID 0xA070 + +typedef struct +{ + unsigned short usb_vid; + unsigned short usb_pid; + unsigned char usb_interface; + device_type type; + const char * name; +} holtek_device; + +#define HOLTEK_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ])) + +static const holtek_device device_list[] = +{ + /*-------------------------------------------------------------------------------------------------------------*\ + | Mice | + \*-------------------------------------------------------------------------------------------------------------*/ + { HOLTEK_VID, HOLTEK_A070_PID, 1, DEVICE_TYPE_MOUSE, "Holtek USB Gaming Mouse" }, +}; + +void DetectHoltekControllers(std::vector& rgb_controllers) +{ + hid_init(); + + for(int device_idx = 0; device_idx < HOLTEK_NUM_DEVICES; device_idx++) + { + switch(device_list[device_idx].type) + { + case DEVICE_TYPE_MOUSE: + { + hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid); + + while(info) + { + if((info->vendor_id == device_list[device_idx].usb_vid) + &&(info->product_id == device_list[device_idx].usb_pid) +#ifdef USE_HID_USAGE + &&(info->interface_number == device_list[device_idx].usb_interface) + &&(info->usage_page == 0xFF00) + &&(info->usage == 2)) +#else + &&(info->interface_number == device_list[device_idx].usb_interface)) +#endif + { + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + switch(device_list[device_idx].usb_pid) + { + case HOLTEK_A070_PID: + { + HoltekA070Controller* controller = new HoltekA070Controller(dev); + + RGBController_HoltekA070* rgb_controller = new RGBController_HoltekA070(controller); + + rgb_controller->name = device_list[device_idx].name; + rgb_controllers.push_back(rgb_controller); + } + break; + } + } + } + info = info->next; + } + hid_free_enumeration(info); + } + break; + } + + } +} \ No newline at end of file diff --git a/RGBController/RGBController_HoltekA070.cpp b/RGBController/RGBController_HoltekA070.cpp new file mode 100644 index 00000000..401f4c4d --- /dev/null +++ b/RGBController/RGBController_HoltekA070.cpp @@ -0,0 +1,90 @@ +/*--------------------------------------------------------------*\ +| RGBController_HoltekA070.cpp | +| | +| Generic RGB Interface for Holtek USB Gaming Mouse [04d9:a070] | +| | +| Santeri Pikarinen (santeri3700) 8/01/2020 | +\*--------------------------------------------------------------*/ + +#include "RGBController_HoltekA070.h" + +RGBController_HoltekA070::RGBController_HoltekA070(HoltekA070Controller* holtek_ptr) +{ + holtek = holtek_ptr; + + name = "Holtek USB Gaming Mouse Device"; + type = DEVICE_TYPE_MOUSE; + description = "Holtek USB Gaming Mouse Device"; + + mode Static; + Static.name = "Static"; + Static.speed = HOLTEK_A070_MODE_STATIC; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Static.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Static); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.speed_min = HOLTEK_A070_MODE_BREATHING_SLOW; + Breathing.speed_max = HOLTEK_A070_MODE_BREATHING_FAST; + Breathing.speed = HOLTEK_A070_MODE_BREATHING_MEDIUM; + modes.push_back(Breathing); + + SetupZones(); +} + +void RGBController_HoltekA070::SetupZones() +{ + zone mouse_zone; + mouse_zone.name = "Mouse Zone"; + mouse_zone.type = ZONE_TYPE_SINGLE; + mouse_zone.leds_min = 1; + mouse_zone.leds_max = 1; + mouse_zone.leds_count = 1; + mouse_zone.matrix_map = NULL; + zones.push_back(mouse_zone); + + led mouse_led; + mouse_led.name = "All LEDs"; + leds.push_back(mouse_led); + + SetupColors(); +} + +void RGBController_HoltekA070::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_HoltekA070::DeviceUpdateLEDs() +{ + unsigned char red = RGBGetRValue(colors[0]); + unsigned char green = RGBGetGValue(colors[0]); + unsigned char blue = RGBGetBValue(colors[0]); + + holtek->SendCustomColor(red, green, blue); +} + +void RGBController_HoltekA070::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HoltekA070::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_HoltekA070::SetCustomMode() +{ + +} + +void RGBController_HoltekA070::DeviceUpdateMode() +{ + holtek->SendMode(modes[active_mode].speed); +} diff --git a/RGBController/RGBController_HoltekA070.h b/RGBController/RGBController_HoltekA070.h new file mode 100644 index 00000000..b8cf2b5a --- /dev/null +++ b/RGBController/RGBController_HoltekA070.h @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------*\ +| RGBController_HoltekA070.h | +| | +| Generic RGB Interface for Holtek USB Gaming Mouse [04d9:a070] | +| | +| Santeri Pikarinen (santeri3700) 8/01/2020 | +\*--------------------------------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "HoltekA070Controller.h" + +class RGBController_HoltekA070 : public RGBController +{ +public: + RGBController_HoltekA070(HoltekA070Controller* holtek_ptr); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + HoltekA070Controller* holtek; +};