From 7a1af0854a6c61d02ca919089c83c43b3ef8037a Mon Sep 17 00:00:00 2001 From: morg Date: Fri, 30 Dec 2022 23:04:29 +0000 Subject: [PATCH] Initial commit for Lenovo motherboards - #2999 --- .../LenovoMotherboardController.cpp | 90 ++++++++ .../LenovoMotherboardController.h | 57 +++++ .../LenovoMotherboardControllerDetect.cpp | 33 +++ .../RGBController_LenovoMotherboard.cpp | 203 ++++++++++++++++++ .../RGBController_LenovoMotherboard.h | 32 +++ OpenRGB.pro | 6 + 6 files changed, 421 insertions(+) create mode 100644 Controllers/LenovoMotherboardController/LenovoMotherboardController.cpp create mode 100644 Controllers/LenovoMotherboardController/LenovoMotherboardController.h create mode 100644 Controllers/LenovoMotherboardController/LenovoMotherboardControllerDetect.cpp create mode 100644 Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.cpp create mode 100644 Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.h diff --git a/Controllers/LenovoMotherboardController/LenovoMotherboardController.cpp b/Controllers/LenovoMotherboardController/LenovoMotherboardController.cpp new file mode 100644 index 00000000..36eeae62 --- /dev/null +++ b/Controllers/LenovoMotherboardController/LenovoMotherboardController.cpp @@ -0,0 +1,90 @@ +/*-----------------------------------------*\ +| LenovoMotherboardController.cpp | +| | +| Driver for Lenovo motherboards lighting | +| controller | +| | +| Guimard Morgan (morg) 12/26/2022 | +\*-----------------------------------------*/ +#include "LenovoMotherboardController.h" +#include + +LenovoMotherboardController::LenovoMotherboardController(hid_device* dev_handle, const hid_device_info& info) +{ + dev = dev_handle; + location = info.path; + version = ""; + + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + serial_number = ""; + } + else + { + std::wstring return_wstring = serial_string; + serial_number = std::string(return_wstring.begin(), return_wstring.end()); + } +} + +LenovoMotherboardController::~LenovoMotherboardController() +{ + hid_close(dev); +} + +std::string LenovoMotherboardController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string LenovoMotherboardController::GetSerialString() +{ + return(serial_number); +} + +std::string LenovoMotherboardController::GetFirmwareVersion() +{ + return(version); +} + +void LenovoMotherboardController::SetMode(uint8_t zone, uint8_t mode, uint8_t brightness, uint8_t speed, RGBColor color) +{ + uint8_t r = RGBGetRValue(color); + uint8_t g = RGBGetGValue(color); + uint8_t b = RGBGetBValue(color); + + uint8_t buffer[LENOVO_MB_PACKET_LENGTH]; + memset(buffer, 0x00, LENOVO_MB_PACKET_LENGTH); + + buffer[0] = LENOVO_MB_REPORT_ID; + + buffer[1] = zone; + buffer[2] = mode; + buffer[3] = speed; + buffer[4] = brightness; + + buffer[5] = r; + buffer[6] = g; + buffer[7] = b; + + hid_send_feature_report(dev, buffer, LENOVO_MB_PACKET_LENGTH); + + memset(buffer, 0x00, LENOVO_MB_PACKET_LENGTH); + + buffer[0] = LENOVO_MB_REPORT_ID; + buffer[1] = 0x28; + buffer[2] = 0x06; + + buffer[33] = zone; + buffer[34] = mode; + buffer[35] = speed; + buffer[36] = brightness; + + buffer[37] = r; + buffer[38] = g; + buffer[39] = b; + + hid_send_feature_report(dev, buffer, LENOVO_MB_PACKET_LENGTH); +} diff --git a/Controllers/LenovoMotherboardController/LenovoMotherboardController.h b/Controllers/LenovoMotherboardController/LenovoMotherboardController.h new file mode 100644 index 00000000..1f0d4381 --- /dev/null +++ b/Controllers/LenovoMotherboardController/LenovoMotherboardController.h @@ -0,0 +1,57 @@ +/*-----------------------------------------*\ +| LenovoMotherboardController.cpp | +| | +| Driver for Lenovo motherboards lighting | +| controller - header file | +| | +| Guimard Morgan (morg) 12/26/2022 | +\*-----------------------------------------*/ +#pragma once + +#include +#include +#include "RGBController.h" + +#define LENOVO_MB_PACKET_LENGTH 64 +#define LENOVO_MB_REPORT_ID 0xCC +#define LENOVO_MB_NUMBER_OF_LEDS 2 +#define LENOVO_MB_ZONE_1_VALUE 0x12 +#define LENOVO_MB_ZONE_2_VALUE 0x11 + +enum +{ + LENOVO_MB_STATIC_MODE = 0x01, + LENOVO_MB_SPARKLE_MODE = 0x02, + LENOVO_MB_BREATHING_MODE = 0x03, + LENOVO_MB_WAVE_MODE = 0x04, + LENOVO_MB_SPECTER_MODE = 0x06, + LENOVO_MB_RAINBOW_WAVE_MODE = 0x09, + LENOVO_MB_RANDOM_MODE = 0x0A +}; + +enum +{ + LENOVO_MB_BRIGHTNESS_MIN = 1, + LENOVO_MB_BRIGHTNESS_MAX = 4, + LENOVO_MB_SPEED_MIN = 1, + LENOVO_MB_SPEED_MAX = 4, +}; + +class LenovoMotherboardController +{ +public: + LenovoMotherboardController(hid_device* dev_handle, const hid_device_info& info); + ~LenovoMotherboardController(); + + std::string GetSerialString(); + std::string GetDeviceLocation(); + std::string GetFirmwareVersion(); + + void SetMode(uint8_t zone, uint8_t mode, uint8_t brightness, uint8_t speed, RGBColor color); + +private: + hid_device* dev; + std::string location; + std::string serial_number; + std::string version; +}; diff --git a/Controllers/LenovoMotherboardController/LenovoMotherboardControllerDetect.cpp b/Controllers/LenovoMotherboardController/LenovoMotherboardControllerDetect.cpp new file mode 100644 index 00000000..92ca1385 --- /dev/null +++ b/Controllers/LenovoMotherboardController/LenovoMotherboardControllerDetect.cpp @@ -0,0 +1,33 @@ +#include "Detector.h" +#include "LenovoMotherboardController.h" +#include "RGBController.h" +#include "RGBController_LenovoMotherboard.h" +#include "dependencies/dmiinfo.h" + +/*---------------------------------------------------------*\ +| vendor ID | +\*---------------------------------------------------------*/ +#define LENOVO_MB_VID 0x17EF + +/*---------------------------------------------------------*\ +| Product ID | +\*---------------------------------------------------------*/ +#define LENOVO_MB_PID 0xC955 + +void DetectLenovoMotherboardControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + DMIInfo dmi; + + LenovoMotherboardController* controller = new LenovoMotherboardController(dev, *info); + RGBController_LenovoMotherboard* rgb_controller = new RGBController_LenovoMotherboard(controller); + rgb_controller->name = name + " " + dmi.getMainboard(); + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_HID_DETECTOR_PU("Lenovo", DetectLenovoMotherboardControllers, LENOVO_MB_VID, LENOVO_MB_PID, 0xFF89, 0xCC); diff --git a/Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.cpp b/Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.cpp new file mode 100644 index 00000000..1146c58a --- /dev/null +++ b/Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.cpp @@ -0,0 +1,203 @@ +/*-----------------------------------------*\ +| RGBController_LenovoMotherboard.h | +| | +| Generic RGB Interface for OpenRGB | +| Lenovo motherboards RGB USB Driver | +| | +| Guimard Morgan (morg) 12/26/2022 | +\*-----------------------------------------*/ + +#include "RGBController_LenovoMotherboard.h" + +#include +#include + +/**------------------------------------------------------------------*\ + @name LenovoMotherboard mouse + @category Motherboard + @type USB + @save :x: + @direct :x: + @effects :white_check_mark: + @detectors DetectLenovoMotherboardControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_LenovoMotherboard::RGBController_LenovoMotherboard(LenovoMotherboardController* controller_ptr) +{ + controller = controller_ptr; + name = "Lenovo motherboard"; + vendor = "Lenovo"; + type = DEVICE_TYPE_MOTHERBOARD; + description = name; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + version = controller->GetFirmwareVersion(); + + mode Static; + Static.name = "Static"; + Static.value = LENOVO_MB_STATIC_MODE; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; + Static.color_mode = MODE_COLORS_PER_LED; + Static.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Static.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Static.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Static.speed = LENOVO_MB_SPEED_MIN; + modes.push_back(Static); + + mode Sparkle; + Sparkle.name = "Sparkle"; + Sparkle.value = LENOVO_MB_SPARKLE_MODE; + Sparkle.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Sparkle.color_mode = MODE_COLORS_PER_LED; + Sparkle.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Sparkle.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Sparkle.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Sparkle.speed = LENOVO_MB_SPEED_MIN; + Sparkle.speed_max = LENOVO_MB_SPEED_MAX; + Sparkle.speed_min = LENOVO_MB_SPEED_MIN; + modes.push_back(Sparkle); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = LENOVO_MB_BREATHING_MODE; + Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Breathing.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Breathing.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Breathing.speed = LENOVO_MB_SPEED_MIN; + Breathing.speed_max = LENOVO_MB_SPEED_MAX; + Breathing.speed_min = LENOVO_MB_SPEED_MIN; + modes.push_back(Breathing); + + mode Wave; + Wave.name = "Wave"; + Wave.value = LENOVO_MB_WAVE_MODE; + Wave.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Wave.color_mode = MODE_COLORS_NONE; + Wave.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Wave.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Wave.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Wave.speed = LENOVO_MB_SPEED_MIN; + Wave.speed_max = LENOVO_MB_SPEED_MAX; + Wave.speed_min = LENOVO_MB_SPEED_MIN; + modes.push_back(Wave); + + mode Specter; + Specter.name = "Specter"; + Specter.value = LENOVO_MB_SPECTER_MODE; + Specter.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Specter.color_mode = MODE_COLORS_PER_LED; + Specter.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Specter.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Specter.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Specter.speed = LENOVO_MB_SPEED_MIN; + Specter.speed_max = LENOVO_MB_SPEED_MAX; + Specter.speed_min = LENOVO_MB_SPEED_MIN; + modes.push_back(Specter); + + mode Rainbow; + Rainbow.name = "Rainbow wave"; + Rainbow.value = LENOVO_MB_RAINBOW_WAVE_MODE; + Rainbow.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Rainbow.color_mode = MODE_COLORS_NONE; + Rainbow.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Rainbow.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Rainbow.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Rainbow.speed = LENOVO_MB_SPEED_MIN; + Rainbow.speed_max = LENOVO_MB_SPEED_MAX; + Rainbow.speed_min = LENOVO_MB_SPEED_MIN; + modes.push_back(Rainbow); + + mode Random; + Random.name = "Random"; + Random.value = LENOVO_MB_RANDOM_MODE; + Random.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Random.color_mode = MODE_COLORS_NONE; + Random.brightness_min = LENOVO_MB_BRIGHTNESS_MIN; + Random.brightness_max = LENOVO_MB_BRIGHTNESS_MAX; + Random.brightness = LENOVO_MB_BRIGHTNESS_MAX; + Random.speed = LENOVO_MB_SPEED_MIN; + Random.speed_max = LENOVO_MB_SPEED_MAX; + Random.speed_min = LENOVO_MB_SPEED_MIN; + modes.push_back(Random); + + SetupZones(); +} + +RGBController_LenovoMotherboard::~RGBController_LenovoMotherboard() +{ + delete controller; +} + +void RGBController_LenovoMotherboard::SetupZones() +{ + zone cpu_fan_zone; + + cpu_fan_zone.name = "CPU FAN Zone"; + cpu_fan_zone.type = ZONE_TYPE_SINGLE; + cpu_fan_zone.leds_min = 1; + cpu_fan_zone.leds_max = 1; + cpu_fan_zone.leds_count = 1; + cpu_fan_zone.matrix_map = nullptr; + + zones.emplace_back(cpu_fan_zone); + + zone rear_fan_zone; + + rear_fan_zone.name = "Rear FAN Zone"; + rear_fan_zone.type = ZONE_TYPE_SINGLE; + rear_fan_zone.leds_min = 1; + rear_fan_zone.leds_max = 1; + rear_fan_zone.leds_count = 1; + rear_fan_zone.matrix_map = nullptr; + + zones.emplace_back(rear_fan_zone); + + leds.resize(LENOVO_MB_NUMBER_OF_LEDS); + + leds[0].name = "LED 1"; + leds[0].value = LENOVO_MB_ZONE_1_VALUE; + + leds[1].name = "LED 2"; + leds[1].value = LENOVO_MB_ZONE_2_VALUE; + + SetupColors(); +} + +void RGBController_LenovoMotherboard::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_LenovoMotherboard::DeviceUpdateLEDs() +{ + for(uint8_t i = 0; i < leds.size(); i++) + { + controller->SetMode( + leds[i].value, + modes[active_mode].value, + modes[active_mode].brightness, + modes[active_mode].speed, + colors[i] + ); + } +} + +void RGBController_LenovoMotherboard::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_LenovoMotherboard::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_LenovoMotherboard::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} diff --git a/Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.h b/Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.h new file mode 100644 index 00000000..7f312a5d --- /dev/null +++ b/Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.h @@ -0,0 +1,32 @@ +/*-----------------------------------------*\ +| RGBController_LenovoMotherboard.h | +| | +| Generic RGB Interface for OpenRGB | +| Lenovo motherboards RGB USB Driver | +| | +| Guimard Morgan (morg) 12/26/2022 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "LenovoMotherboardController.h" + +class RGBController_LenovoMotherboard : public RGBController +{ +public: + RGBController_LenovoMotherboard(LenovoMotherboardController* controller_ptr); + ~RGBController_LenovoMotherboard(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + LenovoMotherboardController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 3c0f84fe..2e8df187 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -132,6 +132,7 @@ INCLUDEPATH += Controllers/IntelArcA770LEController/ \ Controllers/LEDStripController/ \ Controllers/LenovoControllers/ \ + Controllers/LenovoMotherboardController/ \ Controllers/LianLiController/ \ Controllers/LIFXController/ \ Controllers/LogitechController/ \ @@ -457,6 +458,8 @@ HEADERS += Controllers/LenovoControllers/LenovoDevices.h \ Controllers/LenovoControllers/LenovoUSBController.h \ Controllers/LenovoControllers/RGBController_LenovoUSB.h \ + Controllers/LenovoMotherboardController/LenovoMotherboardController.h \ + Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.h \ Controllers/LexipMouseController/LexipMouseController.h \ Controllers/LexipMouseController/RGBController_LexipMouse.h \ Controllers/LIFXController/LIFXController.h \ @@ -1028,6 +1031,9 @@ SOURCES += Controllers/LenovoControllers/LenovoUSBController.cpp \ Controllers/LenovoControllers/LenovoUSBDetect.cpp \ Controllers/LenovoControllers/RGBController_LenovoUSB.cpp \ + Controllers/LenovoMotherboardController/LenovoMotherboardController.cpp \ + Controllers/LenovoMotherboardController/LenovoMotherboardControllerDetect.cpp \ + Controllers/LenovoMotherboardController/RGBController_LenovoMotherboard.cpp \ Controllers/LexipMouseController/LexipMouseController.cpp \ Controllers/LexipMouseController/LexipMouseControllerDetect.cpp \ Controllers/LexipMouseController/RGBController_LexipMouse.cpp \