From 165d0f7790d04f39fd96d5b344eb162d02906197 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Fri, 19 Nov 2021 13:29:52 -0600 Subject: [PATCH] Add read support to XPG Spectrix S40G in Windows --- .../RGBController_XPGSpectrixS40G.cpp | 2 +- .../XPGSpectrixS40GController.cpp | 200 +++++++++++++++++- .../XPGSpectrixS40GController.h | 2 +- .../XPGSpectrixS40GControllerDetect.cpp | 20 +- 4 files changed, 201 insertions(+), 23 deletions(-) diff --git a/Controllers/XPGSpectrixS40GControllerWindows/RGBController_XPGSpectrixS40G.cpp b/Controllers/XPGSpectrixS40GControllerWindows/RGBController_XPGSpectrixS40G.cpp index 9e435e009..46f5f211f 100644 --- a/Controllers/XPGSpectrixS40GControllerWindows/RGBController_XPGSpectrixS40G.cpp +++ b/Controllers/XPGSpectrixS40GControllerWindows/RGBController_XPGSpectrixS40G.cpp @@ -241,7 +241,7 @@ RGBController_XPGSpectrixS40G::RGBController_XPGSpectrixS40G(XPGSpectrixS40GCont /*-------------------------------------------------*\ | Initialize active mode | \*-------------------------------------------------*/ - //active_mode = GetDeviceMode(); + active_mode = GetDeviceMode(); } RGBController_XPGSpectrixS40G::~RGBController_XPGSpectrixS40G() diff --git a/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.cpp b/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.cpp index 795b9c893..dd26bc396 100644 --- a/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.cpp +++ b/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.cpp @@ -17,6 +17,8 @@ #include #include +using namespace std::chrono_literals; + int XPGSpectrixS40GController::SetHandle(wchar_t buff[MAX_PATH]) { wchar_t path[MAX_PATH]; @@ -67,13 +69,124 @@ static const char* aura_channels[] = /* Aura channel strings "Unknown", }; -XPGSpectrixS40GController::XPGSpectrixS40GController(aura_dev_id dev) +XPGSpectrixS40GController::XPGSpectrixS40GController(wchar_t dev_name[MAX_PATH], aura_dev_id dev) { this->dev = dev; - direct_reg = AURA_REG_COLORS_DIRECT_V2; - effect_reg = AURA_REG_COLORS_EFFECT_V2; - channel_cfg = AURA_CONFIG_CHANNEL_V2; - led_count = 8; + + SetHandle(dev_name); + + AuraUpdateDeviceName(); + + // Read the device configuration table + for (int i = 0; i < 64; i++) + { + config_table[i] = AuraRegisterRead(AURA_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]); + } + + // Read LED count from configuration table + led_count = config_table[AURA_CONFIG_LED_COUNT]; + + // LED-0116 - First generation motherboard controller + if (strcmp(device_name, "LED-0116") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT; + effect_reg = AURA_REG_COLORS_EFFECT; + channel_cfg = AURA_CONFIG_CHANNEL_V1; + } + // DIMM_LED-0102 - First generation DRAM controller (Trident Z RGB) + else if (strcmp(device_name, "DIMM_LED-0102") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT; + effect_reg = AURA_REG_COLORS_EFFECT; + channel_cfg = AURA_CONFIG_CHANNEL_V1; + } + // AUDA0-E6K5-0101 - Second generation DRAM controller (Geil Super Luce) + else if (strcmp(device_name, "AUDA0-E6K5-0101") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT_V2; + effect_reg = AURA_REG_COLORS_EFFECT_V2; + channel_cfg = AURA_CONFIG_CHANNEL_V1; + } + // AUMA0-E6K5-0106 - Second generation motherboard controller + else if (strcmp(device_name, "AUMA0-E6K5-0106") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT_V2; + effect_reg = AURA_REG_COLORS_EFFECT_V2; + channel_cfg = AURA_CONFIG_CHANNEL_V2; + } + // AUMA0-E6K5-0105 - Second generation motherboard controller + else if (strcmp(device_name, "AUMA0-E6K5-0105") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT_V2; + effect_reg = AURA_REG_COLORS_EFFECT_V2; + channel_cfg = AURA_CONFIG_CHANNEL_V2; + } + // AUMA0-E6K5-0104 - Second generation motherboard controller + else if (strcmp(device_name, "AUMA0-E6K5-0104") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT_V2; + effect_reg = AURA_REG_COLORS_EFFECT_V2; + channel_cfg = AURA_CONFIG_CHANNEL_V2; + } + // AUMA0-E8K4-0101 - First generation motherboard controller + else if (strcmp(device_name, "AUMA0-E8K4-0101") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT; + effect_reg = AURA_REG_COLORS_EFFECT; + channel_cfg = AURA_CONFIG_CHANNEL_V1; + } + // AUMA0-E6K5-0107 - Second generation GPU controller + else if (strcmp(device_name, "AUMA0-E6K5-0107") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT_V2; + effect_reg = AURA_REG_COLORS_EFFECT_V2; + channel_cfg = AURA_CONFIG_CHANNEL_V2; + + // Read LED count from configuration table + //led_count = config_table[ENE_CONFIG_LED_COUNT_0107]; + } + // AUDA0-E6K5--100 - Second generation NVMe SSD controller + else if (strcmp(device_name, "AUDA0-E6K5--100") == 0) + { + direct_reg = AURA_REG_COLORS_DIRECT_V2; + effect_reg = AURA_REG_COLORS_EFFECT_V2; + channel_cfg = AURA_CONFIG_CHANNEL_V2; + } + // Assume first generation controller if string does not match + else + { + direct_reg = AURA_REG_COLORS_DIRECT; + effect_reg = AURA_REG_COLORS_EFFECT; + channel_cfg = AURA_CONFIG_CHANNEL_V1; + } } XPGSpectrixS40GController::~XPGSpectrixS40GController() @@ -83,12 +196,12 @@ XPGSpectrixS40GController::~XPGSpectrixS40GController() std::string XPGSpectrixS40GController::GetDeviceName() { - return("SSD"); + return(device_name); } std::string XPGSpectrixS40GController::GetDeviceLocation() { - return("I2C: SSD"); + return("SSD"); } unsigned char XPGSpectrixS40GController::GetChannel(unsigned int led) @@ -245,7 +358,76 @@ void XPGSpectrixS40GController::AuraUpdateDeviceName() unsigned char XPGSpectrixS40GController::AuraRegisterRead(aura_register reg) { - return(0); + if(hDevice != INVALID_HANDLE_VALUE) + { + std::this_thread::sleep_for(10ms); + + /*-----------------------------------------------------------------------------*\ + | 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; + bool result = DeviceIoControl(hDevice, 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(ExtraValue[16]); + } } void XPGSpectrixS40GController::AuraRegisterWrite(aura_register reg, unsigned char val) @@ -298,7 +480,6 @@ void XPGSpectrixS40GController::AuraRegisterWrite(aura_register reg, unsigned ch unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF); CommandValue->CDW0.OPC = 0xFB; - CommandValue->NSID = 0x00000031; CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1); CommandValue->u.GENERAL.CDW13 = 0x01100001; @@ -370,7 +551,6 @@ void XPGSpectrixS40GController::AuraRegisterWriteBlock(aura_register reg, unsign unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF); CommandValue->CDW0.OPC = 0xFB; - CommandValue->NSID = 0x00000031; CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1); CommandValue->u.GENERAL.CDW13 = 0x03100000 | sz; diff --git a/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.h b/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.h index 13460b11d..7c91d0be3 100644 --- a/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.h +++ b/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GController.h @@ -115,7 +115,7 @@ enum class XPGSpectrixS40GController { public: - XPGSpectrixS40GController(aura_dev_id dev); + XPGSpectrixS40GController(wchar_t dev_name[MAX_PATH], aura_dev_id dev); ~XPGSpectrixS40GController(); /*-----------------------------------------------------*\ diff --git a/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GControllerDetect.cpp b/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GControllerDetect.cpp index e023ec554..341d03637 100644 --- a/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GControllerDetect.cpp +++ b/Controllers/XPGSpectrixS40GControllerWindows/XPGSpectrixS40GControllerDetect.cpp @@ -64,18 +64,16 @@ void DetectSpectrixS40GControllers(std::vector& rgb_controllers) if(Search(dev_name)) { - new_xpg_s40g = new XPGSpectrixS40GController(0x67); - int result = new_xpg_s40g->SetHandle(dev_name); + new_xpg_s40g = new XPGSpectrixS40GController(dev_name, 0x67); + + new_controller = new RGBController_XPGSpectrixS40G(new_xpg_s40g); + + new_controller->name = "XPG Spectrix S40G"; + new_controller->vendor = "XPG"; + new_controller->type = DEVICE_TYPE_STORAGE; + + rgb_controllers.push_back(new_controller); - if(result) - { - new_controller = new RGBController_XPGSpectrixS40G(new_xpg_s40g); - rgb_controllers.push_back(new_controller); - } - else - { - delete new_xpg_s40g; - } } } /* DetectSpectrixS40GControllers() */