From b3a50d669e6962dd75fbac14ea79a01b5612f029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eder=20S=C3=A1nchez?= Date: Thu, 9 Apr 2026 11:21:52 -0600 Subject: [PATCH] Add support for ZOTAC GAMING GeForce RTX 5080 AMP Extreme INFINITY --- .../RGBController_ZotacBlackwellGPU.cpp | 369 +++++++++++++++++++++ .../RGBController_ZotacBlackwellGPU.h | 36 ++ .../ZotacBlackwellGPUController.cpp | 124 +++++++ .../ZotacBlackwellGPUController.h | 109 ++++++ .../ZotacBlackwellGPUControllerDetect.cpp | 43 +++ pci_ids/pci_ids.h | 1 + 6 files changed, 682 insertions(+) create mode 100644 Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp create mode 100644 Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h create mode 100644 Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.cpp create mode 100644 Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h create mode 100644 Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp diff --git a/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp new file mode 100644 index 00000000..590aebcb --- /dev/null +++ b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.cpp @@ -0,0 +1,369 @@ +/*---------------------------------------------------------*\ +| RGBController_ZotacBlackwellGPU.cpp | +| | +| RGBController for ZOTAC Blackwell (RTX 50 series) GPU | +| | +| Eder Sánchez 27 Mar 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include "RGBController_ZotacBlackwellGPU.h" + +/**------------------------------------------------------------------*\ + @name ZOTAC RTX 50 series GPU + @category GPU + @type I2C + @save :robot: + @direct :x: + @effects :tools: + @detectors DetectZotacBlackwellGPUControllersPCI + @comment + Supports ZOTAC Blackwell (RTX 50 series) GPUs with 3 zones: + Logo, Side Bar, and Infinity Mirror. + + 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 + `Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp`. +\*-------------------------------------------------------------------*/ + +RGBController_ZotacBlackwellGPU::RGBController_ZotacBlackwellGPU(ZotacBlackwellGPUController* controller_ptr) +{ + controller = controller_ptr; + + name = controller->GetName(); + vendor = "ZOTAC"; + description = "ZOTAC RTX 50 series RGB GPU Device (" + controller->GetVersion() + ")"; + location = controller->GetDeviceLocation(); + type = DEVICE_TYPE_GPU; + version = controller->GetVersion(); + + /*---------------------------------------------------------*\ + | Static mode | + \*---------------------------------------------------------*/ + mode STATIC; + STATIC.name = "Static"; + STATIC.value = ZOTAC_BLACKWELL_GPU_MODE_STATIC; + STATIC.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR; + STATIC.brightness_min = 0; + STATIC.brightness_max = 100; + STATIC.brightness = 100; + STATIC.color_mode = MODE_COLORS_PER_LED; + modes.push_back(STATIC); + + /*---------------------------------------------------------*\ + | Breathe mode | + \*---------------------------------------------------------*/ + mode BREATHE; + BREATHE.name = "Breathe"; + BREATHE.value = ZOTAC_BLACKWELL_GPU_MODE_BREATHE; + BREATHE.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + BREATHE.brightness_min = 0; + BREATHE.brightness_max = 100; + BREATHE.brightness = 100; + BREATHE.speed_min = 0; + BREATHE.speed_max = 100; + BREATHE.speed = 20; + BREATHE.color_mode = MODE_COLORS_PER_LED; + modes.push_back(BREATHE); + + /*---------------------------------------------------------*\ + | Fade mode | + \*---------------------------------------------------------*/ + mode FADE; + FADE.name = "Fade"; + FADE.value = ZOTAC_BLACKWELL_GPU_MODE_FADE; + FADE.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED; + FADE.speed_min = 0; + FADE.speed_max = 100; + FADE.speed = 20; + FADE.color_mode = MODE_COLORS_NONE; + modes.push_back(FADE); + + /*---------------------------------------------------------*\ + | Wink mode | + \*---------------------------------------------------------*/ + mode WINK; + WINK.name = "Wink"; + WINK.value = ZOTAC_BLACKWELL_GPU_MODE_WINK; + WINK.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + WINK.brightness_min = 0; + WINK.brightness_max = 100; + WINK.brightness = 100; + WINK.speed_min = 0; + WINK.speed_max = 100; + WINK.speed = 20; + WINK.color_mode = MODE_COLORS_PER_LED; + modes.push_back(WINK); + + /*---------------------------------------------------------*\ + | Glide mode | + \*---------------------------------------------------------*/ + mode GLIDE; + GLIDE.name = "Glide"; + GLIDE.value = ZOTAC_BLACKWELL_GPU_MODE_GLIDE; + GLIDE.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_PER_LED_COLOR; + GLIDE.brightness_min = 0; + GLIDE.brightness_max = 100; + GLIDE.brightness = 100; + GLIDE.speed_min = 0; + GLIDE.speed_max = 100; + GLIDE.speed = 20; + GLIDE.color_mode = MODE_COLORS_PER_LED; + modes.push_back(GLIDE); + + /*---------------------------------------------------------*\ + | Prism mode (called "Rainbow" in older firmware) | + \*---------------------------------------------------------*/ + mode PRISM; + PRISM.name = "Prism"; + PRISM.value = ZOTAC_BLACKWELL_GPU_MODE_PRISM; + PRISM.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR; + PRISM.speed_min = 0; + PRISM.speed_max = 100; + PRISM.speed = 20; + PRISM.color_mode = MODE_COLORS_NONE; + modes.push_back(PRISM); + + /*---------------------------------------------------------*\ + | Bokeh mode | + \*---------------------------------------------------------*/ + mode BOKEH; + BOKEH.name = "Bokeh"; + BOKEH.value = ZOTAC_BLACKWELL_GPU_MODE_BOKEH; + BOKEH.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + BOKEH.brightness_min = 0; + BOKEH.brightness_max = 100; + BOKEH.brightness = 100; + BOKEH.speed_min = 0; + BOKEH.speed_max = 100; + BOKEH.speed = 20; + BOKEH.color_mode = MODE_COLORS_PER_LED; + modes.push_back(BOKEH); + + /*---------------------------------------------------------*\ + | Beacon mode | + \*---------------------------------------------------------*/ + mode BEACON; + BEACON.name = "Beacon"; + BEACON.value = ZOTAC_BLACKWELL_GPU_MODE_BEACON; + BEACON.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + BEACON.brightness_min = 0; + BEACON.brightness_max = 100; + BEACON.brightness = 100; + BEACON.speed_min = 0; + BEACON.speed_max = 100; + BEACON.speed = 20; + BEACON.color_mode = MODE_COLORS_PER_LED; + modes.push_back(BEACON); + + /*---------------------------------------------------------*\ + | Tandem mode | + \*---------------------------------------------------------*/ + mode TANDEM; + TANDEM.name = "Tandem"; + TANDEM.value = ZOTAC_BLACKWELL_GPU_MODE_TANDEM; + TANDEM.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + TANDEM.brightness_min = 0; + TANDEM.brightness_max = 100; + TANDEM.brightness = 100; + TANDEM.speed_min = 0; + TANDEM.speed_max = 100; + TANDEM.speed = 20; + TANDEM.color_mode = MODE_COLORS_PER_LED; + modes.push_back(TANDEM); + + /*---------------------------------------------------------*\ + | Tidal mode | + \*---------------------------------------------------------*/ + mode TIDAL; + TIDAL.name = "Tidal"; + TIDAL.value = ZOTAC_BLACKWELL_GPU_MODE_TIDAL; + TIDAL.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_PER_LED_COLOR; + TIDAL.brightness_min = 0; + TIDAL.brightness_max = 100; + TIDAL.brightness = 100; + TIDAL.speed_min = 0; + TIDAL.speed_max = 100; + TIDAL.speed = 20; + TIDAL.color_mode = MODE_COLORS_PER_LED; + modes.push_back(TIDAL); + + /*---------------------------------------------------------*\ + | Astra mode | + \*---------------------------------------------------------*/ + mode ASTRA; + ASTRA.name = "Astra"; + ASTRA.value = ZOTAC_BLACKWELL_GPU_MODE_ASTRA; + ASTRA.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + ASTRA.brightness_min = 0; + ASTRA.brightness_max = 100; + ASTRA.brightness = 100; + ASTRA.speed_min = 0; + ASTRA.speed_max = 100; + ASTRA.speed = 20; + ASTRA.color_mode = MODE_COLORS_PER_LED; + modes.push_back(ASTRA); + + /*---------------------------------------------------------*\ + | Cosmic mode | + \*---------------------------------------------------------*/ + mode COSMIC; + COSMIC.name = "Cosmic"; + COSMIC.value = ZOTAC_BLACKWELL_GPU_MODE_COSMIC; + COSMIC.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + COSMIC.brightness_min = 0; + COSMIC.brightness_max = 100; + COSMIC.brightness = 100; + COSMIC.speed_min = 0; + COSMIC.speed_max = 100; + COSMIC.speed = 20; + COSMIC.color_mode = MODE_COLORS_PER_LED; + modes.push_back(COSMIC); + + /*---------------------------------------------------------*\ + | Volta mode | + \*---------------------------------------------------------*/ + mode VOLTA; + VOLTA.name = "Volta"; + VOLTA.value = ZOTAC_BLACKWELL_GPU_MODE_VOLTA; + VOLTA.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR; + VOLTA.brightness_min = 0; + VOLTA.brightness_max = 100; + VOLTA.brightness = 100; + VOLTA.speed_min = 0; + VOLTA.speed_max = 100; + VOLTA.speed = 20; + VOLTA.color_mode = MODE_COLORS_PER_LED; + modes.push_back(VOLTA); + + SetupZones(); +} + +RGBController_ZotacBlackwellGPU::~RGBController_ZotacBlackwellGPU() +{ + delete controller; +} + +void RGBController_ZotacBlackwellGPU::SetupZones() +{ + /*---------------------------------------------------------*\ + | Zone 0: Logo | + \*---------------------------------------------------------*/ + 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); + + 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); + + SetupColors(); +} + +void RGBController_ZotacBlackwellGPU::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_ZotacBlackwellGPU::DeviceUpdateLEDs() +{ + DeviceUpdateMode(); +} + +void RGBController_ZotacBlackwellGPU::UpdateZoneLEDs(int zone) +{ + DeviceUpdateZone(zone); +} + +void RGBController_ZotacBlackwellGPU::UpdateSingleLED(int led) +{ + DeviceUpdateZone(led); +} + +void RGBController_ZotacBlackwellGPU::DeviceUpdateZone(int zone) +{ + unsigned int mode_val = modes[active_mode].value; + unsigned int brightness = modes[active_mode].brightness; + unsigned int speed = modes[active_mode].speed; + unsigned int direction = modes[active_mode].direction == MODE_DIRECTION_RIGHT + ? ZOTAC_BLACKWELL_GPU_DIR_RIGHT + : ZOTAC_BLACKWELL_GPU_DIR_LEFT; + + RGBColor color1; + RGBColor color2 = ToRGBColor(0, 0, 0); + + switch(modes[active_mode].color_mode) + { + case MODE_COLORS_PER_LED: + color1 = colors[zone]; + break; + + case MODE_COLORS_MODE_SPECIFIC: + color1 = (modes[active_mode].colors.size() >= 1) + ? modes[active_mode].colors[0] + : ToRGBColor(0, 0, 0); + color2 = (modes[active_mode].colors.size() >= 2) + ? modes[active_mode].colors[1] + : ToRGBColor(0, 0, 0); + break; + + default: + color1 = ToRGBColor(0, 0, 0); + break; + } + + controller->SetMode(zone, mode_val, color1, color2, brightness, speed, direction); + controller->Commit(); +} + +void RGBController_ZotacBlackwellGPU::DeviceUpdateMode() +{ + for(unsigned int zone_idx = 0; zone_idx < ZOTAC_BLACKWELL_GPU_NUM_ZONES; zone_idx++) + { + DeviceUpdateZone(zone_idx); + } +} diff --git a/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h new file mode 100644 index 00000000..8e186294 --- /dev/null +++ b/Controllers/ZotacBlackwellGPUController/RGBController_ZotacBlackwellGPU.h @@ -0,0 +1,36 @@ +/*---------------------------------------------------------*\ +| RGBController_ZotacBlackwellGPU.h | +| | +| RGBController for ZOTAC Blackwell (RTX 50 series) GPU | +| | +| Eder Sánchez 27 Mar 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "ZotacBlackwellGPUController.h" + +class RGBController_ZotacBlackwellGPU : public RGBController +{ +public: + RGBController_ZotacBlackwellGPU(ZotacBlackwellGPUController* controller_ptr); + ~RGBController_ZotacBlackwellGPU(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + void DeviceUpdateZone(int zone); + +private: + ZotacBlackwellGPUController* controller; +}; diff --git a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.cpp b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.cpp new file mode 100644 index 00000000..9a441b36 --- /dev/null +++ b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.cpp @@ -0,0 +1,124 @@ +/*---------------------------------------------------------*\ +| ZotacBlackwellGPUController.cpp | +| | +| Driver for ZOTAC Blackwell (RTX 50 series) GPU | +| | +| Eder Sánchez 27 Mar 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include +#include "ZotacBlackwellGPUController.h" +#include "LogManager.h" + +ZotacBlackwellGPUController::ZotacBlackwellGPUController(i2c_smbus_interface* bus, u8 dev, std::string dev_name) +{ + this->bus = bus; + this->dev = dev; + this->name = dev_name; + + ReadVersion(); +} + +ZotacBlackwellGPUController::~ZotacBlackwellGPUController() +{ +} + +std::string ZotacBlackwellGPUController::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); +} + +std::string ZotacBlackwellGPUController::GetName() +{ + return(name); +} + +std::string ZotacBlackwellGPUController::GetVersion() +{ + return(version); +} + +void ZotacBlackwellGPUController::ReadVersion() +{ + /*---------------------------------------------------------*\ + | Read version via raw I2C block read. The first bytes | + | returned contain the ASCII version string (e.g. | + | "N762A-2008e"). If the raw read fails or returns empty, | + | fall back to reading register 0x2F as an identifier. | + \*---------------------------------------------------------*/ + 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 && rdata_pkt[0] != 0x00) + { + version = std::string((char*)rdata_pkt); + } + else + { + version = "Unknown"; + } + + LOG_INFO("[%s] Firmware version: %s", name.c_str(), version.c_str()); +} + +void ZotacBlackwellGPUController::SetMode +( + unsigned int zone, + unsigned int mode_val, + RGBColor color1, + RGBColor color2, + unsigned int brightness, + unsigned int speed, + unsigned int direction +) +{ + /*---------------------------------------------------------*\ + | Write all 16 registers 0x20 - 0x2F via individual | + | i2c_smbus_write_byte_data calls with 3ms delay between | + | each transaction. Partial writes are not supported. | + \*---------------------------------------------------------*/ + + u8 regs[16]; + regs[0x00] = 0x00; /* 0x20 - Fixed = 0x00 */ + regs[0x01] = (u8)zone; /* 0x21 - Zone index */ + regs[0x02] = (u8)mode_val; /* 0x22 - Mode */ + regs[0x03] = (u8)RGBGetRValue(color1); /* 0x23 - Red 1 */ + regs[0x04] = (u8)RGBGetGValue(color1); /* 0x24 - Green 1 */ + regs[0x05] = (u8)RGBGetBValue(color1); /* 0x25 - Blue 1 */ + regs[0x06] = (u8)RGBGetRValue(color2); /* 0x26 - Red 2 */ + regs[0x07] = (u8)RGBGetGValue(color2); /* 0x27 - Green 2 */ + regs[0x08] = (u8)RGBGetBValue(color2); /* 0x28 - Blue 2 */ + regs[0x09] = (u8)brightness; /* 0x29 - Brightness (0-100) */ + regs[0x0A] = (u8)speed; /* 0x2A - Speed (0-100) */ + regs[0x0B] = (u8)direction; /* 0x2B - Direction */ + regs[0x0C] = 0x00; /* 0x2C - Reserved */ + regs[0x0D] = 0x00; /* 0x2D - Reserved */ + regs[0x0E] = 0x00; /* 0x2E - Reserved */ + regs[0x0F] = 0x00; /* 0x2F - Reserved */ + + for(int i = 0; i < 16; i++) + { + bus->i2c_smbus_write_byte_data(dev, (u8)(ZOTAC_BLACKWELL_GPU_REG_FIXED + i), regs[i]); + usleep(ZOTAC_BLACKWELL_GPU_DELAY_US); + } +} + +void ZotacBlackwellGPUController::Commit() +{ + /*---------------------------------------------------------*\ + | Write commit register to apply staged changes. | + | A longer delay is needed after commit to allow the | + | firmware to process the change — without this, some | + | effects don't visually update until a parameter changes. | + \*---------------------------------------------------------*/ + bus->i2c_smbus_write_byte_data(dev, ZOTAC_BLACKWELL_GPU_REG_COMMIT, 0x01); + usleep(ZOTAC_BLACKWELL_GPU_COMMIT_DELAY_US); +} diff --git a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h new file mode 100644 index 00000000..b87edc72 --- /dev/null +++ b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUController.h @@ -0,0 +1,109 @@ +/*---------------------------------------------------------*\ +| ZotacBlackwellGPUController.h | +| | +| Driver for ZOTAC Blackwell (RTX 50 series) GPU | +| | +| Eder Sánchez 27 Mar 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include "i2c_smbus.h" +#include "RGBController.h" + +/*---------------------------------------------------------*\ +| ZOTAC Blackwell I2C address | +\*---------------------------------------------------------*/ +#define ZOTAC_BLACKWELL_GPU_ADDR 0x4B + +/*---------------------------------------------------------*\ +| Register map (0x20 - 0x2F) | +\*---------------------------------------------------------*/ +#define ZOTAC_BLACKWELL_GPU_REG_FIXED 0x20 +#define ZOTAC_BLACKWELL_GPU_REG_ZONE 0x21 +#define ZOTAC_BLACKWELL_GPU_REG_MODE 0x22 +#define ZOTAC_BLACKWELL_GPU_REG_RED1 0x23 +#define ZOTAC_BLACKWELL_GPU_REG_GREEN1 0x24 +#define ZOTAC_BLACKWELL_GPU_REG_BLUE1 0x25 +#define ZOTAC_BLACKWELL_GPU_REG_RED2 0x26 +#define ZOTAC_BLACKWELL_GPU_REG_GREEN2 0x27 +#define ZOTAC_BLACKWELL_GPU_REG_BLUE2 0x28 +#define ZOTAC_BLACKWELL_GPU_REG_BRIGHTNESS 0x29 +#define ZOTAC_BLACKWELL_GPU_REG_SPEED 0x2A +#define ZOTAC_BLACKWELL_GPU_REG_DIRECTION 0x2B +#define ZOTAC_BLACKWELL_GPU_REG_RESERVED_2C 0x2C +#define ZOTAC_BLACKWELL_GPU_REG_RESERVED_2D 0x2D +#define ZOTAC_BLACKWELL_GPU_REG_RESERVED_2E 0x2E +#define ZOTAC_BLACKWELL_GPU_REG_RESERVED_2F 0x2F + +/*---------------------------------------------------------*\ +| Control registers | +\*---------------------------------------------------------*/ +#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.) | +\*---------------------------------------------------------*/ +#define ZOTAC_BLACKWELL_GPU_MODE_STATIC 0x01 +#define ZOTAC_BLACKWELL_GPU_MODE_BREATHE 0x02 +#define ZOTAC_BLACKWELL_GPU_MODE_FADE 0x03 +#define ZOTAC_BLACKWELL_GPU_MODE_WINK 0x04 +#define ZOTAC_BLACKWELL_GPU_MODE_GLIDE 0x08 +#define ZOTAC_BLACKWELL_GPU_MODE_PRISM 0x09 +#define ZOTAC_BLACKWELL_GPU_MODE_BOKEH 0x0A +#define ZOTAC_BLACKWELL_GPU_MODE_BEACON 0x0B +#define ZOTAC_BLACKWELL_GPU_MODE_TANDEM 0x18 +#define ZOTAC_BLACKWELL_GPU_MODE_TIDAL 0x19 +#define ZOTAC_BLACKWELL_GPU_MODE_ASTRA 0x20 +#define ZOTAC_BLACKWELL_GPU_MODE_COSMIC 0x21 +#define ZOTAC_BLACKWELL_GPU_MODE_VOLTA 0x22 + +/*---------------------------------------------------------*\ +| Direction values | +\*---------------------------------------------------------*/ +#define ZOTAC_BLACKWELL_GPU_DIR_LEFT 0x00 +#define ZOTAC_BLACKWELL_GPU_DIR_RIGHT 0x01 + +/*---------------------------------------------------------*\ +| I2C transaction delays (microseconds) | +\*---------------------------------------------------------*/ +#define ZOTAC_BLACKWELL_GPU_DELAY_US 3000 +#define ZOTAC_BLACKWELL_GPU_COMMIT_DELAY_US 10000 + +class ZotacBlackwellGPUController +{ +public: + ZotacBlackwellGPUController(i2c_smbus_interface* bus, u8 dev, std::string dev_name); + ~ZotacBlackwellGPUController(); + + std::string GetDeviceLocation(); + std::string GetName(); + std::string GetVersion(); + + void SetMode(unsigned int zone, unsigned int mode_val, + RGBColor color1, RGBColor color2, + unsigned int brightness, unsigned int speed, + unsigned int direction); + void Commit(); + +private: + i2c_smbus_interface* bus; + u8 dev; + std::string name; + std::string version; + + void ReadVersion(); +}; diff --git a/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp new file mode 100644 index 00000000..96676594 --- /dev/null +++ b/Controllers/ZotacBlackwellGPUController/ZotacBlackwellGPUControllerDetect.cpp @@ -0,0 +1,43 @@ +/*---------------------------------------------------------*\ +| ZotacBlackwellGPUControllerDetect.cpp | +| | +| Detector for ZOTAC Blackwell (RTX 50 series) GPU | +| | +| Eder Sánchez 27 Mar 2026 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-or-later | +\*---------------------------------------------------------*/ + +#include "Detector.h" +#include "ZotacBlackwellGPUController.h" +#include "RGBController_ZotacBlackwellGPU.h" +#include "i2c_smbus.h" +#include "pci_ids.h" + +/******************************************************************************************\ +* * +* DetectZotacBlackwellGPUControllersPCI * +* * +* Detect ZOTAC Blackwell (RTX 50 series) RGB controllers on the enumerated * +* I2C busses at address 0x4B. * +* * +* 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); + + if(result >= 0) + { + ZotacBlackwellGPUController* controller = new ZotacBlackwellGPUController(bus, i2c_addr, name); + RGBController_ZotacBlackwellGPU* rgb_controller = new RGBController_ZotacBlackwellGPU(controller); + + 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); diff --git a/pci_ids/pci_ids.h b/pci_ids/pci_ids.h index 105b13ab..83e6c5ed 100644 --- a/pci_ids/pci_ids.h +++ b/pci_ids/pci_ids.h @@ -983,6 +983,7 @@ #define ZOTAC_RTX4080_AMP_ALT_SUB_DEV 0x2688 #define ZOTAC_RTX4090_TRINITY_SUB_DEV 0x3675 #define ZOTAC_RTX4090_AMP_SUB_DEV 0x4675 +#define ZOTAC_RTX5080_AMP_EXTREME_SUB_DEV 0x1762 /*-----------------------------------------------------*\ | Manli Sub-Device IDs |