Due to the lack of ready made kernel-land drivers, iCUE implements userland SMBus drivers for common controllers using their kernel RPC in LLAccessService
See code from the eeprom module.
ee1004 is for DDR4
spd5118 is for DDR5 (somebody wrote a driver => source)
iCUE's C# LED driver
iCUE is a mix of qt5 and C#. It seems like a migration is in progress, and fortunately, support for my device was already migrated to C#. The probing part is done in CorsairLink4.Module.Dram.DramLedFactory.GetDramLedDevices.
There are three types of LED controllers: RBG, SingleLed, or RBGPro.
The type of the controller is detected by first probing 0x58 to 0x60, then by parsing the serial number from SPD metadata (It seems like it should really be done the other way around, if the SMBus address of the controller can be deduced from SPD metadata).
https://linuxfr.org/users/benoar/journaux/des-dimms-ddr-rgb-en-smbus-vraiment-pita
https://gitlab.com/CalcProgrammer1/OpenRGB/-/issues/2375
The low level bridge between the C# and kernel seems to be from this company https://www.cpuid-pro.com/products-system-information-kit.php
The kernel driver
LLAccessLib
LLAccessService
The LLAccessService service protocol
Userland SMBus drivers
Due to the lack of ready made kernel-land drivers, iCUE implements userland SMBus drivers for common controllers using their kernel RPC in LLAccessService
datasheet: https://www.intel.com/Assets/PDF/datasheet/290562.pdf
linux driver: https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-piix4.c
Userland ee1004 driver
Making SMBus work on my motherboard
loading the correct module does nothing
Turns out an SMBus driver inside the ACPI tables conflicts with the kernel's driver. https://uefi.org/specs/ACPI/6.4/13_ACPI_System_Mgmt_Bus_Interface_Spec/using-the-smbus-protocols.html https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt https://lwn.net/Articles/391230/
The ACPI smbus driver is called from WMI stuff https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn614028(v=vs.85)?redirectedfrom=MSDN#E6OAC https://paste.awesom.eu/Zelj&ln
The chosen path is to use the already existing kernel driver. Unfortunately, the current driver does not implement auto-probing. https://www.spinics.net/lists/linux-i2c/msg32331.html
See code from the eeprom module. ee1004 is for DDR4 spd5118 is for DDR5 (somebody wrote a driver => source)
iCUE's C# LED driver
iCUE is a mix of qt5 and C#. It seems like a migration is in progress, and fortunately, support for my device was already migrated to C#. The probing part is done in
CorsairLink4.Module.Dram.DramLedFactory.GetDramLedDevices
.There are three types of LED controllers: RBG, SingleLed, or RBGPro. The type of the controller is detected by first probing 0x58 to 0x60, then by parsing the serial number from SPD metadata (It seems like it should really be done the other way around, if the SMBus address of the controller can be deduced from SPD metadata).
https://en.wikipedia.org/wiki/Serial_presence_detect
Single LED driver
There are two known modes:
WriteSMBus(160, ConvertBrightness(brightness))
WriteSMBus(164, slope)
thenWriteSMBus(165, plateau)
. I have no idea what that means.For example, this command turns off the LED for a single LED module: