From 71b7450ec991d676630a83195acd1f735cf9ae05 Mon Sep 17 00:00:00 2001 From: Kendall Morgan Date: Wed, 20 Oct 2021 15:29:56 +0000 Subject: [PATCH] Add support for PNY 3090 --- .../PNYGPUController/PNYGPUController.cpp | 66 +++++++++++ .../PNYGPUController/PNYGPUController.h | 52 +++++++++ .../PNYGPUControllerDetect.cpp | 79 +++++++++++++ .../PNYGPUController/RGBController_PNYGPU.cpp | 105 ++++++++++++++++++ .../PNYGPUController/RGBController_PNYGPU.h | 33 ++++++ OpenRGB.pro | 6 + pci_ids/pci_ids.h | 5 + 7 files changed, 346 insertions(+) create mode 100644 Controllers/PNYGPUController/PNYGPUController.cpp create mode 100644 Controllers/PNYGPUController/PNYGPUController.h create mode 100644 Controllers/PNYGPUController/PNYGPUControllerDetect.cpp create mode 100644 Controllers/PNYGPUController/RGBController_PNYGPU.cpp create mode 100644 Controllers/PNYGPUController/RGBController_PNYGPU.h diff --git a/Controllers/PNYGPUController/PNYGPUController.cpp b/Controllers/PNYGPUController/PNYGPUController.cpp new file mode 100644 index 00000000..cc67e5d2 --- /dev/null +++ b/Controllers/PNYGPUController/PNYGPUController.cpp @@ -0,0 +1,66 @@ +/*-----------------------------------------*\ +| PNYGPUController.cpp | +| | +| Driver for PNY GPU RGB (Turing) | +| lighting controller | +| | +| KendallMorgan 10/17/2021 | +\*-----------------------------------------*/ + +#include "PNYGPUController.h" + +PNYGPUController::PNYGPUController(i2c_smbus_interface* bus, pny_dev_id dev) +{ + this->bus = bus; + this->dev = dev; +} + +PNYGPUController::~PNYGPUController() +{ + +} + +std::string PNYGPUController::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); +} + +unsigned char PNYGPUController::GetMode() +{ + return(bus->i2c_smbus_read_byte_data(dev, PNY_GPU_MODE_OFF)); +} + +unsigned char PNYGPUController::GetRed() +{ + return(bus->i2c_smbus_read_byte_data(dev, PNY_GPU_REG_COLOR_RED)); +} + +unsigned char PNYGPUController::GetGreen() +{ + return(bus->i2c_smbus_read_byte_data(dev, PNY_GPU_REG_COLOR_GREEN)); +} + +unsigned char PNYGPUController::GetBlue() +{ + return(bus->i2c_smbus_read_byte_data(dev, PNY_GPU_REG_COLOR_BLUE)); +} + +void PNYGPUController::SetColor(unsigned char red, unsigned char green, unsigned char blue) +{ + bus->i2c_smbus_write_byte_data(dev, 0xE0, 0x00); + bus->i2c_smbus_write_byte_data(dev, PNY_GPU_REG_MODE, 0x01); + bus->i2c_smbus_write_byte_data(dev, PNY_GPU_REG_COLOR_RED, red); + bus->i2c_smbus_write_byte_data(dev, PNY_GPU_REG_COLOR_BLUE, blue); + bus->i2c_smbus_write_byte_data(dev, PNY_GPU_REG_COLOR_GREEN, green); + bus->i2c_smbus_write_byte_data(dev, PNY_GPU_REG_COLOR_BRIGHTNESS, 0x64); +} + +void PNYGPUController::SetMode(unsigned char mode) +{ + bus->i2c_smbus_write_byte_data(dev, PNY_GPU_REG_MODE, mode); +} diff --git a/Controllers/PNYGPUController/PNYGPUController.h b/Controllers/PNYGPUController/PNYGPUController.h new file mode 100644 index 00000000..d92fe996 --- /dev/null +++ b/Controllers/PNYGPUController/PNYGPUController.h @@ -0,0 +1,52 @@ +/*-----------------------------------------*\ +| PNYGPUController.h | +| | +| Definitions and types for PNY GPU RGB | +| (Turing) lighting controller | +| | +| KendallMorgan 10/17/2021 | +\*-----------------------------------------*/ + +#include +#include "i2c_smbus.h" + +#pragma once + +typedef unsigned char pny_dev_id; + +enum +{ + PNY_GPU_REG_MODE = 0x60, + PNY_GPU_REG_COLOR_RED = 0x6C, + PNY_GPU_REG_COLOR_GREEN = 0x6D, + PNY_GPU_REG_COLOR_BLUE = 0x6E, + PNY_GPU_REG_COLOR_BRIGHTNESS = 0x6F, +}; + +enum +{ + PNY_GPU_MODE_OFF = 0x00, + PNY_GPU_MODE_CUSTOM = 0x01, +}; + +class PNYGPUController +{ +public: + PNYGPUController(i2c_smbus_interface* bus, pny_dev_id dev); + ~PNYGPUController(); + + std::string GetDeviceLocation(); + + unsigned char GetMode(); + unsigned char GetRed(); + unsigned char GetGreen(); + unsigned char GetBlue(); + + void SetColor(unsigned char red, unsigned char green, unsigned char blue); + void SetMode(unsigned char mode); + +private: + i2c_smbus_interface* bus; + pny_dev_id dev; + +}; diff --git a/Controllers/PNYGPUController/PNYGPUControllerDetect.cpp b/Controllers/PNYGPUController/PNYGPUControllerDetect.cpp new file mode 100644 index 00000000..918d813d --- /dev/null +++ b/Controllers/PNYGPUController/PNYGPUControllerDetect.cpp @@ -0,0 +1,79 @@ +#include "Detector.h" +#include "PNYGPUController.h" +#include "RGBController.h" +#include "RGBController_PNYGPU.h" +#include "i2c_smbus.h" +#include "pci_ids.h" +#include +#include +#include + +enum +{ + PNY_RGB, +}; + +typedef struct +{ + int pci_vendor; + int pci_device; + int pci_subsystem_vendor; + int pci_subsystem_device; + int gpu_rgb_version; + const char * name; +} gpu_pci_device; + +#define GPU_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ])) + +static const gpu_pci_device device_list[] = +{ + { NVIDIA_VEN, NVIDIA_RTX3090_DEV, PNY_SUB_VEN, PNY_RTX_3090_XLR8_REVEL_EPIC_X_SUB_DEV, PNY_RGB, "PNY XLR8 Revel EPIC-X RTX 3090" }, +}; + +/******************************************************************************************\ + * * + * DetectPNYGPUControllers * + * * + * Detect PNY GPU controllers on the enumerated I2C busses at address 0x49. * + * * + * bus - pointer to i2c_smbus_interface where PNY GPU device is connected * + * dev - I2C address of PNY GPU device * + * * +\******************************************************************************************/ + +void DetectPNYGPUControllers(std::vector& busses) +{ + for(unsigned int bus = 0; bus < busses.size(); bus++) + { + for(unsigned int dev_idx = 0; dev_idx < GPU_NUM_DEVICES; dev_idx++) + { + if(busses[bus]->port_id != 1) + { + break; + } + + if(busses[bus]->pci_vendor == device_list[dev_idx].pci_vendor && + busses[bus]->pci_device == device_list[dev_idx].pci_device && + busses[bus]->pci_subsystem_vendor == device_list[dev_idx].pci_subsystem_vendor && + busses[bus]->pci_subsystem_device == device_list[dev_idx].pci_subsystem_device) + { + switch(device_list[dev_idx].gpu_rgb_version) + { + case PNY_RGB: + { + PNYGPUController* new_controller; + RGBController_PNYGPU* new_rgbcontroller; + + new_controller = new PNYGPUController(busses[bus], 0x49); + new_rgbcontroller = new RGBController_PNYGPU(new_controller); + new_rgbcontroller->name = device_list[dev_idx].name; + ResourceManager::get()->RegisterRGBController(new_rgbcontroller); + } + break; + } + } + } + } +} +/* DetectPNYGPUControllers() */ +REGISTER_I2C_DETECTOR("PNY GPU", DetectPNYGPUControllers); diff --git a/Controllers/PNYGPUController/RGBController_PNYGPU.cpp b/Controllers/PNYGPUController/RGBController_PNYGPU.cpp new file mode 100644 index 00000000..e8cac47e --- /dev/null +++ b/Controllers/PNYGPUController/RGBController_PNYGPU.cpp @@ -0,0 +1,105 @@ +/*-----------------------------------------*\ +| RGBController_PNYGPU.cpp | +| | +| Generic RGB Interface for OpenRGB PNY | +| GPU (Turing) Driver | +| | +| KendallMorgan 10/17/2021 | +\*-----------------------------------------*/ + +#include "RGBController_PNYGPU.h" + +RGBController_PNYGPU::RGBController_PNYGPU(PNYGPUController* pny_ptr) +{ + pny = pny_ptr; + + name = "PNY GPU"; + vendor = "PNY"; + description = "PNY RGB GPU Device"; + location = pny->GetDeviceLocation(); + + type = DEVICE_TYPE_GPU; + + mode Off; + Off.name = "Off"; + Off.value = PNY_GPU_MODE_OFF; + Off.flags = 0; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Direct; + Direct.name = "Direct"; + Direct.value = PNY_GPU_MODE_CUSTOM; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + + SetupZones(); + + // Initialize active mode + active_mode = 0; +} + +void RGBController_PNYGPU::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(); +} + +void RGBController_PNYGPU::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_PNYGPU::DeviceUpdateLEDs() +{ + RGBColor color = colors[0]; + unsigned char red = RGBGetRValue(color); + unsigned char grn = RGBGetGValue(color); + unsigned char blu = RGBGetBValue(color); + + pny->SetColor(red, grn, blu); +} + +void RGBController_PNYGPU::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_PNYGPU::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_PNYGPU::SetCustomMode() +{ + active_mode = 1; +} + +void RGBController_PNYGPU::DeviceUpdateMode() +{ + pny->SetMode((unsigned char)modes[(unsigned int)active_mode].value); +} diff --git a/Controllers/PNYGPUController/RGBController_PNYGPU.h b/Controllers/PNYGPUController/RGBController_PNYGPU.h new file mode 100644 index 00000000..f9a3ccd1 --- /dev/null +++ b/Controllers/PNYGPUController/RGBController_PNYGPU.h @@ -0,0 +1,33 @@ +/*-----------------------------------------*\ +| RGBController_PNYGPU.h | +| | +| Generic RGB Interface for OpenRGB | +| PNY GPU RGB (Turing) Driver | +| | +| KendallMorgan 10/17/2021 | +\*-----------------------------------------*/ + +#pragma once + +#include "RGBController.h" +#include "PNYGPUController.h" + +class RGBController_PNYGPU : public RGBController +{ +public: + RGBController_PNYGPU(PNYGPUController* pny_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: + PNYGPUController* pny; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 494b8cc6..85a4724c 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -129,6 +129,7 @@ INCLUDEPATH += Controllers/PatriotViperController/ \ Controllers/PhilipsHueController/ \ Controllers/PhilipsWizController/ \ + Controllers/PNYGPUController/ \ Controllers/QMKOpenRGBController/ \ Controllers/RazerController/ \ Controllers/RedragonController/ \ @@ -393,6 +394,8 @@ HEADERS += Controllers/PhilipsHueController/RGBController_PhilipsHue.h \ Controllers/PhilipsWizController/PhilipsWizController.h \ Controllers/PhilipsWizController/RGBController_PhilipsWiz.h \ + Controllers/PNYGPUController/PNYGPUController.h \ + Controllers/PNYGPUController/RGBController_PNYGPU.h \ Controllers/QMKOpenRGBController/QMKOpenRGBController.h \ Controllers/QMKOpenRGBController/QMKOpenRGBRev9Controller.h \ Controllers/QMKOpenRGBController/QMKOpenRGBRevBController.h \ @@ -791,6 +794,9 @@ SOURCES += Controllers/PhilipsWizController/PhilipsWizController.cpp \ Controllers/PhilipsWizController/PhilipsWizControllerDetect.cpp \ Controllers/PhilipsWizController/RGBController_PhilipsWiz.cpp \ + Controllers/PNYGPUController/PNYGPUController.cpp \ + Controllers/PNYGPUController/PNYGPUControllerDetect.cpp \ + Controllers/PNYGPUController/RGBController_PNYGPU.cpp \ Controllers/QMKOpenRGBController/QMKOpenRGBControllerDetect.cpp \ Controllers/QMKOpenRGBController/QMKOpenRGBRev9Controller.cpp \ Controllers/QMKOpenRGBController/QMKOpenRGBRevBController.cpp \ diff --git a/pci_ids/pci_ids.h b/pci_ids/pci_ids.h index 0129c54b..10f5cc70 100644 --- a/pci_ids/pci_ids.h +++ b/pci_ids/pci_ids.h @@ -235,6 +235,11 @@ #define MSI_RTX3090_GAMING_X_TRIO_SUB_DEV 0x3884 #define MSI_RTX3090_SUPRIM_X_SUB_DEV 0x3882 +/*-----------------------------------------------------*\ +| PNY Sub-Device IDs | +\*-----------------------------------------------------*/ +#define PNY_RTX_3090_XLR8_REVEL_EPIC_X_SUB_DEV 0x136A + /*-----------------------------------------------------*\ | Sapphire Sub-Device IDs | \*-----------------------------------------------------*/