From 08412f0c73fd80ada2476cf4a2461e647b64ff56 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 19:21:37 +0000 Subject: [PATCH 1/4] Add T-Force Delta RGB DDR5 support (8 LEDs) The T-Force Xtreem controller was DDR4-only and hardcoded 15 LEDs. The T-Force Delta RGB DDR5 uses the same ENE SMBus protocol but has 8 LEDs in a linear (non-folded) bar arrangement. Changes: - Make TForceXtreemController parameterizable: led_count and folded strip layout are now constructor parameters with defaults that preserve existing DDR4 Xtreem behaviour - Replace the XTREEM_LED_OFFSET macro with a GetLEDOffset() method that handles both folded (Xtreem) and linear (Delta) layouts - Make RGBController_TForceXtreem accept a device_name parameter - Use controller->GetLEDCount() in SetupZones() instead of hardcoded 15 - Fix latent bug: new_led.value was never set, causing UpdateZoneLEDs and UpdateSingleLED to always address LED 0 - Refactor shared remap logic into RemapENERamModules() helper - Add DetectTForceDeltaControllers() and register it for SPD_DDR5_SDRAM https://claude.ai/code/session_012VktdCkNKbhAyMyMH5127H --- .../RGBController_TForceXtreem.cpp | 18 +++--- .../RGBController_TForceXtreem.h | 3 +- .../TForceXtreemController.cpp | 55 ++++++++++-------- .../TForceXtreemController.h | 7 ++- .../TForceXtreemControllerDetect.cpp | 58 ++++++++++++++++--- 5 files changed, 101 insertions(+), 40 deletions(-) diff --git a/Controllers/TForceXtreemController/RGBController_TForceXtreem.cpp b/Controllers/TForceXtreemController/RGBController_TForceXtreem.cpp index 0622582d3..268554e39 100644 --- a/Controllers/TForceXtreemController/RGBController_TForceXtreem.cpp +++ b/Controllers/TForceXtreemController/RGBController_TForceXtreem.cpp @@ -14,24 +14,25 @@ #include "ResourceManager.h" /**------------------------------------------------------------------*\ - @name T-Force Xtreem + @name T-Force Xtreem / Delta @category RAM @type SMBus @save :white_check_mark: @direct :white_check_mark: @effects :white_check_mark: - @detectors DetectTForceXtreemControllers + @detectors DetectTForceXtreemControllers,DetectTForceDeltaControllers @comment Verified models: TeamGroup T-Force Xtreem ARGB DDR4 + TeamGroup T-Force Delta RGB DDR5 \*-------------------------------------------------------------------*/ -RGBController_TForceXtreem::RGBController_TForceXtreem(TForceXtreemController * controller_ptr) +RGBController_TForceXtreem::RGBController_TForceXtreem(TForceXtreemController * controller_ptr, const std::string& device_name) { controller = controller_ptr; type = DEVICE_TYPE_DRAM; - name = "T-Force Xtreem RGB"; + name = device_name; vendor = "TeamGroup"; location = controller->GetDeviceLocation(); @@ -416,15 +417,17 @@ void RGBController_TForceXtreem::UpdateSingleLED(int led) void RGBController_TForceXtreem::SetupZones() { + unsigned int led_count = controller->GetLEDCount(); + /*---------------------------------------------------------*\ | Set up zone | \*---------------------------------------------------------*/ zone new_zone; new_zone.name = "DRAM"; new_zone.type = ZONE_TYPE_LINEAR; - new_zone.leds_min = XTREEM_LED_COUNT; - new_zone.leds_max = XTREEM_LED_COUNT; - new_zone.leds_count = XTREEM_LED_COUNT; + new_zone.leds_min = led_count; + new_zone.leds_max = led_count; + new_zone.leds_count = led_count; new_zone.matrix_map = NULL; zones.push_back(new_zone); @@ -436,6 +439,7 @@ void RGBController_TForceXtreem::SetupZones() led new_led; new_led.name = "DRAM LED "; new_led.name.append(std::to_string(led_idx)); + new_led.value = led_idx; leds.push_back(new_led); } diff --git a/Controllers/TForceXtreemController/RGBController_TForceXtreem.h b/Controllers/TForceXtreemController/RGBController_TForceXtreem.h index 40b2b87cc..a9fefe1e9 100644 --- a/Controllers/TForceXtreemController/RGBController_TForceXtreem.h +++ b/Controllers/TForceXtreemController/RGBController_TForceXtreem.h @@ -11,13 +11,14 @@ #pragma once +#include #include "RGBController.h" #include "TForceXtreemController.h" class RGBController_TForceXtreem : public RGBController { public: - RGBController_TForceXtreem(TForceXtreemController* controller_ptr); + RGBController_TForceXtreem(TForceXtreemController* controller_ptr, const std::string& device_name = "T-Force Xtreem RGB"); ~RGBController_TForceXtreem(); void SetupZones(); diff --git a/Controllers/TForceXtreemController/TForceXtreemController.cpp b/Controllers/TForceXtreemController/TForceXtreemController.cpp index 63e3f50d3..d77658d8c 100644 --- a/Controllers/TForceXtreemController/TForceXtreemController.cpp +++ b/Controllers/TForceXtreemController/TForceXtreemController.cpp @@ -13,10 +13,12 @@ #include "TForceXtreemController.h" #include "LogManager.h" -TForceXtreemController::TForceXtreemController(i2c_smbus_interface *bus, ene_dev_id dev) +TForceXtreemController::TForceXtreemController(i2c_smbus_interface *bus, ene_dev_id dev, unsigned int led_count, bool folded) { this->bus = bus; this->dev = dev; + this->led_count = led_count; + this->folded = folded; } TForceXtreemController::~TForceXtreemController() @@ -37,59 +39,66 @@ std::string TForceXtreemController::GetDeviceLocation() unsigned int TForceXtreemController::GetLEDCount() { - return(XTREEM_LED_COUNT); + return(led_count); } -/*---------------------------------------------------*\ -| LEDs are in a single strip that is folded in half. | -| That makes the LED order: 0-14-1-13-2-...-7-9-8 | -\*---------------------------------------------------*/ -#define XTREEM_LED_OFFSET(x) ((((x) & 0x01) > 0) ? XTREEM_LED_COUNT - 1 - ((x) >> 1) : ((x) >> 1)) +/*-----------------------------------------------------------*\ +| For folded strips (e.g. Xtreem), LEDs are in a single strip | +| folded in half, giving order: 0-(N-1)-1-(N-2)-2-... | +| For linear strips (e.g. Delta), offset is simply the index. | +\*-----------------------------------------------------------*/ +unsigned int TForceXtreemController::GetLEDOffset(unsigned int led) +{ + if(folded) + return (led & 0x01) ? led_count - 1 - (led >> 1) : (led >> 1); + else + return led; +} unsigned char TForceXtreemController::GetLEDRed(unsigned int led) { - return(ENERegisterRead(XTREEM_REG_COLORS_DIRECT + ( 3 * XTREEM_LED_OFFSET(led) ))); + return(ENERegisterRead(XTREEM_REG_COLORS_DIRECT + ( 3 * GetLEDOffset(led) ))); } unsigned char TForceXtreemController::GetLEDGreen(unsigned int led) { - return(ENERegisterRead(XTREEM_REG_COLORS_DIRECT + ( 3 * XTREEM_LED_OFFSET(led) ) + 2)); + return(ENERegisterRead(XTREEM_REG_COLORS_DIRECT + ( 3 * GetLEDOffset(led) ) + 2)); } unsigned char TForceXtreemController::GetLEDBlue(unsigned int led) { - return(ENERegisterRead(XTREEM_REG_COLORS_DIRECT + ( 3 * XTREEM_LED_OFFSET(led) ) + 1)); + return(ENERegisterRead(XTREEM_REG_COLORS_DIRECT + ( 3 * GetLEDOffset(led) ) + 1)); } unsigned char TForceXtreemController::GetLEDRedEffect(unsigned int led) { - return(ENERegisterRead(XTREEM_REG_COLORS_EFFECT + ( 3 * XTREEM_LED_OFFSET(led) ))); + return(ENERegisterRead(XTREEM_REG_COLORS_EFFECT + ( 3 * GetLEDOffset(led) ))); } unsigned char TForceXtreemController::GetLEDGreenEffect(unsigned int led) { - return(ENERegisterRead(XTREEM_REG_COLORS_EFFECT + ( 3 * XTREEM_LED_OFFSET(led) ) + 2)); + return(ENERegisterRead(XTREEM_REG_COLORS_EFFECT + ( 3 * GetLEDOffset(led) ) + 2)); } unsigned char TForceXtreemController::GetLEDBlueEffect(unsigned int led) { - return(ENERegisterRead(XTREEM_REG_COLORS_EFFECT + ( 3 * XTREEM_LED_OFFSET(led) ) + 1)); + return(ENERegisterRead(XTREEM_REG_COLORS_EFFECT + ( 3 * GetLEDOffset(led) ) + 1)); } void TForceXtreemController::SetAllColorsDirect(RGBColor* colors) { - unsigned char* color_buf = new unsigned char[XTREEM_LED_COUNT * 3]; + unsigned char* color_buf = new unsigned char[led_count * 3]; unsigned int bytes_sent = 0; - for(unsigned int i = 0; i < XTREEM_LED_COUNT; i++) + for(unsigned int i = 0; i < led_count; i++) { - unsigned int offset = 3 * XTREEM_LED_OFFSET(i); + unsigned int offset = 3 * GetLEDOffset(i); color_buf[offset + 0] = RGBGetRValue(colors[i]); color_buf[offset + 1] = RGBGetBValue(colors[i]); color_buf[offset + 2] = RGBGetGValue(colors[i]); } - while(bytes_sent < (XTREEM_LED_COUNT * 3)) + while(bytes_sent < (led_count * 3)) { ENERegisterWriteBlock(XTREEM_REG_COLORS_DIRECT + bytes_sent, &color_buf[bytes_sent], 3); @@ -101,18 +110,18 @@ void TForceXtreemController::SetAllColorsDirect(RGBColor* colors) void TForceXtreemController::SetAllColorsEffect(RGBColor* colors) { - unsigned char* color_buf = new unsigned char[XTREEM_LED_COUNT * 3]; + unsigned char* color_buf = new unsigned char[led_count * 3]; unsigned int bytes_sent = 0; - for(unsigned int i = 0; i < XTREEM_LED_COUNT; i++) + for(unsigned int i = 0; i < led_count; i++) { - unsigned int offset = 3 * XTREEM_LED_OFFSET(i); + unsigned int offset = 3 * GetLEDOffset(i); color_buf[offset + 0] = RGBGetRValue(colors[i]); color_buf[offset + 1] = RGBGetBValue(colors[i]); color_buf[offset + 2] = RGBGetGValue(colors[i]); } - while(bytes_sent < (XTREEM_LED_COUNT * 3)) + while(bytes_sent < (led_count * 3)) { ENERegisterWriteBlock(XTREEM_REG_COLORS_EFFECT + bytes_sent, &color_buf[bytes_sent], 3); @@ -135,14 +144,14 @@ void TForceXtreemController::SetLEDColorDirect(unsigned int led, unsigned char r { unsigned char colors[3] = { red, blue, green }; - ENERegisterWriteBlock(XTREEM_REG_COLORS_DIRECT + ( 3 * XTREEM_LED_OFFSET(led) ), colors, 3); + ENERegisterWriteBlock(XTREEM_REG_COLORS_DIRECT + ( 3 * GetLEDOffset(led) ), colors, 3); } void TForceXtreemController::SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue) { unsigned char colors[3] = { red, blue, green }; - ENERegisterWriteBlock(XTREEM_REG_COLORS_EFFECT + (3 * XTREEM_LED_OFFSET(led)), colors, 3); + ENERegisterWriteBlock(XTREEM_REG_COLORS_EFFECT + (3 * GetLEDOffset(led)), colors, 3); ENERegisterWrite(XTREEM_REG_APPLY, XTREEM_APPLY_VAL); } diff --git a/Controllers/TForceXtreemController/TForceXtreemController.h b/Controllers/TForceXtreemController/TForceXtreemController.h index 1ca872632..90ced68da 100644 --- a/Controllers/TForceXtreemController/TForceXtreemController.h +++ b/Controllers/TForceXtreemController/TForceXtreemController.h @@ -17,6 +17,7 @@ #define XTREEM_APPLY_VAL 0x01 /* Value for Apply Changes Register */ #define XTREEM_LED_COUNT 15 +#define DELTA_LED_COUNT 8 typedef unsigned short ene_register; typedef unsigned char ene_dev_id; @@ -83,7 +84,7 @@ enum class TForceXtreemController { public: - TForceXtreemController(i2c_smbus_interface *bus, ene_dev_id dev); + TForceXtreemController(i2c_smbus_interface *bus, ene_dev_id dev, unsigned int led_count = XTREEM_LED_COUNT, bool folded = true); ~TForceXtreemController(); std::string GetDeviceLocation(); @@ -106,6 +107,10 @@ class TForceXtreemController void ENERegisterWriteBlock(ene_register reg, unsigned char * data, unsigned char sz); private: + unsigned int GetLEDOffset(unsigned int led); + i2c_smbus_interface * bus; ene_dev_id dev; + unsigned int led_count; + bool folded; }; diff --git a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp index 1423f6627..0c320d7c9 100644 --- a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp +++ b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp @@ -114,21 +114,18 @@ bool TestForTForceXtreemController(i2c_smbus_interface* bus, unsigned char addre /******************************************************************************************\ * * -* DetectTForceXtreemDRAMControllers * +* RemapENERamModules * * * -* Detects T-Force Xtreem controllers on DRAM devices * -* * -* bus - pointer to i2c_smbus_interface where device is connected * -* slots - SPD accessors to occupied slots * +* Remaps ENE RAM modules from the default 0x77 master address to individual * +* per-slot addresses from the xtreem_ram_addresses list. * * * \******************************************************************************************/ -void DetectTForceXtreemControllers(i2c_smbus_interface* bus, std::vector &slots, const std::string &/*name*/) +static void RemapENERamModules(i2c_smbus_interface* bus, std::vector& slots) { - LOG_DEBUG("[%s] Remapping ENE SMBus RAM modules on 0x77", DETECTOR_NAME); - for(SPDWrapper *slot : slots) + for(SPDWrapper* slot : slots) { int address_list_idx = slot->index() - 1; int res; @@ -167,6 +164,22 @@ void DetectTForceXtreemControllers(i2c_smbus_interface* bus, std::vector &slots, const std::string &/*name*/) +{ + RemapENERamModules(bus, slots); // Add ENE controllers at their remapped addresses for(unsigned int address_list_idx = 0; address_list_idx < XTREEM_RAM_ADDRESS_COUNT; address_list_idx++) @@ -181,4 +194,33 @@ void DetectTForceXtreemControllers(i2c_smbus_interface* bus, std::vector& slots, const std::string& /*name*/) +{ + RemapENERamModules(bus, slots); + + // Add ENE controllers at their remapped addresses + for(unsigned int address_list_idx = 0; address_list_idx < XTREEM_RAM_ADDRESS_COUNT; address_list_idx++) + { + if(TestForTForceXtreemController(bus, xtreem_ram_addresses[address_list_idx])) + { + TForceXtreemController* controller = new TForceXtreemController(bus, xtreem_ram_addresses[address_list_idx], DELTA_LED_COUNT, false); + RGBController_TForceXtreem* rgb_controller = new RGBController_TForceXtreem(controller, "T-Force Delta RGB"); + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + } +} /* DetectTForceDeltaControllers() */ + REGISTER_I2C_DIMM_DETECTOR("T-Force Xtreem DDR4 DRAM", DetectTForceXtreemControllers, JEDEC_TEAMGROUP, SPD_DDR4_SDRAM); +REGISTER_I2C_DIMM_DETECTOR("T-Force Delta DDR5 DRAM", DetectTForceDeltaControllers, JEDEC_TEAMGROUP, SPD_DDR5_SDRAM); From beb980d72d86bc9ab3a5d327bf14e6bb2d0ad96d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 20:29:02 +0000 Subject: [PATCH 2/4] Remove non-working T-Force Delta DDR5 custom detector The Delta DDR5 uses the standard ENE SMBus DRAM protocol, not the Xtreem-specific ENE protocol. Testing confirmed the generic ENE DRAM controller already detects both DIMMs with all 8 LEDs correctly. https://claude.ai/code/session_012VktdCkNKbhAyMyMH5127H --- .../TForceXtreemControllerDetect.cpp | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp index 0c320d7c9..8bfceac57 100644 --- a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp +++ b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp @@ -194,33 +194,4 @@ void DetectTForceXtreemControllers(i2c_smbus_interface* bus, std::vector& slots, const std::string& /*name*/) -{ - RemapENERamModules(bus, slots); - - // Add ENE controllers at their remapped addresses - for(unsigned int address_list_idx = 0; address_list_idx < XTREEM_RAM_ADDRESS_COUNT; address_list_idx++) - { - if(TestForTForceXtreemController(bus, xtreem_ram_addresses[address_list_idx])) - { - TForceXtreemController* controller = new TForceXtreemController(bus, xtreem_ram_addresses[address_list_idx], DELTA_LED_COUNT, false); - RGBController_TForceXtreem* rgb_controller = new RGBController_TForceXtreem(controller, "T-Force Delta RGB"); - - ResourceManager::get()->RegisterRGBController(rgb_controller); - } - } -} /* DetectTForceDeltaControllers() */ - REGISTER_I2C_DIMM_DETECTOR("T-Force Xtreem DDR4 DRAM", DetectTForceXtreemControllers, JEDEC_TEAMGROUP, SPD_DDR4_SDRAM); -REGISTER_I2C_DIMM_DETECTOR("T-Force Delta DDR5 DRAM", DetectTForceDeltaControllers, JEDEC_TEAMGROUP, SPD_DDR5_SDRAM); From 39e16bfd993ff5c19bf8e26d54ea02d1a598823f Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 21:00:35 +0000 Subject: [PATCH 3/4] Add T-Force Delta DDR5 detector with correct ENE test pattern The Delta DDR5 uses the ENE 0xExxx register range (same as Xtreem) but responds to the standard ENE test pattern (0xA0-0xAF incrementing 0x00-0x0F) rather than the Xtreem-specific pattern (0x90-0xA0). The generic "ENE SMBus DRAM" detector uses wrong registers (0x8xxx), resulting in only 2 of 8 LEDs being controllable. This adds a dedicated DDR5 detector using the correct test pattern and the TForceXtreem controller which writes to the correct 0xExxx registers. Also refactors RemapENERamModules to accept a test function parameter. https://claude.ai/code/session_012VktdCkNKbhAyMyMH5127H --- .../TForceXtreemControllerDetect.cpp | 91 ++++++++++++++++++- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp index 8bfceac57..be2fb7042 100644 --- a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp +++ b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp @@ -112,6 +112,53 @@ bool TestForTForceXtreemController(i2c_smbus_interface* bus, unsigned char addre } /* TestForTForceXtreemController() */ +/******************************************************************************************\ +* * +* TestForTForceDeltaController * +* * +* Tests the given address to see if an ENE controller exists there using the * +* standard ENE test pattern (0xA0-0xAF incrementing 0x00-0x0F). The Delta DDR5 * +* does not respond to the Xtreem-specific test at 0x90-0xA0. * +* * +\******************************************************************************************/ + +static bool TestForTForceDeltaController(i2c_smbus_interface* bus, unsigned char address) +{ + bool pass = false; + + LOG_DEBUG("[%s] looking for Delta DDR5 devices at 0x%02X...", DETECTOR_NAME, 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("[%s] Detected an I2C device at address %02X, testing ENE register range", DETECTOR_NAME, address); + + for(int i = 0xA0; i < 0xB0; i++) + { + res = bus->i2c_smbus_read_byte_data(address, i); + + if(res != (i - 0xA0)) + { + LOG_VERBOSE("[%s] Delta detection failed testing register %02X. Expected %02X, got %02X.", DETECTOR_NAME, i, (i - 0xA0), res); + + pass = false; + break; + } + } + } + + return(pass); + +} /* TestForTForceDeltaController() */ + /******************************************************************************************\ * * * RemapENERamModules * @@ -121,7 +168,9 @@ bool TestForTForceXtreemController(i2c_smbus_interface* bus, unsigned char addre * * \******************************************************************************************/ -static void RemapENERamModules(i2c_smbus_interface* bus, std::vector& slots) +typedef bool (*ENETestFunction)(i2c_smbus_interface*, unsigned char); + +static void RemapENERamModules(i2c_smbus_interface* bus, std::vector& slots, ENETestFunction test_func) { LOG_DEBUG("[%s] Remapping ENE SMBus RAM modules on 0x77", DETECTOR_NAME); @@ -133,7 +182,7 @@ static void RemapENERamModules(i2c_smbus_interface* bus, std::vector &slots, const std::string &/*name*/) { - RemapENERamModules(bus, slots); + RemapENERamModules(bus, slots, TestForTForceXtreemController); // Add ENE controllers at their remapped addresses for(unsigned int address_list_idx = 0; address_list_idx < XTREEM_RAM_ADDRESS_COUNT; address_list_idx++) @@ -194,4 +243,40 @@ void DetectTForceXtreemControllers(i2c_smbus_interface* bus, std::vector& slots, const std::string& /*name*/) +{ + RemapENERamModules(bus, slots, TestForTForceDeltaController); + + // Add ENE controllers at their remapped addresses + for(unsigned int address_list_idx = 0; address_list_idx < XTREEM_RAM_ADDRESS_COUNT; address_list_idx++) + { + if(TestForTForceDeltaController(bus, xtreem_ram_addresses[address_list_idx])) + { + TForceXtreemController* controller = new TForceXtreemController(bus, xtreem_ram_addresses[address_list_idx], DELTA_LED_COUNT, false); + RGBController_TForceXtreem* rgb_controller = new RGBController_TForceXtreem(controller, "T-Force Delta RGB"); + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + } +} /* DetectTForceDeltaControllers() */ + REGISTER_I2C_DIMM_DETECTOR("T-Force Xtreem DDR4 DRAM", DetectTForceXtreemControllers, JEDEC_TEAMGROUP, SPD_DDR4_SDRAM); +REGISTER_I2C_DIMM_DETECTOR("T-Force Delta DDR5 DRAM", DetectTForceDeltaControllers, JEDEC_TEAMGROUP, SPD_DDR5_SDRAM); From 1e39bb4025988173e783a73e21e3d7e4014f230b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 16 Mar 2026 21:17:19 +0000 Subject: [PATCH 4/4] Change Delta DDR5 detector to bus-based (REGISTER_I2C_DETECTOR) The DIMM-based detector (REGISTER_I2C_DIMM_DETECTOR) relies on DDR5 SPD detection which doesn't work on all systems. Switch to a bus-based detector (REGISTER_I2C_DETECTOR) that scans DRAM SMBus interfaces directly, similar to how the generic ENE DRAM detector works. Users should disable "ENE SMBus DRAM" in Settings > Supported Devices to avoid duplicate detection, as that detector uses wrong registers (0x8xxx instead of 0xExxx) for the Delta DDR5. https://claude.ai/code/session_012VktdCkNKbhAyMyMH5127H --- .../TForceXtreemControllerDetect.cpp | 71 ++++++++++++++++--- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp index be2fb7042..f955b17f4 100644 --- a/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp +++ b/Controllers/TForceXtreemController/TForceXtreemControllerDetect.cpp @@ -13,6 +13,7 @@ #include "LogManager.h" #include "RGBController_TForceXtreem.h" #include "i2c_smbus.h" +#include "pci_ids.h" #define DETECTOR_NAME "TForce Xtreem Controller" @@ -261,22 +262,70 @@ void DetectTForceXtreemControllers(i2c_smbus_interface* bus, std::vector& slots, const std::string& /*name*/) +void DetectTForceDeltaDRAMControllers(std::vector &busses) { - RemapENERamModules(bus, slots, TestForTForceDeltaController); - - // Add ENE controllers at their remapped addresses - for(unsigned int address_list_idx = 0; address_list_idx < XTREEM_RAM_ADDRESS_COUNT; address_list_idx++) + for(unsigned int bus = 0; bus < busses.size(); bus++) { - if(TestForTForceDeltaController(bus, xtreem_ram_addresses[address_list_idx])) + int address_list_idx = -1; + + IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device) { - TForceXtreemController* controller = new TForceXtreemController(bus, xtreem_ram_addresses[address_list_idx], DELTA_LED_COUNT, false); - RGBController_TForceXtreem* rgb_controller = new RGBController_TForceXtreem(controller, "T-Force Delta RGB"); + LOG_DEBUG("[T-Force Delta DDR5] Remapping ENE SMBus RAM modules on 0x77"); - ResourceManager::get()->RegisterRGBController(rgb_controller); + for(unsigned int slot = 0; slot < 8; slot++) + { + if(!TestForTForceDeltaController(busses[bus], 0x77)) + { + LOG_DEBUG("[T-Force Delta DDR5] No device detected at 0x77, aborting remap"); + break; + } + + do + { + address_list_idx++; + + if(address_list_idx < XTREEM_RAM_ADDRESS_COUNT) + { + LOG_DEBUG("[T-Force Delta DDR5] Testing address %02X to see if there is a device there", xtreem_ram_addresses[address_list_idx]); + + int res = busses[bus]->i2c_smbus_write_quick(xtreem_ram_addresses[address_list_idx], I2C_SMBUS_WRITE); + + if(res < 0) + { + break; + } + } + else + { + break; + } + } while(true); + + if(address_list_idx < XTREEM_RAM_ADDRESS_COUNT) + { + LOG_DEBUG("[T-Force Delta DDR5] Remapping slot %d to address %02X", slot, xtreem_ram_addresses[address_list_idx]); + + XtreemRegisterWrite(busses[bus], 0x77, XTREEM_REG_SLOT_INDEX, slot); + XtreemRegisterWrite(busses[bus], 0x77, XTREEM_REG_I2C_ADDRESS, (xtreem_ram_addresses[address_list_idx] << 1)); + } + } + + // Add controllers at their remapped addresses + for(unsigned int addr_idx = 0; addr_idx < XTREEM_RAM_ADDRESS_COUNT; addr_idx++) + { + if(TestForTForceDeltaController(busses[bus], xtreem_ram_addresses[addr_idx])) + { + TForceXtreemController* controller = new TForceXtreemController(busses[bus], xtreem_ram_addresses[addr_idx], DELTA_LED_COUNT, false); + RGBController_TForceXtreem* rgb_controller = new RGBController_TForceXtreem(controller, "T-Force Delta RGB"); + + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + + std::this_thread::sleep_for(1ms); + } } } -} /* DetectTForceDeltaControllers() */ +} /* DetectTForceDeltaDRAMControllers() */ REGISTER_I2C_DIMM_DETECTOR("T-Force Xtreem DDR4 DRAM", DetectTForceXtreemControllers, JEDEC_TEAMGROUP, SPD_DDR4_SDRAM); -REGISTER_I2C_DIMM_DETECTOR("T-Force Delta DDR5 DRAM", DetectTForceDeltaControllers, JEDEC_TEAMGROUP, SPD_DDR5_SDRAM); +REGISTER_I2C_DETECTOR("T-Force Delta DDR5 DRAM", DetectTForceDeltaDRAMControllers);