diff --git a/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp index 590aebcb7..c9205a54b 100644 --- a/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp +++ b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp @@ -10,6 +10,8 @@ \*---------------------------------------------------------*/ #include "RGBController_ZotacBlackwellGPU.h" +#include "LogManager.h" +#include "pci_ids.h" /**------------------------------------------------------------------*\ @name ZOTAC RTX 50 series GPU @@ -20,21 +22,60 @@ @effects :tools: @detectors DetectZotacBlackwellGPUControllersPCI @comment - Supports ZOTAC Blackwell (RTX 50 series) GPUs with 3 zones: - Logo, Side Bar, and Infinity Mirror. + Supports ZOTAC Blackwell (RTX 50 series) GPUs. The zone layout + varies per card and is resolved from a static table keyed on + PCI device and sub-device IDs. The controller uses individual SMBus byte writes (registers 0x20-0x2F) with a 3ms delay between each transaction. - To add new cards, add PCI ID entries in `pci_ids/pci_ids.h` - and detection entries in + To add new cards, add PCI ID entries in `pci_ids/pci_ids.h`, + a zone config entry in `device_zone_configs` below, and a + `REGISTER_I2C_PCI_DETECTOR` line in `Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp`. \*-------------------------------------------------------------------*/ -RGBController_ZotacBlackwellGPU::RGBController_ZotacBlackwellGPU(ZotacBlackwellGPUController* controller_ptr) +const RGBController_ZotacBlackwellGPU::DeviceZoneConfig RGBController_ZotacBlackwellGPU::device_zone_configs[] = +{ + { NVIDIA_RTX5080_DEV, ZOTAC_RTX5080_AMP_EXTREME_SUB_DEV, { "Logo", "Side Bar", "Infinity Mirror" }, 3 }, + { NVIDIA_RTX5090_DEV, ZOTAC_RTX5090_SOLID_OC_SUB_DEV, { "ZOTAC Gaming", "Logo" }, 2 }, + { 0, 0, { nullptr }, 0 } +}; + +const RGBController_ZotacBlackwellGPU::DeviceZoneConfig* RGBController_ZotacBlackwellGPU::FindZoneConfig(uint16_t device, uint16_t subdevice) +{ + for(const DeviceZoneConfig* cfg = device_zone_configs; cfg->zone_count != 0; cfg++) + { + if(cfg->device == device && cfg->subdevice == subdevice) + { + return cfg; + } + } + return nullptr; +} + +RGBController_ZotacBlackwellGPU::RGBController_ZotacBlackwellGPU(ZotacBlackwellGPUController* controller_ptr, + uint16_t device, uint16_t subdevice) { controller = controller_ptr; + const DeviceZoneConfig* cfg = FindZoneConfig(device, subdevice); + if(cfg == nullptr) + { + LOG_ERROR("[%s] Unrecognized PCI device/subdevice: %04X/%04X. Falling back to three generic zones.", + controller->GetName().c_str(), device, subdevice); + zone_names.push_back("Zone 0"); + zone_names.push_back("Zone 1"); + zone_names.push_back("Zone 2"); + } + else + { + for(uint8_t z = 0; z < cfg->zone_count; z++) + { + zone_names.push_back(cfg->zones[z]); + } + } + name = controller->GetName(); vendor = "ZOTAC"; description = "ZOTAC RTX 50 series RGB GPU Device (" + controller->GetVersion() + ")"; @@ -252,52 +293,25 @@ RGBController_ZotacBlackwellGPU::~RGBController_ZotacBlackwellGPU() void RGBController_ZotacBlackwellGPU::SetupZones() { /*---------------------------------------------------------*\ - | Zone 0: Logo | + | One single-LED zone per name from the device_zone_configs | + | table. The zone's index is its position here, which is | + | written verbatim to the zone register (0x21) on update. | \*---------------------------------------------------------*/ - zone logo_zone; - logo_zone.name = "Logo"; - logo_zone.type = ZONE_TYPE_SINGLE; - logo_zone.leds_min = 1; - logo_zone.leds_max = 1; - logo_zone.leds_count = 1; - logo_zone.matrix_map = NULL; - zones.push_back(logo_zone); + for(const std::string& zone_name : zone_names) + { + zone new_zone; + new_zone.name = zone_name; + 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; + zones.push_back(new_zone); - led logo_led; - logo_led.name = "Logo LED"; - leds.push_back(logo_led); - - /*---------------------------------------------------------*\ - | Zone 1: Side Bar | - \*---------------------------------------------------------*/ - zone sidebar_zone; - sidebar_zone.name = "Side Bar"; - sidebar_zone.type = ZONE_TYPE_SINGLE; - sidebar_zone.leds_min = 1; - sidebar_zone.leds_max = 1; - sidebar_zone.leds_count = 1; - sidebar_zone.matrix_map = NULL; - zones.push_back(sidebar_zone); - - led sidebar_led; - sidebar_led.name = "Side Bar LED"; - leds.push_back(sidebar_led); - - /*---------------------------------------------------------*\ - | Zone 2: Infinity Mirror | - \*---------------------------------------------------------*/ - zone infinity_zone; - infinity_zone.name = "Infinity Mirror"; - infinity_zone.type = ZONE_TYPE_SINGLE; - infinity_zone.leds_min = 1; - infinity_zone.leds_max = 1; - infinity_zone.leds_count = 1; - infinity_zone.matrix_map = NULL; - zones.push_back(infinity_zone); - - led infinity_led; - infinity_led.name = "Infinity Mirror LED"; - leds.push_back(infinity_led); + led new_led; + new_led.name = zone_name + " LED"; + leds.push_back(new_led); + } SetupColors(); } @@ -362,7 +376,7 @@ void RGBController_ZotacBlackwellGPU::DeviceUpdateZone(int zone) void RGBController_ZotacBlackwellGPU::DeviceUpdateMode() { - for(unsigned int zone_idx = 0; zone_idx < ZOTAC_BLACKWELL_GPU_NUM_ZONES; zone_idx++) + for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++) { DeviceUpdateZone(zone_idx); } diff --git a/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h index 8e1862947..94c0b96ba 100644 --- a/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h +++ b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h @@ -11,13 +11,17 @@ #pragma once +#include +#include +#include #include "RGBController.h" #include "ZotacBlackwellGPUController.h" class RGBController_ZotacBlackwellGPU : public RGBController { public: - RGBController_ZotacBlackwellGPU(ZotacBlackwellGPUController* controller_ptr); + RGBController_ZotacBlackwellGPU(ZotacBlackwellGPUController* controller_ptr, + uint16_t device, uint16_t subdevice); ~RGBController_ZotacBlackwellGPU(); void SetupZones(); @@ -33,4 +37,17 @@ public: private: ZotacBlackwellGPUController* controller; + std::vector zone_names; + + struct DeviceZoneConfig + { + uint16_t device; + uint16_t subdevice; + const char* zones[4]; + uint8_t zone_count; + }; + + static const DeviceZoneConfig device_zone_configs[]; + + static const DeviceZoneConfig* FindZoneConfig(uint16_t device, uint16_t subdevice); }; diff --git a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h index b87edc722..eb69df89e 100644 --- a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h +++ b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h @@ -46,14 +46,6 @@ #define ZOTAC_BLACKWELL_GPU_REG_RELOAD 0x11 #define ZOTAC_BLACKWELL_GPU_REG_COMMIT 0x17 -/*---------------------------------------------------------*\ -| Zone indices | -\*---------------------------------------------------------*/ -#define ZOTAC_BLACKWELL_GPU_ZONE_LOGO 0x00 -#define ZOTAC_BLACKWELL_GPU_ZONE_SIDEBAR 0x01 -#define ZOTAC_BLACKWELL_GPU_ZONE_INFINITY 0x02 -#define ZOTAC_BLACKWELL_GPU_NUM_ZONES 3 - /*---------------------------------------------------------*\ | Mode values (from Firestorm V5.0.0.012E reverse eng.) | \*---------------------------------------------------------*/ diff --git a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp index 966765941..adf7ba463 100644 --- a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp +++ b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp @@ -20,13 +20,13 @@ * DetectZotacBlackwellGPUControllersPCI * * * * Detect ZOTAC Blackwell (RTX 50 series) RGB controllers on the enumerated * -* I2C busses at address 0x4B. * +* I2C busses at address 0x4B. Zone configuration is resolved inside the * +* RGBController by looking up the PCI device/sub-device IDs in a static table. * * * * bus - pointer to i2c_smbus_interface where RGB device is connected * * dev - I2C address of RGB device * * * \******************************************************************************************/ - void DetectZotacBlackwellGPUControllersPCI(i2c_smbus_interface* bus, u8 i2c_addr, const std::string& name) { s32 result = bus->i2c_smbus_read_byte_data(i2c_addr, 0x10); @@ -34,10 +34,13 @@ void DetectZotacBlackwellGPUControllersPCI(i2c_smbus_interface* bus, u8 i2c_addr if(result >= 0) { ZotacBlackwellGPUController* controller = new ZotacBlackwellGPUController(bus, i2c_addr, name); - RGBController_ZotacBlackwellGPU* rgb_controller = new RGBController_ZotacBlackwellGPU(controller); + RGBController_ZotacBlackwellGPU* rgb_controller = new RGBController_ZotacBlackwellGPU(controller, + bus->pci_device, + bus->pci_subsystem_device); ResourceManager::get()->RegisterRGBController(rgb_controller); } } REGISTER_I2C_PCI_DETECTOR("ZOTAC GAMING GeForce RTX 5080 AMP Extreme INFINITY", DetectZotacBlackwellGPUControllersPCI, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ZOTAC_SUB_VEN, ZOTAC_RTX5080_AMP_EXTREME_SUB_DEV, 0x4B); +REGISTER_I2C_PCI_DETECTOR("ZOTAC GAMING GeForce RTX 5090 SOLID OC", DetectZotacBlackwellGPUControllersPCI, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ZOTAC_SUB_VEN, ZOTAC_RTX5090_SOLID_OC_SUB_DEV, 0x4B); diff --git a/pci_ids/pci_ids.h b/pci_ids/pci_ids.h index ae4cd0bca..59e985eff 100644 --- a/pci_ids/pci_ids.h +++ b/pci_ids/pci_ids.h @@ -1000,6 +1000,7 @@ #define ZOTAC_RTX4090_TRINITY_SUB_DEV 0x3675 #define ZOTAC_RTX4090_AMP_SUB_DEV 0x4675 #define ZOTAC_RTX5080_AMP_EXTREME_SUB_DEV 0x1762 +#define ZOTAC_RTX5090_SOLID_OC_SUB_DEV 0x1761 /*-----------------------------------------------------*\ | Manli Sub-Device IDs |