Skip to content

Instantly share code, notes, and snippets.

@aditya-r-m
Last active May 17, 2026 09:56
Show Gist options
  • Select an option

  • Save aditya-r-m/dc006a278274a9615a05587ab965e0df to your computer and use it in GitHub Desktop.

Select an option

Save aditya-r-m/dc006a278274a9615a05587ab965e0df to your computer and use it in GitHub Desktop.
Custom Trident Z DRAM RGB Turndown
// Pieces extracted & trimmed from https://gitlab.com/CalcProgrammer1/OpenRGB
// Basic usage : g++ crgb.cc -o ledoff && ./ledoff
// For turning off RAM LEDs at startup : compile in root home directory & add "@reboot /root/ledoff" to "sudo crontab -e"
#include <cstring>
#include <iostream>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <fcntl.h>
#include <string>
#include <unistd.h>
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef int s32;
typedef unsigned short ene_register;
typedef unsigned char ene_dev_id;
#define ENE_APPLY_VAL 0x01 /* Value for Apply Changes Register */
#define ENE_SAVE_VAL 0xAA /* Value for Save Changes */
#define I2C_SMBUS_WRITE 0
#define I2C_SMBUS_BYTE_DATA 2
#define I2C_SMBUS_WORD_DATA 3
enum {
ENE_REG_MODE = 0x8021, /* Mode Selection Register */
ENE_REG_APPLY = 0x80A0, /* Apply Changes Register */
};
s32 i2c_smbus_xfer(int handle, u8 addr, char read_write, u8 command, int size,
union i2c_smbus_data *data) {
struct i2c_smbus_ioctl_data args;
// Tell I2C host which slave address to transfer to
ioctl(handle, I2C_SLAVE, addr);
args.read_write = read_write;
args.command = command;
args.size = size;
args.data = data;
return ioctl(handle, I2C_SMBUS, &args);
}
s32 i2c_smbus_read_byte(int handle, u8 addr) {
i2c_smbus_data data;
if (i2c_smbus_xfer(handle, addr, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data)) {
return -1;
} else {
return data.byte;
}
}
s32 i2c_smbus_write_byte_data(int handle, u8 addr, u8 command, u8 value) {
i2c_smbus_data data;
data.byte = value;
return i2c_smbus_xfer(handle, addr, I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, &data);
}
s32 i2c_smbus_write_word_data(int handle, u8 addr, u8 command, u16 value) {
i2c_smbus_data data;
data.word = value;
return i2c_smbus_xfer(handle, addr, I2C_SMBUS_WRITE, command,
I2C_SMBUS_WORD_DATA, &data);
}
void ENERegisterWrite(int handle, ene_dev_id dev, ene_register reg,
unsigned char val) {
// Write ENE register
i2c_smbus_write_word_data(handle, dev, 0x00,
((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF));
// Write ENE value
i2c_smbus_write_byte_data(handle, dev, 0x01, val);
}
int main() {
char device_string[1024];
DIR *dir;
char driver_path[512];
struct dirent *ent;
int test_fd;
char path[1024];
char buff[100];
unsigned short pci_device, pci_vendor;
char *ptr;
// Start looking for I2C adapters in /sys/bus/i2c/devices/
strcpy(driver_path, "/sys/bus/i2c/devices/");
dir = opendir(driver_path);
if (dir == NULL) {
return 0;
}
// Loop through all entries in i2c-adapter list
ent = readdir(dir);
if (ent == NULL) {
return 0;
}
while (ent != NULL) {
if (ent->d_type == DT_DIR || ent->d_type == DT_LNK) {
if (strncmp(ent->d_name, "i2c-", 4) == 0) {
strcpy(device_string, driver_path);
strcat(device_string, ent->d_name);
strcat(device_string, "/name");
test_fd = open(device_string, O_RDONLY);
if (test_fd) {
memset(device_string, 0x00, sizeof(device_string));
read(test_fd, device_string, sizeof(device_string));
device_string[strlen(device_string) - 1] = 0x00;
close(test_fd);
// Clear PCI Information
pci_vendor = 0;
pci_device = 0;
// Get device path
strcpy(path, driver_path);
strcat(path, ent->d_name);
if (ent->d_type == DT_LNK) {
ptr = realpath(path, NULL);
if (ptr == NULL)
continue;
strcpy(path, ptr);
strcat(path, "/..");
free(ptr);
} else {
strcat(path, "/device");
}
ptr = path + strlen(path);
// Get PCI Vendor
strcpy(ptr, "/vendor");
test_fd = open(path, O_RDONLY);
if (test_fd >= 0) {
memset(buff, 0x00, sizeof(buff));
read(test_fd, buff, sizeof(buff));
buff[strlen(buff) - 1] = 0x00;
pci_vendor = strtoul(buff, NULL, 16);
close(test_fd);
}
// Get PCI Device
strcpy(ptr, "/device");
test_fd = open(path, O_RDONLY);
if (test_fd >= 0) {
memset(buff, 0x00, sizeof(buff));
read(test_fd, buff, sizeof(buff));
buff[strlen(buff) - 1] = 0x00;
pci_device = strtoul(buff, NULL, 16);
close(test_fd);
}
strcpy(device_string, "/dev/");
strcat(device_string, ent->d_name);
test_fd = open(device_string, O_RDWR);
if (test_fd < 0) {
ent = readdir(dir);
} else {
if (pci_vendor == 0x1022 && pci_device == 0x790B) {
if (i2c_smbus_read_byte(test_fd, 0x77) > -1) {
ENERegisterWrite(test_fd, 0x77, ENE_REG_MODE, 0);
ENERegisterWrite(test_fd, 0x77, ENE_REG_APPLY, ENE_APPLY_VAL);
}
}
}
}
}
}
ent = readdir(dir);
}
closedir(dir);
return 0;
}
@PsY4

PsY4 commented Nov 7, 2023

Copy link
Copy Markdown

Great job on this ! Thx a lot, I managed to turn off the LEDs on four G.Skill Trident Z RGB DDR4-4000 on my NAS !

Just adding notes to help others :

You NEED to change the vendor and device test on line 172 to match your motherboard i2c bridge.
This code uses an unknown AMD board so it uses 0x1022 / 0x790B
On my Intel Asrock B660M board, I had to use 0x8086 / 0x7AA3

To find out your vendor and device id, you must use:
cat /sys/bus/i2c/devices/i2c-*/device/vendor
cat /sys/bus/i2c/devices/i2c-*/device/device

Edit line 172 with these numbers.
Then, just compile the file using G++ :
g++ -o ledoff crgb.cc

And run it :
./ledoff

@aditya-r-m

Copy link
Copy Markdown
Author

I'm glad this was useful @PsY4 :) Thanks a lot for the added pointers.

@Trogious

Trogious commented Jan 6, 2024

Copy link
Copy Markdown

I had to do some changes for this to work on my setup:

  • MSI z790 Carbon WIFI
  • 4 pieces of: F5-7200J3445G16GX2-TZ5RS

changed code:
https://github.com/Trogious/trident-z5-rgb-off

@aditya-r-m

Copy link
Copy Markdown
Author

Thank you for the added pointer, @Trogious!

@dls7

dls7 commented Aug 23, 2024

Copy link
Copy Markdown

Don´t forget to enable SMBus access before running the script!

@kkm

kkm commented Oct 30, 2024

Copy link
Copy Markdown

I found out that the color black is like the LED being turned off. I took the color as black and there was no light anymore.

@DrDagless

Copy link
Copy Markdown

I had to do some changes for this to work on my setup:

* MSI z790 Carbon WIFI

* 4 pieces of: F5-7200J3445G16GX2-TZ5RS

changed code: https://github.com/Trogious/trident-z5-rgb-off

Thanks so much! And also thanks to @aditya-r-m of course. The changed code for the Z5 ram worked for me on my AMD board.

@madmaximux

madmaximux commented Oct 11, 2025

Copy link
Copy Markdown

I had to do some changes for this to work on my setup:

* MSI z790 Carbon WIFI

* 4 pieces of: F5-7200J3445G16GX2-TZ5RS

changed code: github.com/Trogious/trident-z5-rgb-off

Thanks so much! And also thanks to @aditya-r-m of course. The changed code for the Z5 ram worked for me on my AMD board.

Mine was slightly different (G.SKILL Trident Z5 RGB Series 2x32GB [F5-6400J3239G32GX2-TZ5RW] on an Intel motherboard), so i forked it here: https://github.com/madmaximux/trident-z5-rgb-off.

Thanks @aditya-r-m , @Trogious , and @dls7 !

@aditya-r-m

Copy link
Copy Markdown
Author

Great to see the script being useful, thanks all for extended/improved pointers! :)

@Awnday

Awnday commented Dec 2, 2025

Copy link
Copy Markdown

I'm a huge newbie when it comes to coding and executing scripts. How exactly do I use this? Thank you!

@aditya-r-m

Copy link
Copy Markdown
Author

Hi @Awnday, the first thing you may want to try is downloading and running a pre-built official OpenRGB executable.

Using this script safely will involve a few steps and some familiarity with C/C++ and linux.

  • Comment out all code in the main function, add a simple print statement, compile with a g++ command, and run the output file from bash.
  • Incrementally uncomment code and view print output for variables such as device_string, path, & buffer till you are comfortable with the hardware configuration you are working with.
  • Once the script is configured as intended, you can uncomment ENERegisterWrite, and tag the final executable in startup config for linux cron (or systemd) as mentioned at the top of the file.

Please avoid running the script without thoroughly understanding the code, compilation, & execution steps involved, because worst case it can lead to hardware level issues if done wrong.

@Skartorion

Copy link
Copy Markdown

Hey, thanks for the code! I tweaked it a little bit to suit my 2x16 ddr5 trident z5 (amd motherboard).
here's the code if anyone needs it:
https://github.com/Skartorion/gskill-trindent-z5-rgb/blob/main/crgb.cc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment