diff --git a/Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.cpp b/Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.cpp new file mode 100644 index 00000000..27c6b1eb --- /dev/null +++ b/Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.cpp @@ -0,0 +1,154 @@ +/*-----------------------------------------*\ +| RGBController_ZotacTuringGPU.cpp | +| | +| Generic RGB Interface for OpenRGB | +| ZOTAC Turing GPU Driver | +| | +| David Henry 1/07/2023 | +\*-----------------------------------------*/ + +#include "RGBController_ZotacTuringGPU.h" + +/**------------------------------------------------------------------*\ + @name ZOTAC Turing GPU + @category GPU + @type I2C + @save :white_check_mark: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectZotacTuringGPUControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_ZotacTuringGPU::RGBController_ZotacTuringGPU(ZotacTuringGPUController* controller_ptr) +{ + controller = controller_ptr; + + name = "ZOTAC GPU"; + vendor = "ZOTAC"; + description = "ZOTAC Turing-based RGB GPU Device"; + location = controller->GetDeviceLocation(); + type = DEVICE_TYPE_GPU; + + mode Direct; + Direct.name = "Direct"; + Direct.value = ZOTAC_GPU_MODE_STATIC; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Flashing; + Flashing.name = "Flashing"; + Flashing.value = ZOTAC_GPU_MODE_STROBE; + Flashing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + Flashing.speed_min = ZOTAC_GPU_SPEED_SLOWEST; + Flashing.speed_max = ZOTAC_GPU_SPEED_FASTEST; + Flashing.speed = ZOTAC_GPU_SPEED_NORMAL; + Flashing.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Flashing); + + mode Wave; + Wave.name = "Rainbow Wave"; + Wave.value = ZOTAC_GPU_MODE_WAVE; + Wave.flags = MODE_FLAG_HAS_SPEED; + Wave.speed_min = ZOTAC_GPU_SPEED_SLOWEST; + Wave.speed_max = ZOTAC_GPU_SPEED_FASTEST; + Wave.speed = ZOTAC_GPU_SPEED_NORMAL; + Wave.color_mode = MODE_COLORS_NONE; + modes.push_back(Wave); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = ZOTAC_GPU_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + Breathing.speed_min = ZOTAC_GPU_SPEED_SLOWEST; + Breathing.speed_max = ZOTAC_GPU_SPEED_FASTEST; + Breathing.speed = ZOTAC_GPU_SPEED_NORMAL; + Breathing.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Breathing); + + mode ColorCycle; + ColorCycle.name = "Spectrum Cycle"; + ColorCycle.value = ZOTAC_GPU_MODE_COLOR_CYCLE; + ColorCycle.flags = MODE_FLAG_HAS_SPEED; + ColorCycle.speed_min = ZOTAC_GPU_SPEED_SLOWEST; + ColorCycle.speed_max = ZOTAC_GPU_SPEED_FASTEST; + ColorCycle.speed = ZOTAC_GPU_SPEED_NORMAL; + ColorCycle.color_mode = MODE_COLORS_NONE; + modes.push_back(ColorCycle); + + SetupZones(); +} + +RGBController_ZotacTuringGPU::~RGBController_ZotacTuringGPU() +{ + delete controller; +} + +void RGBController_ZotacTuringGPU::SetupZones() +{ + /*---------------------------------------------------------*\ + | This device only has one LED, so create a single zone and | + | LED for it | + \*---------------------------------------------------------*/ + zone* new_zone = new zone(); + led* new_led = new led(); + + new_zone->name = "GPU Zone"; + new_zone->type = ZONE_TYPE_SINGLE; + new_zone->leds_min = 1; + new_zone->leds_max = 1; + new_zone->leds_count = 1; + new_zone->matrix_map = NULL; + + new_led->name = "GPU LED"; + + /*---------------------------------------------------------*\ + | Push the zone and LED on to device vectors | + \*---------------------------------------------------------*/ + leds.push_back(*new_led); + zones.push_back(*new_zone); + + SetupColors(); + SetupInitialValues(); +} + +void RGBController_ZotacTuringGPU::SetupInitialValues() +{ + /*---------------------------------------------------------*\ + | Retrieve current values by reading the device | + \*---------------------------------------------------------*/ + unsigned int speed; + + controller->GetMode(colors[0], active_mode, speed); + modes[active_mode].speed = speed; + + SignalUpdate(); +} + +void RGBController_ZotacTuringGPU::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_ZotacTuringGPU::DeviceUpdateLEDs() +{ + DeviceUpdateMode(); +} + +void RGBController_ZotacTuringGPU::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateMode(); +} + +void RGBController_ZotacTuringGPU::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateMode(); +} + +void RGBController_ZotacTuringGPU::DeviceUpdateMode() +{ + controller->SetMode(colors[0], modes[active_mode].value, modes[active_mode].speed); +} diff --git a/Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.h b/Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.h new file mode 100644 index 00000000..4d7c3c19 --- /dev/null +++ b/Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.h @@ -0,0 +1,34 @@ +/*-----------------------------------------*\ +| RGBController_ZotacTuringGPU.h | +| | +| Generic RGB Interface for OpenRGB | +| ZOTAC Turing GPU Driver | +| | +| David Henry 1/07/2023 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "ZotacTuringGPUController.h" + +class RGBController_ZotacTuringGPU : public RGBController +{ +public: + RGBController_ZotacTuringGPU(ZotacTuringGPUController* controller_ptr); + ~RGBController_ZotacTuringGPU(); + + void SetupInitialValues(); + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + +private: + ZotacTuringGPUController* controller; +}; diff --git a/Controllers/ZotacTuringGPUController/ZotacTuringGPUController.cpp b/Controllers/ZotacTuringGPUController/ZotacTuringGPUController.cpp new file mode 100644 index 00000000..51841cf5 --- /dev/null +++ b/Controllers/ZotacTuringGPUController/ZotacTuringGPUController.cpp @@ -0,0 +1,66 @@ +/*-----------------------------------------*\ +| ZotacTuringGPUController.cpp | +| | +| Driver for ZOTAC GeForce RTX 20 series | +| GPU lighting controller | +| | +| David Henry 1/07/2023 | +\*-----------------------------------------*/ + +#include "ZotacTuringGPUController.h" + +ZotacTuringGPUController::ZotacTuringGPUController(i2c_smbus_interface* bus, u8 dev) +{ + this->bus = bus; + this->dev = dev; +} + +ZotacTuringGPUController::~ZotacTuringGPUController() +{ +} + +std::string ZotacTuringGPUController::GetDeviceLocation() +{ + std::string return_string(bus->device_name); + char addr[5]; + snprintf(addr, 5, "0x%02X", dev); + return_string.append(", address "); + return_string.append(addr); + return("I2C: " + return_string); +} + +void ZotacTuringGPUController::GetMode(RGBColor& color, int& mode, unsigned int& speed) +{ + u8 rdata_pkt[I2C_SMBUS_BLOCK_MAX] = { 0x00 }; + int rdata_len = sizeof(rdata_pkt); + + if(bus->i2c_read_block(dev, &rdata_len, rdata_pkt) >= 0) + { + mode = rdata_pkt[0]; + color = ToRGBColor(rdata_pkt[1], rdata_pkt[2], rdata_pkt[3]); + speed = rdata_pkt[5]; + } +} + +void ZotacTuringGPUController::SetMode(RGBColor color, int mode, unsigned int speed) +{ + u8 data_pkt[] = + { + ZOTAC_TURING_GPU_REG_COLOR_AND_MODE, + 0x00, // Is it some zone index? + (u8)mode, + (u8)RGBGetRValue(color), + (u8)RGBGetGValue(color), + (u8)RGBGetBValue(color), + 0x00, + (u8)speed + }; + + bus->i2c_write_block(dev, sizeof(data_pkt), data_pkt); + + /*---------------------------------------------------------*\ + | Read back color and mode. Not doing this seems to hang | + | the RGB controller device when switching mode... | + \*---------------------------------------------------------*/ + GetMode(color, mode, speed); +} diff --git a/Controllers/ZotacTuringGPUController/ZotacTuringGPUController.h b/Controllers/ZotacTuringGPUController/ZotacTuringGPUController.h new file mode 100644 index 00000000..51e669f6 --- /dev/null +++ b/Controllers/ZotacTuringGPUController/ZotacTuringGPUController.h @@ -0,0 +1,52 @@ +/*-----------------------------------------*\ +| ZotacTuringGPUController.cpp | +| | +| Definitions and types for ZOTAC GeForce | +| RTX 20 series GPU lighting controller | +| | +| David Henry 1/07/2023 | +\*-----------------------------------------*/ + +#include +#include "i2c_smbus.h" +#include "RGBController.h" + +#pragma once + +enum +{ + ZOTAC_TURING_GPU_REG_COLOR_AND_MODE = 0xA0, +}; + +enum +{ + ZOTAC_GPU_MODE_STATIC = 0x00, + ZOTAC_GPU_MODE_STROBE = 0x01, + ZOTAC_GPU_MODE_WAVE = 0x02, + ZOTAC_GPU_MODE_BREATHING = 0x03, + ZOTAC_GPU_MODE_COLOR_CYCLE = 0x04, +}; + +enum +{ + ZOTAC_GPU_SPEED_SLOWEST = 0x09, + ZOTAC_GPU_SPEED_NORMAL = 0x04, + ZOTAC_GPU_SPEED_FASTEST = 0x00 +}; + +class ZotacTuringGPUController +{ +public: + ZotacTuringGPUController(i2c_smbus_interface* bus, u8 dev); + ~ZotacTuringGPUController(); + + std::string GetDeviceLocation(); + + void GetMode(RGBColor& color, int& mode, unsigned int& speed); + void SetMode(RGBColor color, int mode, unsigned int speed); + +private: + i2c_smbus_interface* bus; + u8 dev; + +}; diff --git a/Controllers/ZotacTuringGPUController/ZotacTuringGPUControllerDetect.cpp b/Controllers/ZotacTuringGPUController/ZotacTuringGPUControllerDetect.cpp new file mode 100644 index 00000000..6caa2ca0 --- /dev/null +++ b/Controllers/ZotacTuringGPUController/ZotacTuringGPUControllerDetect.cpp @@ -0,0 +1,52 @@ +#include "Detector.h" +#include "ZotacTuringGPUController.h" +#include "RGBController.h" +#include "RGBController_ZotacTuringGPU.h" +#include "i2c_smbus.h" +#include "pci_ids.h" + +/******************************************************************************************\ +* * +* TestForZotacTuringGPUController * +* * +* Tests the given address to see if an RGB controller exists there. * +* * +\******************************************************************************************/ + +bool TestForZotacTuringGPUController(i2c_smbus_interface* bus, u8 i2c_addr) +{ + /*---------------------------------------------------------*\ + | This command seems to enable the RGB controller (0xF1, | + | 0x00 disables it). | + | Not really sure it's mandatory, but we can still use it | + | for testing the device: if the command succeeds, assume | + | it's a valid device. | + \*---------------------------------------------------------*/ + u8 data_pkt[] = { ZOTAC_TURING_GPU_REG_COLOR_AND_MODE, 0xF1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; + return (bus->i2c_write_block(i2c_addr, sizeof(data_pkt), data_pkt) >= 0); +} + +/******************************************************************************************\ +* * +* DetectZotacTuringGPUControllers * +* * +* Detect ZOTAC Turing RGB controllers on the enumerated I2C busses at address 0x49. * +* * +* bus - pointer to i2c_smbus_interface where RGB device is connected * +* dev - I2C address of RGB device * +* * +\******************************************************************************************/ + +void DetectZotacTuringGPUControllers(i2c_smbus_interface* bus, u8 i2c_addr, const std::string& name) +{ + if(TestForZotacTuringGPUController(bus, i2c_addr)) + { + ZotacTuringGPUController* controller = new ZotacTuringGPUController(bus, i2c_addr); + RGBController_ZotacTuringGPU* rgb_controller = new RGBController_ZotacTuringGPU(controller); + rgb_controller->name = name; + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +REGISTER_I2C_PCI_DETECTOR("ZOTAC GAMING GeForce RTX 2070 SUPER Twin Fan", DetectZotacTuringGPUControllers, NVIDIA_VEN, NVIDIA_RTX2070S_OC_DEV, ZOTAC_SUB_VEN, ZOTAC_RTX2070S_GAMING_SUB_DEV, 0x49); diff --git a/OpenRGB.pro b/OpenRGB.pro index 5af7ecad..e90100a7 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -170,6 +170,7 @@ INCLUDEPATH += Controllers/WootingKeyboardController/ \ Controllers/YeelightController/ \ Controllers/ZalmanZSyncController/ \ + Controllers/ZotacTuringGPUController/ \ RGBController/ \ qt/ @@ -655,6 +656,8 @@ HEADERS += Controllers/ZETEdgeAirProController/RGBController_ZETEdgeAirPro.h \ Controllers/ZETKeyboardController/ZETBladeOpticalController.h \ Controllers/ZETKeyboardController/RGBController_ZETBladeOptical.h \ + Controllers/ZotacTuringGPUController/ZotacTuringGPUController.h \ + Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.h \ RGBController/RGBController.h \ RGBController/RGBController_Dummy.h \ RGBController/RGBControllerKeyNames.h \ @@ -1273,6 +1276,9 @@ SOURCES += Controllers/ZETKeyboardController/ZETBladeOpticalController.cpp \ Controllers/ZETKeyboardController/ZETKeyboardControllerDetect.cpp \ Controllers/ZETKeyboardController/RGBController_ZETBladeOptical.cpp \ + Controllers/ZotacTuringGPUController/ZotacTuringGPUController.cpp \ + Controllers/ZotacTuringGPUController/ZotacTuringGPUControllerDetect.cpp \ + Controllers/ZotacTuringGPUController/RGBController_ZotacTuringGPU.cpp \ RGBController/RGBController.cpp \ RGBController/RGBController_Dummy.cpp \ RGBController/RGBControllerKeyNames.cpp \ diff --git a/pci_ids/pci_ids.h b/pci_ids/pci_ids.h index f13aff19..bb0b9ee9 100644 --- a/pci_ids/pci_ids.h +++ b/pci_ids/pci_ids.h @@ -563,6 +563,13 @@ #define SAPPHIRE_NAVI21_TOXIC_SUB_DEV1 0xF441 #define SAPPHIRE_NAVI31_NITRO_PLUS_SUB_DEV 0xE471 +/*-----------------------------------------------------*\ +| Zotac Sub-Device IDs | +\*-----------------------------------------------------*/ +#define ZOTAC_RTX2060S_AMP_SUB_DEV 0x5511 +#define ZOTAC_RTX2070S_GAMING_SUB_DEV 0x7500 +#define ZOTAC_RTX2080_AMP_SUB_DEV 0x3500 + /*---------------------------------------------------------*\ | PCI ID Macros | \*---------------------------------------------------------*/