Publish LumaOps source

This commit is contained in:
LumaOps release export
2026-09-03 01:18:36 +02:00
commit 7f1c0e5f71
2363 changed files with 501543 additions and 0 deletions
@@ -0,0 +1,558 @@
/*---------------------------------------------------------*\
| ENESMBusController.cpp |
| |
| Driver for ENE SMBus devices |
| |
| Adam Honse (CalcProgrammer1) 19 Aug 2018 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "ENESMBusController.h"
#include "LogManager.h"
static const char* ene_channels[] = /* ENE channel strings */
{
"Audio",
"Backplate",
"Back I/O",
"Center",
"Center",
"DRAM",
"PCIe",
"RGB Header",
"RGB Header 2",
"RGB Header",
"SSD",
"Unknown",
};
ENESMBusController::ENESMBusController(ENESMBusInterface* interface, ene_dev_id dev, std::string dev_name, device_type dev_type)
{
this->interface = interface;
this->dev = dev;
this->name = dev_name;
this->type = dev_type;
supports_mode_14 = false;
if(interface->GetInterfaceType() != ENE_INTERFACE_TYPE_ROG_ARION)
{
UpdateDeviceName();
/*-------------------------------------------------*\
| Read the device configuration table |
\*-------------------------------------------------*/
for(int i = 0; i < 64; i++)
{
config_table[i] = ENERegisterRead(ENE_REG_CONFIG_TABLE + i);
}
/*-------------------------------------------------*\
| If this is running with TRACE or higher loglevel |
| then dump the entire Feature list to log |
\*-------------------------------------------------*/
if(LogManager::get()->getLoglevel() >= LL_TRACE)
{
LOG_TRACE("[ENE SMBus] ENE config table for 0x%02X:", dev);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[0], config_table[1], config_table[2], config_table[3],
config_table[4], config_table[5], config_table[6], config_table[7],
config_table[8], config_table[9], config_table[10], config_table[11],
config_table[12], config_table[13], config_table[14], config_table[15]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[16], config_table[17], config_table[18], config_table[19],
config_table[20], config_table[21], config_table[22], config_table[23],
config_table[24], config_table[25], config_table[26], config_table[27],
config_table[28], config_table[29], config_table[30], config_table[31]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[32], config_table[33], config_table[34], config_table[35],
config_table[36], config_table[37], config_table[38], config_table[39],
config_table[40], config_table[41], config_table[42], config_table[43],
config_table[44], config_table[45], config_table[46], config_table[47]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[48], config_table[49], config_table[50], config_table[51],
config_table[52], config_table[53], config_table[54], config_table[55],
config_table[56], config_table[57], config_table[58], config_table[59],
config_table[60], config_table[61], config_table[62], config_table[63]);
}
}
else
{
LOG_TRACE("[ENE SMBus] ROG STRIX ARION detected, filling in hard coded config table entries.", dev);
memset(config_table, 0, sizeof(config_table));
config_table[ENE_CONFIG_LED_COUNT] = 4;
config_table[0x03] = 4;
strcpy(device_version, "ROG STRIX ARION");
}
/*-----------------------------------------------------*\
| Read LED count from configuration table |
\*-----------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT];
/*-----------------------------------------------------*\
| LED-0116 - First generation motherboard controller |
\*-----------------------------------------------------*/
if(strcmp(device_version, "LED-0116") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT;
effect_reg = ENE_REG_COLORS_EFFECT;
channel_cfg = ENE_CONFIG_CHANNEL_V1;
}
/*-----------------------------------------------------*\
| DIMM_LED-0102 - First generation DRAM controller |
| (Trident Z RGB) |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "DIMM_LED-0102") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT;
effect_reg = ENE_REG_COLORS_EFFECT;
channel_cfg = ENE_CONFIG_CHANNEL_V1;
}
/*-----------------------------------------------------*\
| AUDA0-E6K5-0101 - Second generation DRAM controller |
| (Geil Super Luce) |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUDA0-E6K5-0101") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V1;
/*-------------------------------------------------*\
| Check for Mode 14 support, only known to exist on |
| modules where the DRAM 3 zone ID exists |
\*-------------------------------------------------*/
for(std::size_t cfg_zone_idx = 0; cfg_zone_idx < ENE_NUM_ZONES; cfg_zone_idx++)
{
if(config_table[channel_cfg + cfg_zone_idx] == (unsigned char)ENE_LED_CHANNEL_DRAM_3)
{
supports_mode_14 = true;
break;
}
}
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-0106 - Second generation motherboard |
| controller |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-0106") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-0105 - Second generation motherboard |
| controller |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-0105") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-0104 - Second generation motherboard |
| controller |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-0104") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
}
/*-----------------------------------------------------*\
| AUMA0-E8K4-0101 - First generation motherboard |
| controller |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E8K4-0101") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT;
effect_reg = ENE_REG_COLORS_EFFECT;
channel_cfg = ENE_CONFIG_CHANNEL_V1;
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-0107 - Second generation GPU controller |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-0107") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-1110 - Third generation GPU controller? |
| found an ASUS ROG Strix 4080 OC, seems to be equal to |
| AUMA0-E6K5-0107 |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-1110") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_1110];
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-1111 - Fourth generation GPU controller? |
| found on ASUS ROG Strix 4090 OC EVA-02 Edition, seems |
| to be equal to AUMA0-E6K5-0107 |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-1111") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-1107 - Second generation GPU controller |
| Found on ASUS TUF 4070 TI OC, seems to be equal to |
| AUMA0-E6K5-0107 |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-1107") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-0008 |
| Found on ASUS STRIX 4070 Super OC |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-0008") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V1;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-1113 |
| Found on ASUS ASTRAL 5080 OC |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-1113") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
/*-----------------------------------------------------*\
| AUMA0-E6K5-1114 |
| Found on ASUS ROG MATRIX PLATINUM 5090 |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "AUMA0-E6K5-1114") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
/*-------------------------------------------------*\
| Read LED count from configuration table |
\*-------------------------------------------------*/
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
/*-----------------------------------------------------*\
| ROG ARION - ASUS ROG Arion external SSD enclosure |
| This device does not support ENE read, so we fake the |
| device name string if the interface is ROG Arion type.|
| It uses second generation registers. |
\*-----------------------------------------------------*/
else if(strcmp(device_version, "ROG STRIX ARION") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
}
/*-----------------------------------------------------*\
| Assume first generation controller if string does not |
| match |
\*-----------------------------------------------------*/
else
{
direct_reg = ENE_REG_COLORS_DIRECT;
effect_reg = ENE_REG_COLORS_EFFECT;
channel_cfg = ENE_CONFIG_CHANNEL_V1;
}
}
ENESMBusController::~ENESMBusController()
{
delete interface;
}
std::string ENESMBusController::GetLocation()
{
std::string return_string = interface->GetLocation();
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return(return_string);
}
std::string ENESMBusController::GetName()
{
return(name);
}
std::string ENESMBusController::GetVersion()
{
return(device_version);
}
device_type ENESMBusController::GetType()
{
return(type);
}
const char * ENESMBusController::GetChannelName(unsigned int cfg_zone)
{
LOG_TRACE("[%s] Config table for zone %02d: %02d", device_version, cfg_zone, config_table[channel_cfg + cfg_zone]);
if(interface->GetInterfaceType() == ENE_INTERFACE_TYPE_ROG_ARION)
{
return(ene_channels[10]);
}
else
{
switch(config_table[channel_cfg + cfg_zone])
{
case (unsigned char)ENE_LED_CHANNEL_AUDIO:
return(ene_channels[0]);
break;
case (unsigned char)ENE_LED_CHANNEL_BACKPLATE:
return(ene_channels[1]);
break;
case (unsigned char)ENE_LED_CHANNEL_BACK_IO:
return(ene_channels[2]);
break;
case (unsigned char)ENE_LED_CHANNEL_CENTER:
return(ene_channels[3]);
break;
case (unsigned char)ENE_LED_CHANNEL_CENTER_START:
return(ene_channels[4]);
break;
case (unsigned char)ENE_LED_CHANNEL_DRAM:
case (unsigned char)ENE_LED_CHANNEL_DRAM_2:
case (unsigned char)ENE_LED_CHANNEL_DRAM_3:
return(ene_channels[5]);
break;
case (unsigned char)ENE_LED_CHANNEL_PCIE:
return(ene_channels[6]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER:
return(ene_channels[7]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER_2:
return(ene_channels[8]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER_3:
return(ene_channels[9]);
break;
default:
return(ene_channels[11]);
break;
}
}
}
unsigned int ENESMBusController::GetLEDCount(unsigned int cfg_zone)
{
LOG_TRACE("[%s] LED Count for zone %02d: %02d", device_version, cfg_zone, config_table[0x03 + cfg_zone]);
return(config_table[0x03 + cfg_zone]);
}
unsigned char ENESMBusController::GetLEDRed(unsigned int led)
{
return(ENERegisterRead(direct_reg + ( 3 * led )));
}
unsigned char ENESMBusController::GetLEDGreen(unsigned int led)
{
return(ENERegisterRead(direct_reg + ( 3 * led ) + 2));
}
unsigned char ENESMBusController::GetLEDBlue(unsigned int led)
{
return(ENERegisterRead(direct_reg + ( 3 * led ) + 1));
}
unsigned char ENESMBusController::GetLEDRedEffect(unsigned int led)
{
return(ENERegisterRead(effect_reg + ( 3 * led )));
}
unsigned char ENESMBusController::GetLEDGreenEffect(unsigned int led)
{
return(ENERegisterRead(effect_reg + ( 3 * led ) + 2));
}
unsigned char ENESMBusController::GetLEDBlueEffect(unsigned int led)
{
return(ENERegisterRead(effect_reg + ( 3 * led ) + 1));
}
void ENESMBusController::SaveMode()
{
ENERegisterWrite(ENE_REG_APPLY, ENE_SAVE_VAL);
}
void ENESMBusController::SetAllColorsDirect(RGBColor* colors)
{
unsigned char* color_buf = new unsigned char[led_count * 3];
unsigned int bytes_sent = 0;
for(unsigned int i = 0; i < (led_count * 3); i += 3)
{
color_buf[i + 0] = RGBGetRValue(colors[i / 3]);
color_buf[i + 1] = RGBGetBValue(colors[i / 3]);
color_buf[i + 2] = RGBGetGValue(colors[i / 3]);
}
while(bytes_sent < (led_count * 3))
{
int bytes_to_send = (led_count * 3) - bytes_sent;
if(bytes_to_send > interface->GetMaxBlock())
{
bytes_to_send = interface->GetMaxBlock();
}
ENERegisterWriteBlock(direct_reg + bytes_sent, &color_buf[bytes_sent], bytes_to_send);
bytes_sent += bytes_to_send;
}
delete[] color_buf;
}
void ENESMBusController::SetAllColorsEffect(RGBColor* colors)
{
unsigned char* color_buf = new unsigned char[led_count * 3];
unsigned int bytes_sent = 0;
for(unsigned int i = 0; i < (led_count * 3); i += 3)
{
color_buf[i + 0] = RGBGetRValue(colors[i / 3]);
color_buf[i + 1] = RGBGetBValue(colors[i / 3]);
color_buf[i + 2] = RGBGetGValue(colors[i / 3]);
}
while(bytes_sent < (led_count * 3))
{
int bytes_to_send = (led_count * 3) - bytes_sent;
if(bytes_to_send > interface->GetMaxBlock())
{
bytes_to_send = interface->GetMaxBlock();
}
ENERegisterWriteBlock(effect_reg + bytes_sent, &color_buf[bytes_sent], bytes_to_send);
bytes_sent += bytes_to_send;
}
ENERegisterWrite(ENE_REG_APPLY, ENE_APPLY_VAL);
delete[] color_buf;
}
void ENESMBusController::SetDirect(unsigned char direct)
{
ENERegisterWrite(ENE_REG_DIRECT, direct);
ENERegisterWrite(ENE_REG_APPLY, ENE_APPLY_VAL);
}
void ENESMBusController::SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, blue, green };
ENERegisterWriteBlock(direct_reg + ( 3 * led ), colors, 3);
}
void ENESMBusController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char colors[3] = { red, blue, green };
ENERegisterWriteBlock(effect_reg + (3 * led), colors, 3);
ENERegisterWrite(ENE_REG_APPLY, ENE_APPLY_VAL);
}
void ENESMBusController::SetMode(unsigned char mode, unsigned char speed, unsigned char direction)
{
ENERegisterWrite(ENE_REG_MODE, mode);
ENERegisterWrite(ENE_REG_SPEED, speed);
ENERegisterWrite(ENE_REG_DIRECTION, direction);
ENERegisterWrite(ENE_REG_APPLY, ENE_APPLY_VAL);
}
bool ENESMBusController::SupportsMode14()
{
return(supports_mode_14);
}
void ENESMBusController::UpdateDeviceName()
{
for (int i = 0; i < 16; i++)
{
device_version[i] = ENERegisterRead(ENE_REG_DEVICE_NAME + i);
}
}
unsigned char ENESMBusController::ENERegisterRead(ene_register reg)
{
return(interface->ENERegisterRead(dev, reg));
}
void ENESMBusController::ENERegisterWrite(ene_register reg, unsigned char val)
{
interface->ENERegisterWrite(dev, reg, val);
}
void ENESMBusController::ENERegisterWriteBlock(ene_register reg, unsigned char * data, unsigned char sz)
{
interface->ENERegisterWriteBlock(dev, reg, data, sz);
}
@@ -0,0 +1,146 @@
/*---------------------------------------------------------*\
| ENESMBusController.h |
| |
| Driver for ENE SMBus devices |
| |
| Adam Honse (CalcProgrammer1) 19 Aug 2018 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include "ENESMBusInterface.h"
#include "RGBController.h"
#define ENE_APPLY_VAL 0x01 /* Value for Apply Changes Register */
#define ENE_SAVE_VAL 0xAA /* Value for Save Changes */
#define ENE_NUM_ZONES 8 /* Number of ENE config table zones */
enum
{
ENE_REG_DEVICE_NAME = 0x1000, /* Device String 16 bytes */
ENE_REG_MICRON_CHECK = 0x1030, /* If "Micron" appears here, skip */
ENE_REG_CONFIG_TABLE = 0x1C00, /* Start of LED configuration bytes */
ENE_REG_COLORS_DIRECT = 0x8000, /* Colors for Direct Mode 15 bytes */
ENE_REG_COLORS_EFFECT = 0x8010, /* Colors for Internal Effects 15 bytes */
ENE_REG_DIRECT = 0x8020, /* "Direct Access" Selection Register */
ENE_REG_MODE = 0x8021, /* Mode Selection Register */
ENE_REG_SPEED = 0x8022, /* Speed Control Register */
ENE_REG_DIRECTION = 0x8023, /* Direction Control Register */
ENE_REG_APPLY = 0x80A0, /* Apply Changes Register */
ENE_REG_SLOT_INDEX = 0x80F8, /* Slot Index Register (RAM only) */
ENE_REG_I2C_ADDRESS = 0x80F9, /* I2C Address Register (RAM only) */
ENE_REG_COLORS_DIRECT_V2 = 0x8100, /* Direct Colors (v2) 30 bytes */
ENE_REG_COLORS_EFFECT_V2 = 0x8160, /* Internal Colors (v2) 30 bytes */
};
enum
{
ENE_MODE_OFF = 0, /* OFF mode */
ENE_MODE_STATIC = 1, /* Static color mode */
ENE_MODE_BREATHING = 2, /* Breathing effect mode */
ENE_MODE_FLASHING = 3, /* Flashing effect mode */
ENE_MODE_SPECTRUM_CYCLE = 4, /* Spectrum Cycle mode */
ENE_MODE_RAINBOW = 5, /* Rainbow effect mode */
ENE_MODE_SPECTRUM_CYCLE_BREATHING = 6, /* Rainbow Breathing effect mode */
ENE_MODE_CHASE_FADE = 7, /* Chase with Fade effect mode */
ENE_MODE_SPECTRUM_CYCLE_CHASE_FADE = 8, /* Chase with Fade, Rainbow effect mode */
ENE_MODE_CHASE = 9, /* Chase effect mode */
ENE_MODE_SPECTRUM_CYCLE_CHASE = 10, /* Chase with Rainbow effect mode */
ENE_MODE_SPECTRUM_CYCLE_WAVE = 11, /* Wave effect mode */
ENE_MODE_CHASE_RAINBOW_PULSE = 12, /* Chase with Rainbow Pulse effect mode*/
ENE_MODE_RANDOM_FLICKER = 13, /* Random flicker effect mode */
ENE_MODE_DOUBLE_FADE = 14, /* Rainbow fade to dual color */
ENE_NUMBER_MODES /* Number of Aura modes */
};
enum
{
ENE_SPEED_SLOWEST = 0x04, /* Slowest effect speed */
ENE_SPEED_SLOW = 0x03, /* Slow effect speed */
ENE_SPEED_NORMAL = 0x02, /* Normal effect speed */
ENE_SPEED_FAST = 0x01, /* Fast effect speed */
ENE_SPEED_FASTEST = 0x00, /* Fastest effect speed */
};
enum
{
ENE_DIRECTION_FORWARD = 0x0, /* Forward effect direction */
ENE_DIRECTION_REVERSE = 0x1, /* Reverse effect direction */
};
enum
{
ENE_LED_CHANNEL_DRAM_2 = 0x05, /* DRAM LED channel */
ENE_LED_CHANNEL_DRAM_3 = 0x0E, /* DRAM LED channel */
ENE_LED_CHANNEL_CENTER_START = 0x82, /* Center zone first LED channel */
ENE_LED_CHANNEL_CENTER = 0x83, /* Center zone LED channel */
ENE_LED_CHANNEL_AUDIO = 0x84, /* Audio zone LED channel */
ENE_LED_CHANNEL_BACK_IO = 0x85, /* Back I/O zone LED channel */
ENE_LED_CHANNEL_RGB_HEADER = 0x86, /* RGB Header LED channel */
ENE_LED_CHANNEL_RGB_HEADER_2 = 0x87, /* RGB Header 2 LED channel */
ENE_LED_CHANNEL_BACKPLATE = 0x88, /* Backplate zone LED channel */
ENE_LED_CHANNEL_DRAM = 0x8A, /* DRAM LED channel */
ENE_LED_CHANNEL_PCIE = 0x8B, /* PCIe zone LED channel */
ENE_LED_CHANNEL_RGB_HEADER_3 = 0x91, /* RGB Header 3 LED channel */
};
enum
{
ENE_CONFIG_LED_COUNT = 0x02, /* LED Count configuration offset */
ENE_CONFIG_LED_COUNT_0107 = 0x03, /* LED Count configuration offset */
ENE_CONFIG_LED_COUNT_1110 = 0x03, /* LED Count configuration offset */
ENE_CONFIG_CHANNEL_V1 = 0x13, /* LED Channel configuration offset */
ENE_CONFIG_CHANNEL_V2 = 0x1B, /* LED Channel V2 configuration offset */
};
class ENESMBusController
{
public:
ENESMBusController(ENESMBusInterface* interface, ene_dev_id dev, std::string dev_name, device_type dev_type);
~ENESMBusController();
std::string GetLocation();
std::string GetName();
std::string GetVersion();
device_type GetType();
const char* GetChannelName(unsigned int cfg_zone);
unsigned int GetLEDCount(unsigned int cfg_zone);
unsigned char GetLEDRed(unsigned int led);
unsigned char GetLEDGreen(unsigned int led);
unsigned char GetLEDBlue(unsigned int led);
unsigned char GetLEDRedEffect(unsigned int led);
unsigned char GetLEDGreenEffect(unsigned int led);
unsigned char GetLEDBlueEffect(unsigned int led);
void SaveMode();
void SetAllColorsDirect(RGBColor* colors);
void SetAllColorsEffect(RGBColor* colors);
void SetDirect(unsigned char direct);
void SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char mode, unsigned char speed, unsigned char direction);
bool SupportsMode14();
void UpdateDeviceName();
unsigned char ENERegisterRead(ene_register reg);
void ENERegisterWrite(ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_register reg, unsigned char * data, unsigned char sz);
private:
char device_version[16];
unsigned char config_table[64];
unsigned int led_count;
ene_register direct_reg;
ene_register effect_reg;
unsigned char channel_cfg;
ENESMBusInterface* interface;
ene_dev_id dev;
bool supports_mode_14;
std::string name;
device_type type;
};
@@ -0,0 +1,510 @@
/*---------------------------------------------------------*\
| ENESMBusControllerDetect.cpp |
| |
| Detector for ENE SMBus devices |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <vector>
#include "Detector.h"
#include "ENESMBusController.h"
#include "ENESMBusInterface_i2c_smbus.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_ENESMBus.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include "dmiinfo.h"
#define DETECTOR_NAME "ENE (ASUS Aura) SMBus Controller"
#define VENDOR_NAME "ASUS" //This should match the Vendor name from DMI
using namespace std::chrono_literals;
/*----------------------------------------------------------------------*\
| Windows defines "interface" for some reason. Work around this |
\*----------------------------------------------------------------------*/
#ifdef interface
#undef interface
#endif
/*---------------------------------------------------------*\
| This list contains the available SMBus addresses for |
| mapping ENE RAM |
\*---------------------------------------------------------*/
#define ENE_RAM_ADDRESS_COUNT (sizeof(ene_ram_addresses) / sizeof(ene_ram_addresses[0]))
static const unsigned char ene_ram_addresses[] =
{
0x70,
0x71,
0x72,
0x73,
0x74,
0x75,
0x76,
0x77,
0x4F,
0x66,
0x67,
0x39,
0x3A,
0x3B,
0x3C,
0x3D
};
/*---------------------------------------------------------*\
| This list contains the available SMBus addresses for |
| mapping Aura motherboards |
\*---------------------------------------------------------*/
#define AURA_MOBO_ADDRESS_COUNT (sizeof(aura_mobo_addresses) / sizeof(aura_mobo_addresses[0]))
static const unsigned char aura_mobo_addresses[] =
{
0x40,
0x4E,
0x4F
};
/******************************************************************************************\
* *
* ENERegisterRead *
* *
* A standalone version of the ENESMBusController::ENERegisterRead function for *
* access to ENE devices without instancing the ENESMBusController class or reading *
* the config table from the device. *
* *
\******************************************************************************************/
static unsigned char ENERegisterRead(i2c_smbus_interface* bus, ene_dev_id dev, ene_register reg)
{
//Write ENE register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Read ENE value
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
}
/******************************************************************************************\
* *
* ENERegisterWrite *
* *
* A standalone version of the ENESMBusController::ENERegisterWrite function for *
* access to ENE devices without instancing the ENESMBusController class or reading *
* the config table from the device. *
* *
\******************************************************************************************/
static void ENERegisterWrite(i2c_smbus_interface* bus, ene_dev_id dev, ene_register reg, unsigned char val)
{
//Write ENE register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write ENE value
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
}
/******************************************************************************************\
* *
* TestForENESMBusController *
* *
* Tests the given address to see if an ENE controller exists there. First does a *
* byte read to test for a response, and if so does a simple read at 0xA0 to test *
* for incrementing values 0...F which was observed at this location during data dump *
* *
* Also tests for the string "Micron" in the ENE register space. Crucial (Micron) *
* DRAM modules use an ENE controller with custom, incompatible firmware and must *
* be excluded from this controller. *
* *
\******************************************************************************************/
bool TestForENESMBusController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
LOG_DEBUG("[ENE SMBus] looking for devices at 0x%02X...", address);
int res = bus->i2c_smbus_read_byte(address);
if(res < 0)
{
res = bus->i2c_smbus_read_byte_data(address, 0x00);
}
if(res >= 0)
{
pass = true;
LOG_DEBUG("[ENE SMBus] Detected an I2C device at address %02X, testing register range", address);
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
LOG_VERBOSE("[ENE SMBus] Detection failed testing register %02X. Expected %02X, got %02X.", i, (i - 0xA0), res);
pass = false;
break;
}
}
if(pass)
{
LOG_DEBUG("[ENE SMBus] Checking for Micron string");
char buf[16];
for(int i = 0; i < 16; i++)
{
buf[i] = ENERegisterRead(bus, address, ENE_REG_MICRON_CHECK + i);
}
if(strcmp(buf, "Micron") == 0)
{
LOG_DEBUG("[ENE SMBus] Device %02X is a Micron device, skipping", address);
pass = false;
}
else
{
LOG_VERBOSE("[ENE SMBus] Detection successful, address %02X", address);
}
}
}
return(pass);
} /* TestForENESMBusController() */
/******************************************************************************************\
* *
* DetectENESMBusDRAMControllers *
* *
* Detects ENE SMBus controllers on DRAM devices *
* *
* bus - pointer to i2c_smbus_interface where device is connected *
* dev - I2C address of device *
* *
\******************************************************************************************/
void DetectENESMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
{
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
LOG_DEBUG("[ENE SMBus DRAM] Remapping ENE SMBus RAM modules on 0x77");
for (unsigned int slot = 0; slot < 8; slot++)
{
int res = busses[bus]->i2c_smbus_read_byte(0x77);
if(res < 0)
{
LOG_DEBUG("[ENE SMBus DRAM] No device detected at 0x77, aborting remap");
break;
}
do
{
address_list_idx++;
if(address_list_idx < (int)ENE_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("[ENE SMBus DRAM] Testing address %02X to see if there is a device there", ene_ram_addresses[address_list_idx]);
res = busses[bus]->i2c_smbus_read_byte(ene_ram_addresses[address_list_idx]);
}
else
{
break;
}
} while (res >= 0);
if(address_list_idx < (int)ENE_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("[ENE SMBus DRAM] Remapping slot %d to address %02X", slot, ene_ram_addresses[address_list_idx]);
ENERegisterWrite(busses[bus], 0x77, ENE_REG_SLOT_INDEX, slot);
ENERegisterWrite(busses[bus], 0x77, ENE_REG_I2C_ADDRESS, (ene_ram_addresses[address_list_idx] << 1));
}
}
// Add ENE controllers at their remapped addresses
for (unsigned int address_list_idx = 0; address_list_idx < ENE_RAM_ADDRESS_COUNT; address_list_idx++)
{
if (TestForENESMBusController(busses[bus], ene_ram_addresses[address_list_idx]))
{
ENESMBusInterface_i2c_smbus* interface = new ENESMBusInterface_i2c_smbus(busses[bus]);
ENESMBusController* controller = new ENESMBusController(interface, ene_ram_addresses[address_list_idx], "ENE DRAM", DEVICE_TYPE_DRAM);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
}
}
}
} /* DetectENESMBusDRAMControllers() */
/******************************************************************************************\
* *
* DetectENESMBusMotherboardControllers *
* *
* Detects ENE (ASUS Aura) SMBus controllers on ASUS motherboard devices *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectENESMBusMotherboardControllers(std::vector<i2c_smbus_interface*> &busses)
{
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Add ENE (ASUS Aura) motherboard controllers
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
if(busses[bus]->pci_subsystem_vendor == ASUS_SUB_VEN || busses[bus]->pci_subsystem_vendor == 0 || busses[bus]->pci_subsystem_vendor == 0xFFFF)
{
for (unsigned int address_list_idx = 0; address_list_idx < AURA_MOBO_ADDRESS_COUNT; address_list_idx++)
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_MESSAGE_EN, DETECTOR_NAME, bus, VENDOR_NAME, aura_mobo_addresses[address_list_idx]);
if (TestForENESMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
{
DMIInfo dmi;
ENESMBusInterface_i2c_smbus* interface = new ENESMBusInterface_i2c_smbus(busses[bus]);
ENESMBusController* controller = new ENESMBusController(interface, aura_mobo_addresses[address_list_idx], "ASUS " + dmi.getMainboard(), DEVICE_TYPE_MOTHERBOARD);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
}
}
else
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_FAILURE_EN, DETECTOR_NAME, bus, VENDOR_NAME);
}
}
}
} /* DetectENESMBusMotherboardControllers() */
/******************************************************************************************\
* *
* DetectENESMBusGPUControllers *
* *
* Detects ENE (ASUS Aura) SMBus controllers on ASUS GPU devices *
* *
\******************************************************************************************/
#define GPU_CHECK_DEVICE_MESSAGE_EN "[%s] Bus %02d is a GPU and the subvendor matches the one for %s, looking for a device at 0x%02X"
void DetectENESMBusGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_addr, const std::string& name)
{
if(TestForENESMBusController(bus, i2c_addr))
{
ENESMBusInterface_i2c_smbus* interface = new ENESMBusInterface_i2c_smbus(bus);
ENESMBusController* controller = new ENESMBusController(interface, i2c_addr, name, DEVICE_TYPE_GPU);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
LOG_DEBUG("[ENE SMBus ASUS GPU] Testing for controller at %d failed", i2c_addr);
}
} /* DetectENESMBusGPUControllers() */
REGISTER_I2C_DETECTOR("ENE SMBus DRAM", DetectENESMBusDRAMControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus Motherboard", DetectENESMBusMotherboardControllers);
/*-----------------------------------------*\
| Nvidia GPUs |
\*-----------------------------------------*/
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3050 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3050_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX3050_8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_DEV, ASUS_SUB_VEN, ASUS_KO_RTX_3060_OC_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3060_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_GA104_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3060_O12G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3060_O12G_LHR_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060_O12G_LHR_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3060 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, ASUS_SUB_VEN, ASUS_KO_RTX_3060_O12G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3060 Ti V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_KO_RTX3060TI_O8G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 Ti OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_GDDR6X_DEV,ASUS_SUB_VEN, ASUS_TUF_RTX_3060TI_O8G, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, ASUS_SUB_VEN, ASUS_KO_RTX3060TI_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, ASUS_SUB_VEN, ASUS_KO_RTX3060TI_08G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3060TI_O8G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Ti OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060TI_O8G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3060 Ti OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3060TI_O8G_OC_V2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Ti V2 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060TI_O8G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3060 Ti V2 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3060TI_O8G_V2_2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_O8G_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 V2 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_8G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_O8G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 V2 White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070_O8G_V2_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070_8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, ASUS_SUB_VEN, ASUS_KO_RTX_3070_O8G_GAMING_V1, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3070 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, ASUS_SUB_VEN, ASUS_KO_RTX_3070_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS KO GeForce RTX 3070 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, ASUS_SUB_VEN, ASUS_KO_RTX_3070_O8G_GAMING_V2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070_O8G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3070TI_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 Ti V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070TI_O8G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 Ti V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_GA102_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070TI_O8G_V2_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 Ti V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_GA102_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070TI_O8G_V2_GAMING_3, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3070TI_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_10G_GAMING_PD, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_10G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG GeForce RTX 3080 GUNDAM EDITION", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_10G_GUNDAM_EDITION, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_10G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O10G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O10G_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 V2 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_10G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O10G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 V2 White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O10G_V2_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 V2 Gaming OC ", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_V2_GAMING_8822, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_V2_GAMING_882B, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 V2 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 12G Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 12G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_12G, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 12G OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O12G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3080 12G OC EVA EDITION", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O12G_EVA, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3090 OC EVA EDITION", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_O24G_EVA, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3090 GUNDAM EDITION", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_GUNDAM_EDITION, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 Ti Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080TI_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3080 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG GeForce RTX STRIX 3080 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC GeForce RTX 3080 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080TI_O12G_GAMING_LC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3090 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3090 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_24G_GAMING_V2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 3090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_O24G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090_O24G, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090_O24G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3090 Ti Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090TI_24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 3090 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090TI_O24G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC GeForce RTX 3090 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RTX_3090TI_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4060TI_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4060_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4060TI_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_O12G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_O12G_GAMING_3, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 SUPER Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070S_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 SUPER Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070S_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 SUPER Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070S_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_12G_GAMING_88DD, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_O12G_GAMING_88DC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_O12G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti SUPER Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_SUPER_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti SUPER Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_SUPER_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4070 Ti SUPER Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_SUPER_O16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 Ti Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070TI_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070TI_O12G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 Ti SUPER Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070TI_SUPER_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4070 Ti SUPER Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070TI_SUPER_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 Gaming White", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_O16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_O16G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_16G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_O16G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 SUPER Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080S_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 SUPER OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080S_016G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 SUPER White", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080S_16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4080 SUPER White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080S_016G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 SUPER Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080S_O16G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4080 SUPER Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080S_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080S_O16G_OC_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4090 Gaming OG OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_OG_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_GAMING_3, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RTX_4090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_213S, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING_88F0, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 OC EVA-02", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_024G_EVA_02, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING_8932, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING_8933, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING_WHITE_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_WHITE_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG MATRIX PLATINUM GeForce RTX 4090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_MATRIX_PLATINUM_RTX_4090_24G, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5060_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming BTF White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING_BTF_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 5070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_5070TI_O16G_GAMING_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5080 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5080_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5090 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5090_O32G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5090 Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5090_32G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 OC WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_O16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5080_16G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC BTF", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_BTF, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL LC GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_LC_RTX_5090_O32G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL LC OC GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_LC_OC_RTX_5090_O32G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG MATRIX PLATINUM GeForce RTX 5090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_MATRIX_PLATINUM_RTX_5090_P32G, 0x67);
/*-----------------------------------------*\
| AMD GPUs |
\*-----------------------------------------*/
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX Radeon RX 6600 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI23_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RX_6600XT_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX Radeon RX 6650 XT Gaming", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI23_DEV1, ASUS_SUB_VEN, ASUS_ROG_STRIX_RX_6650XT_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 6700 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_6700XT_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX Radeon RX 6700 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RX_6700XT_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX Radeon RX 6750 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RX_6750XT_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 6800 Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, ASUS_SUB_VEN, ASUS_RX6800_TUF_GAMING_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX Radeon RX 6800 Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, ASUS_SUB_VEN, ASUS_ROG_STRIX_RX_6800_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 6800 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, ASUS_SUB_VEN, ASUS_TUF_RX_6800XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC Radeon RX 6800 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RX6800XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC Radeon RX 6900 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RX6900XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC Radeon RX 6900 XT Gaming OC TOP", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV2, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RX6900XT_O16G_GAMING_TOP, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 6900 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, ASUS_SUB_VEN, ASUS_TUF_RX_6900XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 6900 XT T16G Gaming", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV2, ASUS_SUB_VEN, ASUS_TUF_RX_6900XT_T16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 6950 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV3, ASUS_SUB_VEN, ASUS_TUF_RX_6950XT_016G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC Radeon RX 6950 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV3, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RX_6950XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7600 XT O16G Gaming", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI33_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7600XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7700 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7700XT_012G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7800 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7800 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_GAMING_0606, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7800 XT Gaming White OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_WHITE_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7900 GRE Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900GRE_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7900 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900XT_020G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 7900 XTX Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900XTX_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 9070 Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_9070_016G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF Radeon RX 9070 XT Gaming OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_9070XT_016G_GAMING, 0x67);
@@ -0,0 +1,41 @@
/*---------------------------------------------------------*\
| ENESMBusInterface.h |
| |
| ENE SMBus interface |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
typedef unsigned short ene_register;
typedef unsigned char ene_dev_id;
typedef unsigned int ene_interface_type;
/*-----------------------------------------*\
| Known interface types |
\*-----------------------------------------*/
enum
{
ENE_INTERFACE_TYPE_I2C_SMBUS,
ENE_INTERFACE_TYPE_SPECTRIX_S40G,
ENE_INTERFACE_TYPE_ROG_ARION,
};
class ENESMBusInterface
{
public:
virtual ~ENESMBusInterface() = default;
virtual ene_interface_type GetInterfaceType() = 0;
virtual std::string GetLocation() = 0;
virtual int GetMaxBlock() = 0;
virtual unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg) = 0;
virtual void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val) = 0;
virtual void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz) = 0;
};
@@ -0,0 +1,96 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_ROGArion.cpp |
| |
| ENE SMBus interface for ASUS ROG Arion |
| |
| Adam Honse (CalcProgrammer1) 17 Sep 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "ENESMBusInterface_ROGArion.h"
ENESMBusInterface_ROGArion::ENESMBusInterface_ROGArion(scsi_device* dev_handle, char* dev_path)
{
scsi_dev = dev_handle;
path = dev_path;
}
ENESMBusInterface_ROGArion::~ENESMBusInterface_ROGArion()
{
}
ene_interface_type ENESMBusInterface_ROGArion::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_ROG_ARION);
}
std::string ENESMBusInterface_ROGArion::GetLocation()
{
std::string str(path.begin(), path.end());
return("SCSI: " + str);
}
int ENESMBusInterface_ROGArion::GetMaxBlock()
{
return(24);
}
unsigned char ENESMBusInterface_ROGArion::ENERegisterRead(ene_dev_id /*dev*/, ene_register /*reg*/)
{
/*-----------------------------------------------------------------------------*\
| This interface does not support reading |
\*-----------------------------------------------------------------------------*/
return( 0 );
}
void ENESMBusInterface_ROGArion::ENERegisterWrite(ene_dev_id /*dev*/, ene_register reg, unsigned char val)
{
SendPacket(reg, &val, sizeof(unsigned char));
}
void ENESMBusInterface_ROGArion::ENERegisterWriteBlock(ene_dev_id /*dev*/, ene_register reg, unsigned char * data, unsigned char sz)
{
SendPacket(reg, data, sz);
}
void ENESMBusInterface_ROGArion::SendPacket
(
ene_register reg,
unsigned char * packet,
unsigned char packet_sz
)
{
/*-----------------------------------------------------------------------------*\
| Create buffer to hold CDB |
\*-----------------------------------------------------------------------------*/
unsigned char cdb[16] = {0};
cdb[0] = 0xEC;
cdb[1] = 0x41;
cdb[2] = 0x53;
cdb[3] = ((reg >> 8) & 0x00FF);
cdb[4] = ( reg & 0x00FF );
cdb[5] = 0x00;
cdb[6] = 0x00;
cdb[7] = 0x00;
cdb[8] = 0x00;
cdb[9] = 0x00;
cdb[10] = 0x00;
cdb[11] = 0x00;
cdb[12] = 0x00;
cdb[13] = packet_sz;
cdb[14] = 0x00;
cdb[15] = 0x00;
/*-----------------------------------------------------------------------------*\
| Create buffer to hold sense data |
\*-----------------------------------------------------------------------------*/
unsigned char sense[32] = {0};
/*-----------------------------------------------------------------------------*\
| Write SCSI packet |
\*-----------------------------------------------------------------------------*/
scsi_write(scsi_dev, packet, packet_sz, cdb, 16, sense, 32);
}
@@ -0,0 +1,40 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_ROGArion.h |
| |
| ENE SMBus interface for ASUS ROG Arion |
| |
| Adam Honse (CalcProgrammer1) 17 Sep 2023 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "ENESMBusInterface.h"
#include "scsiapi.h"
class ENESMBusInterface_ROGArion : public ENESMBusInterface
{
public:
ENESMBusInterface_ROGArion(scsi_device* dev_handle, char* dev_path);
~ENESMBusInterface_ROGArion();
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
scsi_device* scsi_dev;
std::string path;
void SendPacket
(
ene_register reg,
unsigned char * packet,
unsigned char packet_sz
);
};
@@ -0,0 +1,215 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_SpectrixS40G_Linux.cpp |
| |
| ENE SMBus interface for XPG Spectrix S40G (Linux) |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstdint>
#include <cstring>
#include <sys/ioctl.h>
#include "ENESMBusInterface_SpectrixS40G_Linux.h"
/*---------------------------------------------------------------------*\
| Functions for submitting NVME admin passthrough command taken from |
| libnvme: https://github.com/linux-nvme/libnvme |
\*---------------------------------------------------------------------*/
#define NVME_IOCTL_ADMIN_CMD _IOWR('N', 0x41, struct nvme_passthru_cmd)
struct nvme_passthru_cmd
{
uint8_t opcode;
uint8_t flags;
uint16_t rsvd1;
uint32_t nsid;
uint32_t cdw2;
uint32_t cdw3;
uint64_t metadata;
uint64_t addr;
uint32_t metadata_len;
uint32_t data_len;
uint32_t cdw10;
uint32_t cdw11;
uint32_t cdw12;
uint32_t cdw13;
uint32_t cdw14;
uint32_t cdw15;
uint32_t timeout_ms;
uint32_t result;
};
static int nvme_submit_passthru(int fd, unsigned long ioctl_cmd,
struct nvme_passthru_cmd *cmd, uint32_t *result)
{
int err = ioctl(fd, ioctl_cmd, cmd);
if (err >= 0 && result)
*result = cmd->result;
return err;
}
static int nvme_passthru(int fd, unsigned long ioctl_cmd, uint8_t opcode,
uint8_t flags, uint16_t rsvd, uint32_t nsid, uint32_t cdw2,
uint32_t cdw3, uint32_t cdw10, uint32_t cdw11, uint32_t cdw12,
uint32_t cdw13, uint32_t cdw14, uint32_t cdw15, uint32_t data_len,
void *data, uint32_t metadata_len, void *metadata,
uint32_t timeout_ms, uint32_t *result)
{
struct nvme_passthru_cmd cmd = {
.opcode = opcode,
.flags = flags,
.rsvd1 = rsvd,
.nsid = nsid,
.cdw2 = cdw2,
.cdw3 = cdw3,
.metadata = (uint64_t)(uintptr_t)metadata,
.addr = (uint64_t)(uintptr_t)data,
.metadata_len = metadata_len,
.data_len = data_len,
.cdw10 = cdw10,
.cdw11 = cdw11,
.cdw12 = cdw12,
.cdw13 = cdw13,
.cdw14 = cdw14,
.cdw15 = cdw15,
.timeout_ms = timeout_ms,
.result = 0,
};
return nvme_submit_passthru(fd, ioctl_cmd, &cmd, result);
}
int nvme_admin_passthru(int fd, uint8_t opcode, uint8_t flags, uint16_t rsvd,
uint32_t nsid, uint32_t cdw2, uint32_t cdw3, uint32_t cdw10,
uint32_t cdw11, uint32_t cdw12, uint32_t cdw13, uint32_t cdw14,
uint32_t cdw15, uint32_t data_len, void *data,
uint32_t metadata_len, void *metadata, uint32_t timeout_ms,
uint32_t *result)
{
return nvme_passthru(fd, NVME_IOCTL_ADMIN_CMD, opcode, flags, rsvd,
nsid, cdw2, cdw3, cdw10, cdw11, cdw12, cdw13,
cdw14, cdw15, data_len, data, metadata_len,
metadata, timeout_ms, result);
}
/*---------------------------------------------------------------------*\
| ENESMBusInterface_SpectrixS40G implementation |
\*---------------------------------------------------------------------*/
ENESMBusInterface_SpectrixS40G::ENESMBusInterface_SpectrixS40G(int fd, char* path)
{
this->nvme_fd = fd;
this->path = path;
}
ENESMBusInterface_SpectrixS40G::~ENESMBusInterface_SpectrixS40G()
{
}
ene_interface_type ENESMBusInterface_SpectrixS40G::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_SPECTRIX_S40G);
}
std::string ENESMBusInterface_SpectrixS40G::GetLocation()
{
return("NVMe: " + path);
}
int ENESMBusInterface_SpectrixS40G::GetMaxBlock()
{
return(24);
}
unsigned char ENESMBusInterface_SpectrixS40G::ENERegisterRead(ene_dev_id dev, ene_register reg)
{
struct nvme_passthru_cmd cfg;
memset(&cfg, 0, sizeof(nvme_passthru_cmd));
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
cfg.opcode = 0xFA;
cfg.cdw12 = (corrected_reg << 16) | (dev << 1);
cfg.cdw13 = 0x81100001;
cfg.data_len = 1;
unsigned char data[1];
unsigned char metadata[1];
unsigned int result;
/*-----------------------------------------------------------------------------*\
| Send the command to the device |
\*-----------------------------------------------------------------------------*/
nvme_admin_passthru(nvme_fd, cfg.opcode, cfg.flags, cfg.rsvd1,
cfg.nsid, cfg.cdw2, cfg.cdw3, cfg.cdw10,
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
metadata, cfg.timeout_ms, &result);
return(data[0]);
}
void ENESMBusInterface_SpectrixS40G::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
{
struct nvme_passthru_cmd cfg;
memset(&cfg, 0, sizeof(nvme_passthru_cmd));
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
cfg.opcode = 0xFB;
cfg.cdw12 = (corrected_reg << 16) | (dev << 1);
cfg.cdw13 = 0x01100001;
cfg.data_len = 1;
unsigned char data[1];
data[0] = val;
unsigned char metadata[1];
unsigned int result;
/*-----------------------------------------------------------------------------*\
| Send the command to the device |
\*-----------------------------------------------------------------------------*/
nvme_admin_passthru(nvme_fd, cfg.opcode, cfg.flags, cfg.rsvd1,
cfg.nsid, cfg.cdw2, cfg.cdw3, cfg.cdw10,
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
metadata, cfg.timeout_ms, &result);
}
void ENESMBusInterface_SpectrixS40G::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
{
struct nvme_passthru_cmd cfg;
memset(&cfg, 0, sizeof(nvme_passthru_cmd));
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
cfg.opcode = 0xFB;
cfg.cdw12 = (corrected_reg << 16) | (dev << 1);
cfg.cdw13 = 0x03100000 | sz;
cfg.data_len = sz;
unsigned char metadata[1];
unsigned int result;
/*-----------------------------------------------------------------------------*\
| Send the command to the device |
\*-----------------------------------------------------------------------------*/
nvme_admin_passthru(nvme_fd, cfg.opcode, cfg.flags, cfg.rsvd1,
cfg.nsid, cfg.cdw2, cfg.cdw3, cfg.cdw10,
cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
metadata, cfg.timeout_ms, &result);
}
@@ -0,0 +1,32 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_SpectrixS40G_Linux.h |
| |
| ENE SMBus interface for XPG Spectrix S40G (Linux) |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "ENESMBusInterface.h"
class ENESMBusInterface_SpectrixS40G : public ENESMBusInterface
{
public:
ENESMBusInterface_SpectrixS40G(int fd, char* path);
~ENESMBusInterface_SpectrixS40G();
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
int nvme_fd;
std::string path;
};
@@ -0,0 +1,261 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_SpectrixS40G_Windows.cpp |
| |
| ENE SMBus interface for XPG Spectrix S40G (Windows) |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <windows.h>
#include <fileapi.h>
#include <nvme.h>
#include <winioctl.h>
#include "ENESMBusInterface_SpectrixS40G_Windows.h"
#include "StringUtils.h"
ENESMBusInterface_SpectrixS40G::ENESMBusInterface_SpectrixS40G(HANDLE fd, wchar_t* path)
{
this->nvme_fd = fd;
this->path = path;
}
ENESMBusInterface_SpectrixS40G::~ENESMBusInterface_SpectrixS40G()
{
}
ene_interface_type ENESMBusInterface_SpectrixS40G::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_SPECTRIX_S40G);
}
std::string ENESMBusInterface_SpectrixS40G::GetLocation()
{
return("NVMe: " + StringUtils::wstring_to_string(path));
}
int ENESMBusInterface_SpectrixS40G::GetMaxBlock()
{
return(24);
}
unsigned char ENESMBusInterface_SpectrixS40G::ENERegisterRead(ene_dev_id dev, ene_register reg)
{
if(nvme_fd != INVALID_HANDLE_VALUE)
{
/*-----------------------------------------------------------------------------*\
| Create buffer to hold STORAGE_PROTOCOL_COMMAND |
| Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command |
| data. Subtract sizeof(DWORD) as the Command field in the structure overlaps |
| the actual command data. |
\*-----------------------------------------------------------------------------*/
unsigned char buffer[sizeof(STORAGE_PROTOCOL_COMMAND) + (sizeof(DWORD) * 34) - sizeof(DWORD)] = {0};
/*-----------------------------------------------------------------------------*\
| Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer |
\*-----------------------------------------------------------------------------*/
PSTORAGE_PROTOCOL_COMMAND command = (PSTORAGE_PROTOCOL_COMMAND)buffer;
/*-----------------------------------------------------------------------------*\
| Fill in STORAGE_PROTOCOL_COMMAND structure |
\*-----------------------------------------------------------------------------*/
command->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
command->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
command->ProtocolType = ProtocolTypeNvme;
command->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
command->ReturnStatus = 0x00000000;
command->ErrorCode = 0x00000000;
command->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
command->ErrorInfoLength = 0x00000040;
command->DataToDeviceTransferLength = 0x00000000;
command->DataFromDeviceTransferLength = 0x00000001;
command->TimeOutValue = 0x00000001;
command->ErrorInfoOffset = 0x00000090;
command->DataToDeviceBufferOffset = 0x00000000;
command->DataFromDeviceBufferOffset = 0x000000D0;
command->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
command->Reserved0 = 0x00000000;
command->FixedProtocolReturnData = 0x00000000;
command->Reserved1[0] = 0x00000000;
command->Reserved1[1] = 0x00000000;
command->Reserved1[2] = 0x00000000;
/*-----------------------------------------------------------------------------*\
| Create ENE Register Write command, filling in the appropriate register and |
| value |
\*-----------------------------------------------------------------------------*/
PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command;
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
CommandValue->CDW0.OPC = 0xFA;
CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1);
CommandValue->u.GENERAL.CDW13 = 0x81100001;
DWORD ExtraValue[18] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
/*-----------------------------------------------------------------------------*\
| Send the STORAGE_PROTOCOL_COMMAND to the device |
\*-----------------------------------------------------------------------------*/
DWORD bytesreturned = 0;
DeviceIoControl(nvme_fd, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, sizeof(buffer), buffer, sizeof(buffer), &bytesreturned, (LPOVERLAPPED)0x0);
/*-----------------------------------------------------------------------------*\
| Copy the ENE Register Write extra data into the STORAGE_PROTOCOL_COMMAND |
| buffer |
\*-----------------------------------------------------------------------------*/
memcpy(ExtraValue, &command->Command + sizeof(NVME_COMMAND), sizeof(ExtraValue));
return((unsigned char)ExtraValue[16]);
}
return(0);
}
void ENESMBusInterface_SpectrixS40G::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
{
if(nvme_fd != INVALID_HANDLE_VALUE)
{
/*-----------------------------------------------------------------------------*\
| Create buffer to hold STORAGE_PROTOCOL_COMMAND |
| Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command |
| data. Subtract sizeof(DWORD) as the Command field in the structure overlaps |
| the actual command data. |
\*-----------------------------------------------------------------------------*/
unsigned char buffer[sizeof(STORAGE_PROTOCOL_COMMAND) + (sizeof(DWORD) * 34) - sizeof(DWORD)];
/*-----------------------------------------------------------------------------*\
| Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer |
\*-----------------------------------------------------------------------------*/
PSTORAGE_PROTOCOL_COMMAND command = (PSTORAGE_PROTOCOL_COMMAND)buffer;
/*-----------------------------------------------------------------------------*\
| Fill in STORAGE_PROTOCOL_COMMAND structure |
\*-----------------------------------------------------------------------------*/
command->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
command->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
command->ProtocolType = ProtocolTypeNvme;
command->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
command->ReturnStatus = 0x00000000;
command->ErrorCode = 0x00000000;
command->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
command->ErrorInfoLength = 0x00000040;
command->DataToDeviceTransferLength = 0x00000001;
command->DataFromDeviceTransferLength = 0x00000000;
command->TimeOutValue = 0x00000001;
command->ErrorInfoOffset = 0x00000090;
command->DataToDeviceBufferOffset = 0x000000D0;
command->DataFromDeviceBufferOffset = 0x00000000;
command->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
command->Reserved0 = 0x00000000;
command->FixedProtocolReturnData = 0x00000000;
command->Reserved1[0] = 0x00000000;
command->Reserved1[1] = 0x00000000;
command->Reserved1[2] = 0x00000000;
/*-----------------------------------------------------------------------------*\
| Create ENE Register Write command, filling in the appropriate register and |
| value |
\*-----------------------------------------------------------------------------*/
PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command;
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
CommandValue->CDW0.OPC = 0xFB;
CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1);
CommandValue->u.GENERAL.CDW13 = 0x01100001;
DWORD ExtraValue[18] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
ExtraValue[16] = val;
/*-----------------------------------------------------------------------------*\
| Copy the ENE Register Write extra data into the STORAGE_PROTOCOL_COMMAND |
| buffer |
\*-----------------------------------------------------------------------------*/
memcpy(&command->Command + sizeof(NVME_COMMAND), ExtraValue, sizeof(ExtraValue));
/*-----------------------------------------------------------------------------*\
| Send the STORAGE_PROTOCOL_COMMAND to the device |
\*-----------------------------------------------------------------------------*/
DeviceIoControl(nvme_fd, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, sizeof(buffer), buffer, sizeof(buffer), 0x0, (LPOVERLAPPED)0x0);
}
}
void ENESMBusInterface_SpectrixS40G::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
{
if(nvme_fd != INVALID_HANDLE_VALUE)
{
/*-----------------------------------------------------------------------------*\
| Create buffer to hold STORAGE_PROTOCOL_COMMAND |
| Size must be enough for the STORAGE_PROTOCOL_COMMAND struct plus the command |
| data. Subtract sizeof(DWORD) as the Command field in the structure overlaps |
| the actual command data. |
\*-----------------------------------------------------------------------------*/
unsigned char buffer[sizeof(STORAGE_PROTOCOL_COMMAND) + (sizeof(DWORD) * 39) - sizeof(DWORD)];
/*-----------------------------------------------------------------------------*\
| Create STORAGE_PROTOCOL_COMMAND pointer and point it to the buffer |
\*-----------------------------------------------------------------------------*/
PSTORAGE_PROTOCOL_COMMAND command = (PSTORAGE_PROTOCOL_COMMAND)buffer;
/*-----------------------------------------------------------------------------*\
| Fill in STORAGE_PROTOCOL_COMMAND structure |
\*-----------------------------------------------------------------------------*/
command->Version = STORAGE_PROTOCOL_STRUCTURE_VERSION;
command->Length = sizeof(STORAGE_PROTOCOL_COMMAND);
command->ProtocolType = ProtocolTypeNvme;
command->Flags = STORAGE_PROTOCOL_COMMAND_FLAG_ADAPTER_REQUEST;
command->ReturnStatus = 0x00000000;
command->ErrorCode = 0x00000000;
command->CommandLength = STORAGE_PROTOCOL_COMMAND_LENGTH_NVME;
command->ErrorInfoLength = 0x00000040;
command->DataToDeviceTransferLength = sz;
command->DataFromDeviceTransferLength = 0x00000000;
command->TimeOutValue = 0x00000001;
command->ErrorInfoOffset = 0x00000090;
command->DataToDeviceBufferOffset = 0x000000D0;
command->DataFromDeviceBufferOffset = 0x00000000;
command->CommandSpecific = STORAGE_PROTOCOL_SPECIFIC_NVME_ADMIN_COMMAND;
command->Reserved0 = 0x00000000;
command->FixedProtocolReturnData = 0x00000000;
command->Reserved1[0] = 0x00000000;
command->Reserved1[1] = 0x00000000;
command->Reserved1[2] = 0x00000000;
/*-----------------------------------------------------------------------------*\
| Create ENE Register Write Block command, filling in the appropriate register |
| and value |
\*-----------------------------------------------------------------------------*/
PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command;
unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF);
CommandValue->CDW0.OPC = 0xFB;
CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1);
CommandValue->u.GENERAL.CDW13 = 0x03100000 | sz;
DWORD ExtraValue[23] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000 };
memcpy(&ExtraValue[16], data, sz);
/*-----------------------------------------------------------------------------*\
| Copy the ENE Register Write Block extra data into the |
| STORAGE_PROTOCOL_COMMAND buffer |
\*-----------------------------------------------------------------------------*/
memcpy(&command->Command + sizeof(NVME_COMMAND), ExtraValue, sizeof(ExtraValue));
/*-----------------------------------------------------------------------------*\
| Send the STORAGE_PROTOCOL_COMMAND to the device |
\*-----------------------------------------------------------------------------*/
DeviceIoControl(nvme_fd, IOCTL_STORAGE_PROTOCOL_COMMAND, buffer, sizeof(buffer), buffer, sizeof(buffer), 0x0, (LPOVERLAPPED)0x0);
}
}
@@ -0,0 +1,33 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_SpectrixS40G_Windows.h |
| |
| ENE SMBus interface for XPG Spectrix S40G (Windows) |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <windows.h>
#include "ENESMBusInterface.h"
class ENESMBusInterface_SpectrixS40G : public ENESMBusInterface
{
public:
ENESMBusInterface_SpectrixS40G(HANDLE fd, wchar_t* path);
~ENESMBusInterface_SpectrixS40G();
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
HANDLE nvme_fd;
std::wstring path;
};
@@ -0,0 +1,72 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_i2c_smbus.cpp |
| |
| ENE SMBus interface for I2C/SMBus |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "ENESMBusInterface_i2c_smbus.h"
ENESMBusInterface_i2c_smbus::ENESMBusInterface_i2c_smbus(i2c_smbus_interface* bus)
{
this->bus = bus;
}
ENESMBusInterface_i2c_smbus::~ENESMBusInterface_i2c_smbus()
{
}
ene_interface_type ENESMBusInterface_i2c_smbus::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_I2C_SMBUS);
}
std::string ENESMBusInterface_i2c_smbus::GetLocation()
{
std::string return_string(bus->device_name);
return("I2C: " + return_string);
}
int ENESMBusInterface_i2c_smbus::GetMaxBlock()
{
return(3);
}
unsigned char ENESMBusInterface_i2c_smbus::ENERegisterRead(ene_dev_id dev, ene_register reg)
{
//Write ENE register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Read ENE value
return(bus->i2c_smbus_read_byte_data(dev, 0x81));
}
void ENESMBusInterface_i2c_smbus::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
{
//Write ENE register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write ENE value
bus->i2c_smbus_write_byte_data(dev, 0x01, val);
}
void ENESMBusInterface_i2c_smbus::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
{
//Write ENE register
bus->i2c_smbus_write_word_data(dev, 0x00, ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
//Write ENE block data
if(bus->i2c_smbus_write_block_data(dev, 0x03, sz, data) == -1)
{
//Fall back to individual byte operations if the block operation fails
for(unsigned int block_byte = 0; block_byte < sz; block_byte++)
{
bus->i2c_smbus_write_byte_data(dev, 0x01, data[block_byte]);
}
}
}
@@ -0,0 +1,32 @@
/*---------------------------------------------------------*\
| ENESMBusInterface_i2c_smbus.h |
| |
| ENE SMBus interface for I2C/SMBus |
| |
| Adam Honse (CalcProgrammer1) 21 Nov 2021 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "ENESMBusInterface.h"
#include "i2c_smbus.h"
class ENESMBusInterface_i2c_smbus : public ENESMBusInterface
{
public:
ENESMBusInterface_i2c_smbus(i2c_smbus_interface* bus);
~ENESMBusInterface_i2c_smbus();
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
i2c_smbus_interface * bus;
};
@@ -0,0 +1,511 @@
/*---------------------------------------------------------*\
| RGBController_ENESMBus.cpp |
| |
| RGBController for ENE SMBus devices |
| |
| Adam Honse (CalcProgrammer1) 13 Jun 2019 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_ENESMBus.h"
#include "LogManager.h"
#include "SettingsManager.h"
#include "ResourceManager.h"
/**------------------------------------------------------------------*\
@name ENE SMBus Device
@category RAM,Motherboard,GPU,Storage
@type SMBus
@save :white_check_mark:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectENESMBusDRAMControllers,DetectENESMBusMotherboardControllers,DetectENESMBusGPUControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_ENESMBus::RGBController_ENESMBus(ENESMBusController * controller_ptr)
{
controller = controller_ptr;
/*---------------------------------------------------------*\
| Get ENEController settings |
\*---------------------------------------------------------*/
json ene_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("ENESMBusSettings");
/*---------------------------------------------------------*\
| Check if save to device is enabled |
\*---------------------------------------------------------*/
unsigned int save_flag = 0;
if(ene_settings.contains("enable_save"))
{
if(ene_settings["enable_save"] == true)
{
save_flag = MODE_FLAG_MANUAL_SAVE;
}
}
/*---------------------------------------------------------*\
| Determine name and type (DRAM or Motherboard) by checking |
| the ENE controller's version string |
\*---------------------------------------------------------*/
name = controller->GetName();
description = "ENE SMBus Device";
version = controller->GetVersion();
location = controller->GetLocation();
type = controller->GetType();
if((version.find("DIMM_LED") != std::string::npos) || (version.find("AUDA") != std::string::npos) )
{
vendor = "ENE";
}
else if(version.find("ROG STRIX ARION") != std::string::npos)
{
vendor = "ASUS";
}
else if(location.find("NVMe:") != std::string::npos)
{
vendor = "XPG";
}
else
{
vendor = "ASUS";
}
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Off;
Off.name = "Off";
Off.value = ENE_MODE_OFF;
Off.flags = save_flag;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = ENE_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | save_flag;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ENE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | save_flag;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = ENE_SPEED_SLOWEST;
Breathing.speed_max = ENE_SPEED_FASTEST;
Breathing.speed = ENE_SPEED_NORMAL;
modes.push_back(Breathing);
mode Flashing;
Flashing.name = "Flashing";
Flashing.value = ENE_MODE_FLASHING;
Flashing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | save_flag;
Flashing.color_mode = MODE_COLORS_PER_LED;
Flashing.speed_min = ENE_SPEED_SLOWEST;
Flashing.speed_max = ENE_SPEED_FASTEST;
Flashing.speed = ENE_SPEED_NORMAL;
modes.push_back(Flashing);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = ENE_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | save_flag;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
SpectrumCycle.speed_min = ENE_SPEED_SLOWEST;
SpectrumCycle.speed_max = ENE_SPEED_FASTEST;
SpectrumCycle.speed = ENE_SPEED_NORMAL;
modes.push_back(SpectrumCycle);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = ENE_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | save_flag;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed_min = ENE_SPEED_SLOWEST;
Rainbow.speed_max = ENE_SPEED_FASTEST;
Rainbow.speed = ENE_SPEED_NORMAL;
Rainbow.direction = MODE_DIRECTION_LEFT;
modes.push_back(Rainbow);
mode ChaseFade;
ChaseFade.name = "Chase Fade";
ChaseFade.value = ENE_MODE_CHASE_FADE;
ChaseFade.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | save_flag;
ChaseFade.color_mode = MODE_COLORS_PER_LED;
ChaseFade.speed_min = ENE_SPEED_SLOWEST;
ChaseFade.speed_max = ENE_SPEED_FASTEST;
ChaseFade.speed = ENE_SPEED_NORMAL;
ChaseFade.direction = MODE_DIRECTION_LEFT;
modes.push_back(ChaseFade);
mode Chase;
Chase.name = "Chase";
Chase.value = ENE_MODE_CHASE;
Chase.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | save_flag;
Chase.color_mode = MODE_COLORS_PER_LED;
Chase.speed_min = ENE_SPEED_SLOWEST;
Chase.speed_max = ENE_SPEED_FASTEST;
Chase.speed = ENE_SPEED_NORMAL;
ChaseFade.direction = MODE_DIRECTION_LEFT;
modes.push_back(Chase);
mode RandomFlicker;
RandomFlicker.name = "Random Flicker";
RandomFlicker.value = ENE_MODE_RANDOM_FLICKER;
RandomFlicker.flags = MODE_FLAG_HAS_SPEED | save_flag;
RandomFlicker.color_mode = MODE_COLORS_NONE;
RandomFlicker.speed_min = ENE_SPEED_SLOWEST;
RandomFlicker.speed_max = ENE_SPEED_FASTEST;
RandomFlicker.speed = ENE_SPEED_NORMAL;
modes.push_back(RandomFlicker);
if(controller->SupportsMode14())
{
mode DoubleFade;
DoubleFade.name = "Double Fade";
DoubleFade.value = ENE_MODE_DOUBLE_FADE;
DoubleFade.flags = MODE_FLAG_HAS_SPEED;
DoubleFade.color_mode = MODE_COLORS_NONE;
DoubleFade.speed_min = ENE_SPEED_SLOWEST;
DoubleFade.speed_max = ENE_SPEED_FASTEST;
DoubleFade.speed = ENE_SPEED_NORMAL;
modes.push_back(DoubleFade);
}
SetupZones();
/*-------------------------------------------------*\
| Initialize active mode |
\*-------------------------------------------------*/
active_mode = GetDeviceMode();
}
RGBController_ENESMBus::~RGBController_ENESMBus()
{
delete controller;
}
int RGBController_ENESMBus::GetDeviceMode()
{
/*-----------------------------------------------------------------*\
| Determine starting mode by reading the mode and direct registers |
\*-----------------------------------------------------------------*/
int dev_mode = controller->ENERegisterRead(ENE_REG_MODE);
int color_mode = MODE_COLORS_PER_LED;
int speed = controller->ENERegisterRead(ENE_REG_SPEED);
int direction = controller->ENERegisterRead(ENE_REG_DIRECTION);
LOG_TRACE("[%s] Retrieved ENE mode from module: %02d", name.c_str(), dev_mode);
if(controller->ENERegisterRead(ENE_REG_DIRECT))
{
dev_mode = 0xFFFF;
}
switch(dev_mode)
{
case ENE_MODE_OFF:
case ENE_MODE_RAINBOW:
case ENE_MODE_SPECTRUM_CYCLE:
case ENE_MODE_RANDOM_FLICKER:
case ENE_MODE_DOUBLE_FADE:
color_mode = MODE_COLORS_NONE;
break;
case ENE_MODE_SPECTRUM_CYCLE_CHASE:
dev_mode = ENE_MODE_CHASE;
color_mode = MODE_COLORS_RANDOM;
break;
case ENE_MODE_SPECTRUM_CYCLE_BREATHING:
dev_mode = ENE_MODE_BREATHING;
color_mode = MODE_COLORS_RANDOM;
break;
case ENE_MODE_SPECTRUM_CYCLE_CHASE_FADE:
dev_mode = ENE_MODE_CHASE_FADE;
color_mode = MODE_COLORS_RANDOM;
break;
}
for(int mode = 0; mode < (int)modes.size(); mode++)
{
if(modes[mode].value == dev_mode)
{
active_mode = mode;
modes[mode].color_mode = color_mode;
if(modes[mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[mode].speed = speed;
}
if(modes[mode].flags & MODE_FLAG_HAS_DIRECTION_LR)
{
modes[mode].direction = direction;
}
break;
}
}
/*---------------------------------------------------------*\
| Initialize colors for each LED |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
unsigned int led = leds[led_idx].value;
unsigned char red;
unsigned char grn;
unsigned char blu;
if(active_mode == 0)
{
red = controller->GetLEDRed(led);
grn = controller->GetLEDGreen(led);
blu = controller->GetLEDBlue(led);
}
else
{
red = controller->GetLEDRedEffect(led);
grn = controller->GetLEDGreenEffect(led);
blu = controller->GetLEDBlueEffect(led);
}
colors[led_idx] = ToRGBColor(red, grn, blu);
}
return(active_mode);
}
void RGBController_ENESMBus::DeviceUpdateLEDs()
{
if(GetMode() == 0)
{
controller->SetAllColorsDirect(&colors[0]);
}
else
{
controller->SetAllColorsEffect(&colors[0]);
}
}
void RGBController_ENESMBus::UpdateZoneLEDs(int zone)
{
for(std::size_t led_idx = 0; led_idx < zones[zone].leds_count; led_idx++)
{
int led = zones[zone].leds[led_idx].value;
RGBColor color = colors[led];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
if(GetMode() == 0)
{
controller->SetLEDColorDirect(led, red, grn, blu);
}
else
{
controller->SetLEDColorEffect(led, red, grn, blu);
}
}
}
void RGBController_ENESMBus::UpdateSingleLED(int led)
{
RGBColor color = colors[led];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
if(GetMode() == 0)
{
controller->SetLEDColorDirect(led, red, grn, blu);
}
else
{
controller->SetLEDColorEffect(led, red, grn, blu);
}
}
void RGBController_ENESMBus::SetupZones()
{
/*---------------------------------------------------------*\
| Search through all LEDs and create zones for each channel |
| type |
\*---------------------------------------------------------*/
for(unsigned int cfg_zone_idx = 0; cfg_zone_idx < ENE_NUM_ZONES; cfg_zone_idx++)
{
/*---------------------------------------------------------*\
| Get the number of LEDs in the zone |
\*---------------------------------------------------------*/
unsigned int leds_in_zone = controller->GetLEDCount(cfg_zone_idx);
if(leds_in_zone > 0)
{
/*---------------------------------------------------------*\
| Search through existing zones to make sure we don't |
| create a duplicate zone |
\*---------------------------------------------------------*/
bool matched = false;
std::size_t existing_zone_idx = 0;
for(existing_zone_idx = 0; existing_zone_idx < zones.size(); existing_zone_idx++)
{
if(controller->GetChannelName(cfg_zone_idx) == zones[existing_zone_idx].name)
{
matched = true;
break;
}
}
/*---------------------------------------------------------*\
| If zone does not already exist, create it |
\*---------------------------------------------------------*/
if(matched == false)
{
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set zone name to channel name |
\*---------------------------------------------------------*/
new_zone->name = controller->GetChannelName(cfg_zone_idx);
/*---------------------------------------------------------*\
| Set zone LED count to LEDs in zone |
\*---------------------------------------------------------*/
new_zone->leds_count = leds_in_zone;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
}
/*---------------------------------------------------------*\
| Otherwise, add the number of LEDs from this zone to the |
| existing one. |
\*---------------------------------------------------------*/
else
{
zones[existing_zone_idx].leds_count += leds_in_zone;
}
}
}
/*---------------------------------------------------------*\
| Finish setting up the zones |
\*---------------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
zones[zone_idx].leds_min = zones[zone_idx].leds_count;
zones[zone_idx].leds_max = zones[zone_idx].leds_count;
if(zones[zone_idx].leds_count > 1)
{
zones[zone_idx].type = ZONE_TYPE_LINEAR;
}
else
{
zones[zone_idx].type = ZONE_TYPE_SINGLE;
}
zones[zone_idx].matrix_map = NULL;
}
/*---------------------------------------------------------*\
| Create LED entries for each zone |
\*---------------------------------------------------------*/
unsigned int led_idx = 0;
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
for(std::size_t zone_led_idx = 0; zone_led_idx < zones[zone_idx].leds_count; zone_led_idx++)
{
led* new_led = new led();
new_led->name = zones[zone_idx].name + " LED ";
new_led->name.append(std::to_string(zone_led_idx + 1));
new_led->value = led_idx;
led_idx++;
leds.push_back(*new_led);
}
}
SetupColors();
}
void RGBController_ENESMBus::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_ENESMBus::DeviceUpdateMode()
{
if (modes[active_mode].value == 0xFFFF)
{
controller->SetDirect(true);
}
else
{
int new_mode = modes[active_mode].value;
int new_speed = 0;
int new_direction = 0;
if(modes[active_mode].color_mode == MODE_COLORS_RANDOM)
{
switch(new_mode)
{
case ENE_MODE_CHASE:
new_mode = ENE_MODE_SPECTRUM_CYCLE_CHASE;
break;
case ENE_MODE_BREATHING:
new_mode = ENE_MODE_SPECTRUM_CYCLE_BREATHING;
break;
case ENE_MODE_CHASE_FADE:
new_mode = ENE_MODE_SPECTRUM_CYCLE_CHASE_FADE;
break;
}
}
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
new_speed = modes[active_mode].speed;
}
if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR)
{
switch(modes[active_mode].direction)
{
case MODE_DIRECTION_LEFT:
new_direction = ENE_DIRECTION_FORWARD;
break;
case MODE_DIRECTION_RIGHT:
new_direction = ENE_DIRECTION_REVERSE;
break;
}
}
controller->SetMode(new_mode, new_speed, new_direction);
controller->SetDirect(false);
}
}
void RGBController_ENESMBus::DeviceSaveMode()
{
DeviceUpdateMode();
controller->SaveMode();
}
@@ -0,0 +1,38 @@
/*---------------------------------------------------------*\
| RGBController_ENESMBus.h |
| |
| RGBController for ENE SMBus devices |
| |
| Adam Honse (CalcProgrammer1) 13 Jun 2019 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "ENESMBusController.h"
class RGBController_ENESMBus : public RGBController
{
public:
RGBController_ENESMBus(ENESMBusController* controller_ptr);
~RGBController_ENESMBus();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void DeviceSaveMode();
private:
ENESMBusController* controller;
int GetDeviceMode();
};
@@ -0,0 +1,50 @@
/*---------------------------------------------------------*\
| ROGArionDetect.cpp |
| |
| Detector for ASUS ROG Arion |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "Detector.h"
#include "ENESMBusController.h"
#include "ENESMBusInterface_ROGArion.h"
#include "RGBController_ENESMBus.h"
#include "scsiapi.h"
/******************************************************************************************\
* *
* DetectROGArionControllers *
* *
* Detects ENE SMBus controllers on ASUS ROG Arion devices *
* *
\******************************************************************************************/
void DetectROGArionControllers()
{
scsi_device_info * info = scsi_enumerate(NULL, NULL);
while(info)
{
if(strncmp(info->vendor, "ROG", 3) == 0 && strncmp(info->product, "ESD-S1C", 7) == 0)
{
scsi_device * dev = scsi_open_path(info->path);
if(dev)
{
ENESMBusInterface_ROGArion* interface = new ENESMBusInterface_ROGArion(dev, info->path);
ENESMBusController* controller = new ENESMBusController(interface, 0x67, "Asus ROG Strix Arion", DEVICE_TYPE_STORAGE);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
info = info->next;
}
scsi_free_enumeration(info);
} /* DetectROGArionControllers() */
REGISTER_DETECTOR("ASUS ROG Arion", DetectROGArionControllers);
@@ -0,0 +1,93 @@
/*---------------------------------------------------------*\
| XPGSpectrixS40GDetect_Linux.cpp |
| |
| Detector for XPG Spectrix S40G (Linux) |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <vector>
#include "Detector.h"
#include "ENESMBusController.h"
#include "ENESMBusInterface_SpectrixS40G_Linux.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_ENESMBus.h"
/******************************************************************************************\
* *
* DetectSpectrixS40GControllers *
* *
* Detects ENE SMBus controllers on XPG Spectrix S40G NVMe devices *
* *
\******************************************************************************************/
void DetectSpectrixS40GControllers()
{
/*---------------------------------------------------------------------*\
| Search for /dev/nvmeX nodes with model matching "XPG SPECTRIX S40G" |
\*---------------------------------------------------------------------*/
unsigned int nvme_idx = 0;
while(1)
{
/*-------------------------------------------------*\
| Create the nvme class model path |
\*-------------------------------------------------*/
char nvme_dev_buf[1024];
snprintf(nvme_dev_buf, 1024, "/sys/class/nvme/nvme%d/model", nvme_idx);
/*-------------------------------------------------*\
| Open the input event path to get the name |
\*-------------------------------------------------*/
int nvme_model_fd = open(nvme_dev_buf, O_RDONLY|O_NONBLOCK);
if(nvme_model_fd < 0)
{
break;
}
memset(nvme_dev_buf, 0, 1024);
if(read(nvme_model_fd, nvme_dev_buf, 1024) < 0)
{
LOG_WARNING("[XPG Spectrix S40G] Probing %d, failed to read NVMe model", nvme_idx);
}
else
{
LOG_DEBUG("[XPG Spectrix S40G] Probing %d, model: %s", nvme_idx, nvme_dev_buf);
}
close(nvme_model_fd);
/*-------------------------------------------------*\
| Check if this NVMe device is a SPECTRIX S40G |
\*-------------------------------------------------*/
if(strncmp(nvme_dev_buf, "XPG SPECTRIX S40G", 17) == 0)
{
snprintf(nvme_dev_buf, 1024, "/dev/nvme%d", nvme_idx);
int nvme_fd = open(nvme_dev_buf, O_RDWR);
if(nvme_fd > 0)
{
ENESMBusInterface_SpectrixS40G* interface = new ENESMBusInterface_SpectrixS40G(nvme_fd, nvme_dev_buf);
ENESMBusController* controller = new ENESMBusController(interface, 0x67, "XPG Spectrix S40G", DEVICE_TYPE_STORAGE);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
nvme_idx++;
}
} /* DetectSpectrixS40GControllers() */
REGISTER_DETECTOR( "XPG Spectrix S40G", DetectSpectrixS40GControllers);
@@ -0,0 +1,125 @@
/*---------------------------------------------------------*\
| XPGSpectrixS40GDetect_Windows.cpp |
| |
| Detector for XPG Spectrix S40G (Windows) |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <windows.h>
#include <fileapi.h>
#include <stdio.h>
#include <stdlib.h>
#include "Detector.h"
#include "ENESMBusController.h"
#include "ENESMBusInterface_SpectrixS40G_Windows.h"
#include "RGBController.h"
#include "RGBController_ENESMBus.h"
#define DEVBUFSIZE (128 * 1024)
/*----------------------------------------------------------------------*\
| Windows defines "interface" for some reason. Work around this |
\*----------------------------------------------------------------------*/
#ifdef interface
#undef interface
#endif
/******************************************************************************************\
* *
* Search *
* *
* Search for an NVMe device matching "XPG SPECTRIX S40G" *
* *
\******************************************************************************************/
int Search(wchar_t *dev_name)
{
wchar_t buff[DEVBUFSIZE] = L"";
int wchar_count;
wchar_count = QueryDosDeviceW(NULL, buff, DEVBUFSIZE);
if(wchar_count == 0)
{
return 0;
}
for(int i = 0; i < wchar_count; i++)
{
if(wcsstr(buff + i, L"SCSI#Disk&Ven_NVMe&Prod_XPG_SPECTRIX_S40#"))
{
wcsncpy(dev_name, buff + i, MAX_PATH);
(dev_name)[MAX_PATH - 1] = '\0';
return 1;
}
i += (int)wcslen(buff + i);
}
return 0;
}
/******************************************************************************************\
* *
* OpenDevice *
* *
* Open a handle to the given device path *
* *
\******************************************************************************************/
HANDLE OpenDevice(wchar_t buff[MAX_PATH])
{
wchar_t path[MAX_PATH];
wcscpy(path, L"\\\\?\\");
wcsncat(path, buff, MAX_PATH - 4);
for(size_t i = 0; i < MAX_PATH && path[i] != '\0'; i++)
{
path[i] = tolower(path[i]);
}
wprintf(L"%s\n", path);
HANDLE hDevice = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)0x0, OPEN_EXISTING, 0x0, (HANDLE)0x0);
return(hDevice);
}
/******************************************************************************************\
* *
* DetectSpectrixS40GControllers *
* *
* Detects ENE SMBus controllers on XPG Spectrix S40G NVMe devices *
* *
* Tests for the existance of a file descriptor matching *
* SCSI#Disk&Ven_NVMe&Prod_XPG_SPECTRIX_S40# on Windows machines *
* *
\******************************************************************************************/
void DetectSpectrixS40GControllers()
{
/*-------------------------------------------------------------------------------------------------*\
| https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices |
\*-------------------------------------------------------------------------------------------------*/
wchar_t dev_name[MAX_PATH];
if(Search(dev_name))
{
HANDLE nvme_fd = OpenDevice(dev_name);
if(nvme_fd != INVALID_HANDLE_VALUE)
{
ENESMBusInterface_SpectrixS40G* interface = new ENESMBusInterface_SpectrixS40G(nvme_fd, dev_name);
ENESMBusController* controller = new ENESMBusController(interface, 0x67, "XPG Spectrix S40G", DEVICE_TYPE_STORAGE);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
} /* DetectSpectrixS40GControllers() */
REGISTER_DETECTOR( "XPG Spectrix S40G", DetectSpectrixS40GControllers);