Update Gigabyte Motherboard USB RGB Controller

This commit is contained in:
Daniel Clark authored and Adam Honse committed 2026-09-04 09:31:50 -05:00
1 parent 1103a567da
commit fd1bc449ae
7 files changed
+471 -145

No files matched your search

@@ -4,8 +4,8 @@
| Gigabyte Fusion 2 USB Device layouts and |
| and mapping to the device IDs stored on chip |
| |
| megadjc 31 Jul 2025 |
| chrism 29 Aug 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
@@ -19,16 +19,16 @@
static const gb_fusion2_zone common_d_led_zone =
{
HDR_D_LED1,
0,
1024,
RGBFUSION2_DLED_LEDS_MIN,
RGBFUSION2_DLED_LEDS_MAX,
"D_LED"
};
static const gb_fusion2_zone common_gc_usb_d_led_zone =
{
LED1,
0,
1024,
RGBFUSION2_DLED_LEDS_MIN,
RGBFUSION2_DLED_LEDS_MAX,
"D_LED"
};
@@ -36,48 +36,48 @@ static const gb_fusion2_zone common_gc_usb_d_led_zone =
static const gb_fusion2_zone common_d_led1_zone =
{
HDR_D_LED1,
0,
1024,
RGBFUSION2_DLED_LEDS_MIN,
RGBFUSION2_DLED_LEDS_MAX,
"D_LED1"
};
static const gb_fusion2_zone common_dled1_dled2_zone =
{
HDR_D_LED1,
0,
1024,
RGBFUSION2_DLED_LEDS_MIN,
RGBFUSION2_DLED_LEDS_MAX,
"D_LED1/D_LED2"
};
static const gb_fusion2_zone common_argb_v2_1_zone =
{
HDR_D_LED1,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_1"
};
static const gb_fusion2_zone alt_argb_v2_1_zone =
{
LED3,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_1"
};
static const gb_fusion2_zone common_argb_v2_1_3_zone =
{
HDR_D_LED1,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_1/ARGB_V2_3"
};
static const gb_fusion2_zone common_d_led2_zone =
{
HDR_D_LED2,
0,
1024,
RGBFUSION2_DLED_LEDS_MIN,
RGBFUSION2_DLED_LEDS_MAX,
"D_LED2"
};
@@ -85,47 +85,47 @@ static const gb_fusion2_zone common_d_led2_aux_zone =
{
HDR_D_LED2,
2,
1024,
RGBFUSION2_DLED_LEDS_MAX,
"D_LED2 + Aux"
};
static const gb_fusion2_zone common_argb_v2_2_zone =
{
HDR_D_LED2,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_2"
};
static const gb_fusion2_zone alt_argb_v2_2_zone =
{
LED4,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_2"
};
static const gb_fusion2_zone common_argb_v2_3_1_zone =
{
HDR_D_LED1,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_3"
};
static const gb_fusion2_zone common_argb_v2_3_zone =
{
HDR_D_LED3,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_3"
};
static const gb_fusion2_zone common_argb_v2_4_zone =
{
HDR_D_LED4,
0,
1024,
RGBFUSION2_57XX_LEDS_MIN,
RGBFUSION2_57XX_LEDS_MAX,
"ARGB_V2_4"
};
@@ -4,8 +4,8 @@
| Gigabyte Fusion 2 USB Device layouts and |
| and mapping to the device IDs stored on chip |
| |
| megadjc 31 Jul 2025 |
| chrism 29 Aug 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-only |
@@ -54,6 +54,8 @@ enum GB_FUSION2_LED_IDX
HDR_D_LED4 = 8,
HDR_D_LED3_ARGB = 0x62,
HDR_D_LED4_ARGB = 0x63,
ONBOARD1_ARGB = 0x64,
ONBOARD2_ARGB = 0x65,
};
/*-------------------------------------------------*\
@@ -4,7 +4,7 @@
| Driver for Gigabyte Aorus RGB Fusion 2 USB motherboard |
| |
| jackun 08 Jan 2020 |
| megadjc 31 Jul 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -55,6 +55,27 @@ static LEDCount LedCountToEnum(unsigned int c)
}
}
static LEDCount LedCountFromEnum(uint8_t count){
switch(count & 0x0F)
{
case LEDS_32:
return LEDS_32;
case LEDS_64:
return LEDS_64;
case LEDS_256:
return LEDS_256;
case LEDS_512:
return LEDS_512;
case LEDS_1024:
default:
return LEDS_1024;
}
}
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char* path, std::string mb_name, uint16_t pid): dev(handle), product_id(pid)
{
name = mb_name;
@@ -96,9 +117,12 @@ bool RGBFusion2USBController::RefreshHardwareInfo()
}
std::memcpy(&report, buffer, sizeof(IT8297Report));
report_loaded = true;
device_num = report.device_num;
description = std::string(report.str_product, 28);
report_loaded = true;
device_num = report.device_num;
fw_id = report.fw_ver >> 24;
description = std::string(report.str_product, 28);
if(std::string::iterator nul = std::find(description.begin(), description.end(), '\0');
nul != description.end())
{
@@ -122,10 +146,12 @@ bool RGBFusion2USBController::RefreshHardwareInfo()
chip_id = text;
}
D_LED1_count = LedCountToEnum(report.curr_led_count_low & 0x0F);
D_LED2_count = LedCountToEnum((report.curr_led_count_low >> 4) & 0x0F);
D_LED3_count = LedCountToEnum(report.curr_led_count_high & 0x0F);
D_LED4_count = LedCountToEnum((report.curr_led_count_high >> 4) & 0x0F);
ARGB_count[0] = LedCountFromEnum(report.argb01_count & 0x0F);
ARGB_count[1] = LedCountFromEnum((report.argb01_count >> 4) & 0x0F);
ARGB_count[2] = LedCountFromEnum(report.argb23_count & 0x0F);
ARGB_count[3] = LedCountFromEnum((report.argb23_count >> 4) & 0x0F);
ARGB_count[4] = LedCountFromEnum(report.argb45_count & 0x0F);
ARGB_count[5] = LedCountFromEnum((report.argb45_count >> 4) & 0x0F);
cal_data.dled[0] = report.cal_strip0;
cal_data.dled[1] = report.cal_strip1;
@@ -148,26 +174,26 @@ bool RGBFusion2USBController::RefreshHardwareInfo()
std::memcpy(&cali, buffer2, sizeof(IT5711Calibration));
cali_loaded = true;
cal_data.dled[2] = cali.cal_strip2;
cal_data.dled[3] = cali.cal_strip3;
cal_data.spare[2] = cali.cal_spare2;
cal_data.spare[3] = cali.cal_spare3;
cal_data.dled[2] = cali.cal_strip2;
cal_data.dled[3] = cali.cal_strip3;
cal_data.dled[4] = cali.cal_strip4;
cal_data.dled[5] = cali.cal_strip5;
}
else
{
cal_data.dled[2] = 0;
cal_data.dled[3] = 0;
cal_data.spare[2] = 0;
cal_data.spare[3] = 0;
cali_loaded = false;
cal_data.dled[2] = 0;
cal_data.dled[3] = 0;
cal_data.dled[4] = 0;
cal_data.dled[5] = 0;
cali_loaded = false;
}
}
else
{
cal_data.dled[2] = 0;
cal_data.dled[3] = 0;
cal_data.spare[2] = 0;
cal_data.spare[3] = 0;
cal_data.dled[2] = 0;
cal_data.dled[3] = 0;
cal_data.dled[4] = 0;
cal_data.dled[5] = 0;
}
return report_loaded;
@@ -248,17 +274,17 @@ EncodedCalibration RGBFusion2USBController::GetCalibration(bool refresh_from_hw)
if(product_id == 0x5711)
{
out.dled[2] = DecodeCalibrationBuffer(cal_data.dled[2]);
out.dled[3] = DecodeCalibrationBuffer(cal_data.dled[3]);
out.spare[2] = DecodeCalibrationBuffer(cal_data.spare[2]);
out.spare[3] = DecodeCalibrationBuffer(cal_data.spare[3]);
out.dled[2] = DecodeCalibrationBuffer(cal_data.dled[2]);
out.dled[3] = DecodeCalibrationBuffer(cal_data.dled[3]);
out.dled[4] = DecodeCalibrationBuffer(cal_data.dled[4]);
out.dled[5] = DecodeCalibrationBuffer(cal_data.dled[5]);
}
else
{
out.dled[2] = "OFF";
out.dled[3] = "OFF";
out.spare[2] = "OFF";
out.spare[3] = "OFF";
out.dled[2] = "OFF";
out.dled[3] = "OFF";
out.dled[4] = "OFF";
out.dled[5] = "OFF";
}
return out;
@@ -278,9 +304,9 @@ bool RGBFusion2USBController::SetCalibration(const EncodedCalibration& cal, bool
&& EncodeCalibrationBuffer(cal.spare[1]) == cal_data.spare[1]
&& (product_id != 0x5711
|| (EncodeCalibrationBuffer(cal.dled[2]) == cal_data.dled[2]
&& EncodeCalibrationBuffer(cal.dled[3]) == cal_data.dled[3]
&& EncodeCalibrationBuffer(cal.spare[2]) == cal_data.spare[2]
&& EncodeCalibrationBuffer(cal.spare[3]) == cal_data.spare[3])))
&& EncodeCalibrationBuffer(cal.dled[3]) == cal_data.dled[3]
&& EncodeCalibrationBuffer(cal.dled[4]) == cal_data.dled[4]
&& EncodeCalibrationBuffer(cal.dled[5]) == cal_data.dled[5])))
{
return true;
}
@@ -297,8 +323,8 @@ bool RGBFusion2USBController::SetCalibration(const EncodedCalibration& cal, bool
{
desired.c.d_strip_c2 = EncodeCalibrationBuffer(cal.dled[2]);
desired.c.d_strip_c3 = EncodeCalibrationBuffer(cal.dled[3]);
desired.c.c_spare2 = EncodeCalibrationBuffer(cal.spare[2]);
desired.c.c_spare3 = EncodeCalibrationBuffer(cal.spare[3]);
desired.c.d_strip_c4 = EncodeCalibrationBuffer(cal.dled[4]);
desired.c.d_strip_c5 = EncodeCalibrationBuffer(cal.dled[5]);
}
int rc = SendPacket(desired.buffer);
@@ -309,7 +335,7 @@ bool RGBFusion2USBController::SetCalibration(const EncodedCalibration& cal, bool
ResetController();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
SaveCalState();
SaveLightingStateToFlash();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
cal_data.dled[0] = desired.c.d_strip_c0;
@@ -320,40 +346,70 @@ bool RGBFusion2USBController::SetCalibration(const EncodedCalibration& cal, bool
if(product_id == 0x5711)
{
cal_data.dled[2] = desired.c.d_strip_c2;
cal_data.dled[3] = desired.c.d_strip_c3;
cal_data.spare[2] = desired.c.c_spare2;
cal_data.spare[3] = desired.c.c_spare3;
cal_data.dled[2] = desired.c.d_strip_c2;
cal_data.dled[3] = desired.c.d_strip_c3;
cal_data.dled[4] = desired.c.d_strip_c4;
cal_data.dled[5] = desired.c.d_strip_c5;
}
else
{
cal_data.dled[2] = 0u;
cal_data.dled[3] = 0u;
cal_data.spare[2] = 0u;
cal_data.spare[3] = 0u;
cal_data.dled[2] = 0u;
cal_data.dled[3] = 0u;
cal_data.dled[4] = 0u;
cal_data.dled[5] = 0u;
}
return true;
}
void RGBFusion2USBController::SetLedCount(unsigned int c0, unsigned int c1, unsigned int c2, unsigned int c3)
void RGBFusion2USBController::SetLedCount(
unsigned int c0,
unsigned int c1,
unsigned int c2,
unsigned int c3,
unsigned int c4,
unsigned int c5)
{
LEDCount new_d1 = LedCountToEnum(c0);
LEDCount new_d2 = LedCountToEnum(c1);
LEDCount new_d3 = LedCountToEnum(c2);
LEDCount new_d4 = LedCountToEnum(c3);
LEDCount new_count[6] =
{
LedCountToEnum(c0),
LedCountToEnum(c1),
LedCountToEnum(c2),
LedCountToEnum(c3),
LedCountToEnum(c4),
LedCountToEnum(c5)
};
if(new_d1 == D_LED1_count && new_d2 == D_LED2_count && new_d3 == D_LED3_count && new_d4 == D_LED4_count)
bool changed = false;
for(unsigned int i = 0; i < 6; i++)
{
if(new_count[i] != ARGB_count[i])
{
changed = true;
break;
}
}
if(!changed)
{
return;
}
D_LED1_count = new_d1;
D_LED2_count = new_d2;
D_LED3_count = new_d3;
D_LED4_count = new_d4;
for(unsigned int i = 0; i < 6; i++)
{
ARGB_count[i] = new_count[i];
}
SendCCReport(0x34, (new_d2 << 4) | new_d1, (new_d4 << 4) | new_d3);
unsigned char buffer[FUSION2_USB_BUFFER_SIZE] = {0};
buffer[0] = report_id;
buffer[1] = 0x34;
buffer[2] = (new_count[1] << 4) | new_count[0];
buffer[3] = (new_count[3] << 4) | new_count[2];
buffer[4] = (new_count[5] << 4) | new_count[4];
SendPacket(buffer);
}
/*---------------------------------------------------------*\
@@ -371,7 +427,7 @@ bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
bitmask = 0x01;
break;
case 0x5711:
bitmask = 0x01 | 0x02 | 0x08 | 0x10;
bitmask = 0x01 | 0x02 | 0x08 | 0x10 | 0x20 | 0x40;
break;
default:
bitmask = 0x01 | 0x02;
@@ -395,6 +451,14 @@ bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
case HDR_D_LED4_ARGB:
bitmask = 0x10;
break;
case LED10:
case ONBOARD1_ARGB:
bitmask = 0x20;
break;
case LED11:
case ONBOARD2_ARGB:
bitmask = 0x40;
break;
default:
bitmask = 0x01;
break;
@@ -416,17 +480,17 @@ bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
}
/*---------------------------------------------------------*\
| Persist LED config data |
| Enable LED Lighting Persistence |
\*---------------------------------------------------------*/
bool RGBFusion2USBController::SaveLEDState(bool e)
bool RGBFusion2USBController::SetPersistentLightingEnabled(bool e)
{
return SendCCReport(0x47, e ? 1 : 0);
}
/*---------------------------------------------------------*\
| Persist calibration |
| Save lighting state to flash |
\*---------------------------------------------------------*/
bool RGBFusion2USBController::SaveCalState()
bool RGBFusion2USBController::SaveLightingStateToFlash()
{
return SendCCReport(0x5E, 0);
}
@@ -440,7 +504,7 @@ bool RGBFusion2USBController::EnableBeat(bool e)
}
/*---------------------------------------------------------*\
| Set Lamp Array mode (MSDL) |
| Set Lamp Array mode |
\*---------------------------------------------------------*/
bool RGBFusion2USBController::EnableLampArray(bool enable)
{
@@ -461,6 +525,11 @@ std::string RGBFusion2USBController::GetDeviceDescription()
return(description);
}
uint8_t RGBFusion2USBController::GetFWID()
{
return(fw_id);
}
std::string RGBFusion2USBController::GetFWVersion()
{
return(version);
@@ -512,6 +581,12 @@ void RGBFusion2USBController::SetStripColors(unsigned int hdr, RGBColor* colors,
case HDR_D_LED4_ARGB:
byteorder = cal_data.dled[3];
break;
case ONBOARD1_ARGB:
byteorder = cal_data.dled[4];
break;
case ONBOARD2_ARGB:
byteorder = cal_data.dled[5];
break;
default:
byteorder = cal_data.dled[0];
break;
@@ -618,7 +693,7 @@ void RGBFusion2USBController::SetLEDEffect(int led, int mode, unsigned int speed
pkt.e.effect_param0 = 7;
break;
case EFFECT_WAVE:
pkt.e.period0 = (((speed + 1)^2) + (speed + 1) + 10) * 5 / 2;
pkt.e.period0 = ((speed + 1) * (speed + 1) + (speed + 1) + 10) * 5 / 2;
pkt.e.effect_param0 = 7;
pkt.e.effect_param1 = 1;
break;
@@ -719,7 +794,8 @@ void RGBFusion2USBController::ResetController()
| Check controller for gen2 ARGB support |
| Checks for supported device number |
| Then checks for supported controllers |
| Then checks for supported feature bit (SaveLEDState) |
| Then checks for supported feature bit |
| (SetPersistentLighting) |
| Finally checks for strip detection value. |
\*---------------------------------------------------------*/
bool RGBFusion2USBController::SupportsGen2() const
@@ -829,10 +905,10 @@ bool RGBFusion2USBController::ScanGen2Strips(uint8_t enabled_headers)
dst.totalLeds = total_leds;
SetLedCount(0, 0, 0, 0);
SetLedCount(0, 0, 0, 0, 0, 0);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
SaveLEDState(false);
SetPersistentLightingEnabled(false);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
@@ -842,7 +918,7 @@ bool RGBFusion2USBController::ScanGen2Strips(uint8_t enabled_headers)
/*---------------------------------------------------------*\
| Check controller for persistent state support |
\*---------------------------------------------------------*/
bool RGBFusion2USBController::SupportsSaveLEDState() const
bool RGBFusion2USBController::SupportsSetPersistentLighting() const
{
return(report_loaded && (report.support_cmd_flag & 0x01));
}
@@ -4,7 +4,7 @@
| Driver for Gigabyte Aorus RGB Fusion 2 USB motherboard |
| |
| jackun 08 Jan 2020 |
| megadjc 31 Jul 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -20,6 +20,14 @@
#include "GigabyteFusion2USB_Devices.h"
#define FUSION2_USB_BUFFER_SIZE 64
#define RGBFUSION2_DLED_LEDS_MIN 0
#define RGBFUSION2_DLED_LEDS_MAX 1024
/*--------------------------------------------------------*\
| IT57xx only supports 256 LED strings |
\*--------------------------------------------------------*/
#define RGBFUSION2_57XX_LEDS_MIN 0
#define RGBFUSION2_57XX_LEDS_MAX 256
/*--------------------------------------------------------*\
| Gen2 scan/info opcode base |
@@ -73,8 +81,8 @@ struct LEDs
\*---------------------------------------------------------*/
struct CalibrationData
{
uint32_t dled[4] = {0, 0, 0, 0};
uint32_t spare[4] = {0, 0, 0, 0};
uint32_t dled[6] = {0, 0, 0, 0, 0, 0};
uint32_t spare[2] = {0, 0};
uint32_t mainboard = 0;
};
@@ -83,8 +91,8 @@ struct CalibrationData
\*---------------------------------------------------------*/
struct EncodedCalibration
{
std::string dled[4];
std::string spare[4];
std::string dled[6];
std::string spare[2];
std::string mainboard;
};
@@ -176,6 +184,12 @@ union PktRGB
case HDR_D_LED4:
header = HDR_D_LED4_ARGB;
break;
case LED10:
header = ONBOARD1_ARGB;
break;
case LED11:
header = ONBOARD2_ARGB;
break;
default:
header = HDR_D_LED1_ARGB;
break;
@@ -271,9 +285,9 @@ struct IT8297Report
uint8_t device_num;
uint8_t strip_detect;
uint32_t fw_ver;
uint8_t curr_led_count_high;
uint8_t curr_led_count_low;
uint8_t strip_ctrl_length1;
uint8_t argb01_count;
uint8_t argb23_count;
uint8_t argb45_count;
uint8_t support_cmd_flag;
char str_product[28];
uint32_t cal_spare0;
@@ -293,8 +307,8 @@ struct IT5711Calibration
uint8_t reserved[3];
uint32_t cal_strip2;
uint32_t cal_strip3;
uint32_t cal_spare2;
uint32_t cal_spare3;
uint32_t cal_strip4;
uint32_t cal_strip5;
uint8_t padding[44];
};
@@ -315,8 +329,8 @@ union CMD_0x33
uint32_t c_spare1 = 0;
uint32_t d_strip_c2 = 0;
uint32_t d_strip_c3 = 0;
uint32_t c_spare2 = 0;
uint32_t c_spare3 = 0;
uint32_t d_strip_c4 = 0;
uint32_t d_strip_c5 = 0;
uint8_t reserved[25];
} c;
@@ -336,14 +350,15 @@ public:
bool ApplyEffect(bool batch_commit = false);
bool SetCalibration(const EncodedCalibration& cal, bool refresh_from_hw);
void SetLedCount(unsigned int c0, unsigned int c1, unsigned int c2, unsigned int c3);
void SetLedCount(unsigned int c0, unsigned int c1, unsigned int c2, unsigned int c3, unsigned int c4, unsigned int c5);
void SetLEDEffect(int led, int mode, unsigned int speed, unsigned char brightness, bool random, uint32_t* color);
bool SetStripBuiltinEffectState(int hdr, bool enable);
void SetStripColors(unsigned int hdr, RGBColor * colors, unsigned int num_colors, int single_led = -1);
bool SupportsGen2() const;
bool ScanGen2Strips(uint8_t hdr_mask);
bool SaveLEDState(bool enable);
bool SupportsSaveLEDState() const;
bool SupportsSetPersistentLighting() const;
bool SetPersistentLightingEnabled(bool enable);
bool SaveLightingStateToFlash();
EncodedCalibration GetCalibration(bool refresh_from_hw = false);
std::string GetDeviceName();
@@ -351,6 +366,7 @@ public:
std::string GetDeviceDescription();
std::string GetDeviceLocation();
std::string GetFWVersion();
uint8_t GetFWID();
uint16_t GetProductID();
std::string GetSerial();
std::vector<Gen2StripInfo> ExportGen2Strips() const;
@@ -363,13 +379,13 @@ private:
uint32_t EncodeCalibrationBuffer(const std::string& rgb_order);
bool RefreshHardwareInfo();
void ResetController();
bool SaveCalState();
bool SendCCReport(uint8_t a, uint8_t b, uint8_t c = 0);
bool SendReport(uint8_t id, uint8_t a, uint8_t b, uint8_t c = 0);
int SendPacket(unsigned char* packet);
hid_device* dev;
uint8_t device_num;
uint8_t fw_id = 0;
uint16_t product_id;
uint32_t effect_zone_mask = 0;
int mode;
@@ -384,8 +400,5 @@ private:
int report_id = 0xCC;
bool report_loaded = false;
bool cali_loaded = false;
LEDCount D_LED1_count;
LEDCount D_LED2_count;
LEDCount D_LED3_count;
LEDCount D_LED4_count;
LEDCount ARGB_count[6];
};
@@ -5,7 +5,7 @@
| motherboard |
| |
| jackun 08 Jan 2020 |
| megadjc 31 Jul 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -5,7 +5,7 @@
| motherboard |
| |
| jackun 08 Jan 2020 |
| megadjc 31 Jul 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -15,6 +15,112 @@
#include "LogManager.h"
#include "RGBController_GigabyteRGBFusion2USB.h"
#include "ResourceManager.h"
struct IT5711ZoneCounts
{
uint16_t led10 = 0;
uint16_t led11 = 0;
};
/*---------------------------------------------------------*\
| Sets LED10/11 counts based on firmware series |
\*---------------------------------------------------------*/
static IT5711ZoneCounts GetIT5711ZoneCounts(uint8_t fw_id, uint32_t lid)
{
switch(fw_id)
{
case 0x00:
return {27, 2};
case 0x02:
switch(lid)
{
case 0x013001DF:
return {4, 6};
case 0x015001DF:
return {6, 6};
default:
return {14, 6};
}
case 0x03:
case 0x08:
return {13, 0};
case 0x05:
case 0x0C:
switch(lid)
{
case 0x016001DF:
return {8, 4};
case 0x028001DF:
return {26, 18};
default:
return {16, 4};
}
case 0x06:
case 0x09:
return {12, 0};
default:
return {};
}
}
static void ApplyIT5711ZoneCounts(gb_fusion2_device* layout, uint8_t fw_id, std::vector<gb_fusion2_zone*>& allocated_zones)
{
const IT5711ZoneCounts counts = GetIT5711ZoneCounts(fw_id, layout->layout_id);
for(uint8_t zone_idx = 0; zone_idx < GB_FUSION2_ZONES_MAX; ++zone_idx)
{
const gb_fusion2_zone* zone = (*layout->zones)[zone_idx];
if(!zone)
{
continue;
}
uint16_t led_count = 0;
switch(zone->idx)
{
case LED10:
led_count = counts.led10;
break;
case LED11:
led_count = counts.led11;
break;
default:
continue;
}
/*-----------------------------------------------------*\
| A zero count means that no firmware mapping is known |
\*-----------------------------------------------------*/
if(led_count == 0)
{
continue;
}
/*-----------------------------------------------------*\
| Static layouts contain const zone objects, so create |
| a mutable per-instance copy before changing the count |
\*-----------------------------------------------------*/
gb_fusion2_zone* new_zone = new gb_fusion2_zone(*zone);
new_zone->leds_min = led_count;
new_zone->leds_max = led_count;
(*layout->zones)[zone_idx] = new_zone;
allocated_zones.push_back(new_zone);
}
}
/**------------------------------------------------------------------*\
@name Gigabyte RGB Fusion 2 USB
@@ -27,7 +133,6 @@
@comment The Fusion 2 USB controller applies to most AMD and
Intel mainboards from the X570 and z390 chipsets onwards.
\*-------------------------------------------------------------------*/
RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController* controller_ptr, std::string detector)
{
controller = controller_ptr;
@@ -41,6 +146,7 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
serial = controller->GetSerial();
product_id = controller->GetProductID();
device_num = controller->GetDeviceNum();
fw_id = controller->GetFWID();
mode Direct;
@@ -231,7 +337,7 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
Wave4.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave4);
if(!controller->SupportsSaveLEDState())
if(!controller->SupportsSetPersistentLighting())
{
for(unsigned int mode_idx = 0; mode_idx < modes.size(); mode_idx++)
{
@@ -254,6 +360,13 @@ RGBController_RGBFusion2USB::~RGBController_RGBFusion2USB()
Shutdown();
if(persist_lighting_on_exit && active_mode >= 0
&& active_mode < static_cast<int>(modes.size())
&& (modes[active_mode].flags & MODE_FLAG_MANUAL_SAVE))
{
DeviceSaveMode();
}
delete controller;
}
@@ -272,6 +385,17 @@ void RGBController_RGBFusion2USB::Init_Controller()
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
nlohmann::json device_settings = settings_manager->GetSettings(detector_name);
/*---------------------------------------------------------*\
| Remove obsolete layout settings |
\*---------------------------------------------------------*/
for(const char* section : {"MotherboardLayouts", "CustomLayout"})
{
if(device_settings.erase(section))
{
settings_changed = true;
}
}
/*---------------------------------------------------------*\
| Checks for Gen2 support and adds flag to json. |
\*---------------------------------------------------------*/
@@ -300,6 +424,16 @@ void RGBController_RGBFusion2USB::Init_Controller()
device_settings[SectionGen2].erase("Enabled");
settings_changed = true;
}
/*-----------------------------------------------------*\
| Remove settings for unsupported Gen2 headers |
\*-----------------------------------------------------*/
for(unsigned int header = header_count; header < 4; ++header)
{
if(device_settings[SectionGen2].erase(gen2_header_keys[header]))
{
settings_changed = true;
}
}
/*-----------------------------------------------------*\
| Create and read the per-header settings |
@@ -325,12 +459,33 @@ void RGBController_RGBFusion2USB::Init_Controller()
controller->ScanGen2Strips(enabled_headers);
}
}
else if(device_settings.contains(SectionGen2))
else if(device_num == 0 && device_settings.contains(SectionGen2))
{
device_settings.erase(SectionGen2);
settings_changed = true;
}
/*---------------------------------------------------------*\
| Persistent lighting on controller teardown |
\*---------------------------------------------------------*/
const bool supports_persistent_save = controller->SupportsSetPersistentLighting();
if(supports_persistent_save)
{
if(!device_settings.contains("PersistLightingOnExit"))
{
device_settings["PersistLightingOnExit"] = false;
settings_changed = true;
}
persist_lighting_on_exit = device_settings["PersistLightingOnExit"];
}
else if(device_num == 0 && device_settings.contains("PersistLightingOnExit"))
{
device_settings.erase("PersistLightingOnExit");
settings_changed = true;
}
if(settings_changed)
{
settings_manager->SetSettings(detector_name, device_settings);
@@ -405,9 +560,40 @@ void RGBController_RGBFusion2USB::Init_Controller()
}
else
{
nlohmann::json& cdata = cal_sec["Data"];
nlohmann::json& cdata = cal_sec["Data"];
const nlohmann::json old_cdata = cdata;
/*-----------------------------------------------------*\
| Migrate legacy ARGB4/5 calibration names |
\*-----------------------------------------------------*/
if(cdata.contains("Spare2"))
{
if(!cdata.contains("ONBOARD1_ARGB"))
{
cdata["ONBOARD1_ARGB"] = cdata["Spare2"];
}
cdata.erase("Spare2");
}
if(cdata.contains("Spare3"))
{
if(!cdata.contains("ONBOARD2_ARGB"))
{
cdata["ONBOARD2_ARGB"] = cdata["Spare3"];
}
cdata.erase("Spare3");
}
FillMissingWith(cdata, hw_cal);
if(cdata != old_cdata)
{
settings_manager->SetSettings(detector_name, device_settings);
settings_manager->SaveSettings();
}
if(!cal_enable)
{
cal_sec["Data"] = WriteCalJsonFrom(hw_cal);
@@ -429,17 +615,17 @@ void RGBController_RGBFusion2USB::Init_Controller()
if(controller->GetProductID() == 0x5711)
{
desired.dled[2] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED3");
desired.dled[3] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED4");
desired.spare[2] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare2");
desired.spare[3] = GET_JSON_VAL_ELSE_OFF(cdata, "Spare3");
desired.dled[2] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED3");
desired.dled[3] = GET_JSON_VAL_ELSE_OFF(cdata, "HDR_D_LED4");
desired.dled[4] = GET_JSON_VAL_ELSE_OFF(cdata, "ONBOARD1_ARGB");
desired.dled[5] = GET_JSON_VAL_ELSE_OFF(cdata, "ONBOARD2_ARGB");
}
else
{
desired.dled[2] = "OFF";
desired.dled[3] = "OFF";
desired.spare[2] = "OFF";
desired.spare[3] = "OFF";
desired.dled[2] = "OFF";
desired.dled[3] = "OFF";
desired.dled[4] = "OFF";
desired.dled[5] = "OFF";
}
controller->SetCalibration(desired, false);
}
@@ -487,6 +673,15 @@ void RGBController_RGBFusion2USB::Init_Controller()
{
LoadCustomLayoutFromJson(device_settings[SectionCustom]["Data"], LedLookup, &instance_layout);
}
/*---------------------------------------------------------*\
| Apply physical onboard ARGB LED counts for IT5711 |
\*---------------------------------------------------------*/
if(product_id == 0x5711)
{
ApplyIT5711ZoneCounts(&instance_layout, fw_id, allocated_zones);
}
/*---------------------------------------------------------------------*\
| Culls the mode support based on layout_id. |
\*---------------------------------------------------------------------*/
@@ -551,7 +746,7 @@ void RGBController_RGBFusion2USB::SetupZones()
zones.resize(num_zones);
unsigned int d1 = 0, d2 = 0, d3 = 0, d4 = 0;
unsigned int d1 = 0, d2 = 0, d3 = 0, d4 = 0, d5 = 0, d6 =0;
/*-----------------------------------------------------*\
| Retrieve the latest Gen2 scan results |
@@ -579,10 +774,12 @@ void RGBController_RGBFusion2USB::SetupZones()
const Gen2StripInfo* gen2_info = nullptr;
bool gen2_zone = zone_at_idx->idx != LED10
&& zone_at_idx->idx != LED11;
/*-------------------------------------------------*\
| Locate the Gen2 result corresponding to this zone |
\*-------------------------------------------------*/
if(supports_gen2 && !fixed_zone)
if(supports_gen2 && !fixed_zone && gen2_zone)
{
unsigned int slot = 0;
@@ -888,6 +1085,12 @@ void RGBController_RGBFusion2USB::SetupZones()
case HDR_D_LED4:
d4 = zones[zone_idx].leds_count;
break;
case LED10:
d5 = zones[zone_idx].leds_count;
break;
case LED11:
d6 = zones[zone_idx].leds_count;
break;
default:
d1 = zones[zone_idx].leds_count;
break;
@@ -895,7 +1098,7 @@ void RGBController_RGBFusion2USB::SetupZones()
}
}
controller->SetLedCount(d1, d2, d3, d4);
controller->SetLedCount(d1, d2, d3, d4, d5, d6);
controller->SetStripBuiltinEffectState(-1, false);
SetupColors();
}
@@ -924,9 +1127,22 @@ void RGBController_RGBFusion2USB::DeviceUpdateLEDs()
controller->ApplyEffect();
controller->SetLEDEffect(2, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
controller->ApplyEffect();
entire_device_effect_active = true;
return;
}
/*---------------------------------------------------------*\
| Tear down the special wave slot before returning to |
| normal per-zone/direct operation |
\*---------------------------------------------------------*/
if(entire_device_effect_active)
{
controller->SetLEDEffect(2, EFFECT_STATIC, 0, 0xFF, false, color);
controller->ApplyEffect();
entire_device_effect_active = false;
}
for(int zone_idx = 0; zone_idx < (int)zones.size(); zone_idx++)
{
mode* selected_mode = &modes[active_mode];
@@ -1225,7 +1441,9 @@ int RGBController_RGBFusion2USB::GetLED_Zone(int led_idx)
void RGBController_RGBFusion2USB::DeviceSaveMode()
{
controller->SaveLEDState(true);
controller->SetPersistentLightingEnabled(true);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
controller->SaveLightingStateToFlash();
}
/*---------------------------------------------------------*\
@@ -1234,15 +1452,16 @@ void RGBController_RGBFusion2USB::DeviceSaveMode()
nlohmann::json RGBController_RGBFusion2USB::WriteCalJsonFrom(const EncodedCalibration& src)
{
nlohmann::json calib_json;
calib_json["HDR_D_LED1"] = src.dled[0];
calib_json["HDR_D_LED2"] = src.dled[1];
calib_json["HDR_D_LED3"] = src.dled[2];
calib_json["HDR_D_LED4"] = src.dled[3];
calib_json["ONBOARD1_ARGB"] = src.dled[4];
calib_json["ONBOARD2_ARGB"] = src.dled[5];
calib_json["Mainboard"] = src.mainboard;
calib_json["Spare0"] = src.spare[0];
calib_json["Spare1"] = src.spare[1];
calib_json["Spare2"] = src.spare[2];
calib_json["Spare3"] = src.spare[3];
return calib_json;
}
@@ -1277,8 +1496,8 @@ void RGBController_RGBFusion2USB::FillMissingWith(nlohmann::json& dst, const Enc
{
set_if_missing("HDR_D_LED3", fb.dled[2]);
set_if_missing("HDR_D_LED4", fb.dled[3]);
set_if_missing("Spare2", fb.spare[2]);
set_if_missing("Spare3", fb.spare[3]);
set_if_missing("ONBOARD1_ARGB", fb.dled[4]);
set_if_missing("ONBOARD2_ARGB", fb.dled[5]);
}
}
@@ -1334,16 +1553,31 @@ void RGBController_RGBFusion2USB::LoadCustomLayoutFromJson(
new_zone->idx = forwardLookup.at(header);
if( header == "HDR_D_LED1"
|| header == "HDR_D_LED2"
|| header == "HDR_D_LED3"
|| header == "HDR_D_LED4")
|| (product_id == 0x5711
&& (header == "HDR_D_LED3"
|| header == "HDR_D_LED4"
|| header == "LED10"
|| header == "LED11"))
|| (product_id == 0x8950
&& (header == "LED3"
|| header == "LED4")))
{
new_zone->leds_min = std::max(json_zone["leds_min"].get<int>(), 1);
new_zone->leds_max = std::min(json_zone["leds_max"].get<int>(), 1024);
if(product_id == 0x5711)
{
new_zone->leds_min = std::max(json_zone["leds_min"].get<int>(), RGBFUSION2_57XX_LEDS_MIN);
new_zone->leds_max = std::min(json_zone["leds_max"].get<int>(), RGBFUSION2_57XX_LEDS_MAX);
}
else
{
new_zone->leds_min = std::max(json_zone["leds_min"].get<int>(), RGBFUSION2_DLED_LEDS_MIN);
new_zone->leds_max = std::min(json_zone["leds_max"].get<int>(), RGBFUSION2_DLED_LEDS_MAX);
}
}
else
{
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_min = 1;
new_zone->leds_max = 1;
}
/*---------------------------------------------------------*\
@@ -5,7 +5,7 @@
| motherboard |
| |
| jackun 08 Jan 2020 |
| megadjc 31 Jul 2025 |
| megadjc 03 Sep 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -19,8 +19,6 @@
#include "GigabyteRGBFusion2USBController.h"
#include "SettingsManager.h"
#define RGBFUSION2_DIGITAL_LEDS_MIN 0
#define RGBFUSION2_DIGITAL_LEDS_MAX 1024
#define RGBFUSION2_BRIGHTNESS_MIN 0
#define RGBFUSION2_BRIGHTNESS_MAX 255
#define RGBFUSION2_SPEED_MIN 9
@@ -65,8 +63,11 @@ private:
RGBFusion2USBController* controller;
uint8_t device_num;
uint8_t fw_id = 0;
RGBColor null_color = 0;
bool supports_gen2 = 0;
bool entire_device_effect_active = false;
bool persist_lighting_on_exit = false;
/*---------------------------------------------------------*\
| The intial value of device_index should point to the |
| layout for the generic_device |