Publish LumaOps source

This commit is contained in:
LumaOps release export
2026-09-03 01:18:36 +02:00
commit 7f1c0e5f71
2363 changed files with 501543 additions and 0 deletions
@@ -0,0 +1,303 @@
/*---------------------------------------------------------*\
| RGBController_RealtekBridge.cpp |
| |
| Controller for Realtek USB to SSD Bridge ICs |
| |
| Jerry Fan (JerryFan0612) 13 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_RealtekBridge.h"
/**------------------------------------------------------------------*\
@name Realtek Bridge Device
@category Storage
@type USB
@save :x:
@direct :rotating_light:
@effects :white_check_mark:
@detectors RealtekBridgeControllerDetect
@comment
\*-------------------------------------------------------------------*/
RGBController_RealtekBridge::RGBController_RealtekBridge(RealtekBridgeController* controller_ptr)
{
controller = controller_ptr;
name = controller_ptr->get_product_name();
vendor = controller_ptr->get_manu_name();
location = controller_ptr->get_dev_loc();
serial = controller_ptr->get_sn();
version = controller_ptr->get_fw_ver();
description = vendor + "Storage Device";
type = DEVICE_TYPE_STORAGE;
SetupModes();
SetupZones();
}
RGBController_RealtekBridge::~RGBController_RealtekBridge()
{
delete controller;
}
void RGBController_RealtekBridge::SetupModes()
{
int brightness = controller->get_argb_brightness() >> 8;
mode Direct;
Direct.name = "Direct";
Direct.value = REALTEK_BRIDGE_LED_EFF_NONE;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = 0;
Direct.brightness_max = 255;
Direct.brightness = brightness;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = REALTEK_BRIDGE_LED_EFF_ALWAYS;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
Static.brightness_min = 0;
Static.brightness_max = 255;
Static.brightness = brightness;
modes.push_back(Static);
mode Blink;
Blink.name = "Blink";
Blink.value = REALTEK_BRIDGE_LED_EFF_BLINK;
Blink.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Blink.speed_min = REALTEK_BRIDGE_SPEED_MIN;
Blink.speed_max = REALTEK_BRIDGE_SPEED_MAX;
Blink.speed = REALTEK_BRIDGE_SPEED_NORMAL;
Blink.colors_min = 1;
Blink.colors_max = 1;
Blink.color_mode = MODE_COLORS_MODE_SPECIFIC;
Blink.colors.resize(1);
Blink.brightness_min = 0;
Blink.brightness_max = 255;
Blink.brightness = brightness;
modes.push_back(Blink);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = REALTEK_BRIDGE_LED_EFF_BREATHE;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Breathing.speed_min = REALTEK_BRIDGE_SPEED_MIN;
Breathing.speed_max = REALTEK_BRIDGE_SPEED_MAX;
Breathing.speed = REALTEK_BRIDGE_SPEED_NORMAL;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors.resize(1);
Breathing.brightness_min = 0;
Breathing.brightness_max = 255;
Breathing.brightness = brightness;
modes.push_back(Breathing);
mode Spectrum;
Spectrum.name = "Spectrum";
Spectrum.value = REALTEK_BRIDGE_LED_EFF_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Spectrum.speed_min = REALTEK_BRIDGE_SPEED_MIN;
Spectrum.speed_max = REALTEK_BRIDGE_SPEED_MAX;
Spectrum.speed = REALTEK_BRIDGE_SPEED_NORMAL;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.brightness_min = 0;
Spectrum.brightness_max = 255;
Spectrum.brightness = brightness;
modes.push_back(Spectrum);
mode Scroll;
Scroll.name = "Scroll";
Scroll.value = REALTEK_BRIDGE_LED_EFF_SCROLL;
Scroll.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Scroll.speed_min = REALTEK_BRIDGE_SPEED_MIN;
Scroll.speed_max = REALTEK_BRIDGE_SPEED_MAX;
Scroll.speed = REALTEK_BRIDGE_SPEED_NORMAL;
Scroll.colors_min = 1;
Scroll.colors_max = 1;
Scroll.color_mode = MODE_COLORS_MODE_SPECIFIC;
Scroll.colors.resize(1);
Scroll.brightness_min = 0;
Scroll.brightness_max = 255;
Scroll.brightness = brightness;
modes.push_back(Scroll);
mode RainbowScroll;
RainbowScroll.name = "Rainbow Scroll";
RainbowScroll.value = REALTEK_BRIDGE_LED_EFF_RAINBOW_SCROLL;
RainbowScroll.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
RainbowScroll.speed_min = REALTEK_BRIDGE_SPEED_MIN;
RainbowScroll.speed_max = REALTEK_BRIDGE_SPEED_MAX;
RainbowScroll.speed = REALTEK_BRIDGE_SPEED_NORMAL;
RainbowScroll.color_mode = MODE_COLORS_NONE;
RainbowScroll.brightness_min = 0;
RainbowScroll.brightness_max = 255;
RainbowScroll.brightness = brightness;
modes.push_back(RainbowScroll);
mode RunningWater;
RunningWater.name = "Running Water";
RunningWater.value = REALTEK_BRIDGE_LED_EFF_RUNNING_WATER;
RunningWater.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
RunningWater.speed_min = REALTEK_BRIDGE_SPEED_MIN;
RunningWater.speed_max = REALTEK_BRIDGE_SPEED_MAX;
RunningWater.speed = REALTEK_BRIDGE_SPEED_NORMAL;
RunningWater.colors_min = 1;
RunningWater.colors_max = 1;
RunningWater.color_mode = MODE_COLORS_MODE_SPECIFIC;
RunningWater.colors.resize(1);
RunningWater.brightness_min = 0;
RunningWater.brightness_max = 255;
RunningWater.brightness = brightness;
modes.push_back(RunningWater);
mode Sliding;
Sliding.name = "Sliding";
Sliding.value = REALTEK_BRIDGE_LED_EFF_SLIDING;
Sliding.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Sliding.speed_min = REALTEK_BRIDGE_SPEED_MIN;
Sliding.speed_max = REALTEK_BRIDGE_SPEED_MAX;
Sliding.speed = REALTEK_BRIDGE_SPEED_NORMAL;
Sliding.color_mode = MODE_COLORS_NONE;
Sliding.brightness_min = 0;
Sliding.brightness_max = 255;
Sliding.brightness = brightness;
modes.push_back(Sliding);
mode NewtonCradle;
NewtonCradle.name = "Newton Cradle";
NewtonCradle.value = REALTEK_BRIDGE_LED_EFF_NEWTON_CRADLE;
NewtonCradle.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
NewtonCradle.speed_min = REALTEK_BRIDGE_SPEED_MIN;
NewtonCradle.speed_max = REALTEK_BRIDGE_SPEED_MAX;
NewtonCradle.speed = REALTEK_BRIDGE_SPEED_NORMAL;
NewtonCradle.color_mode = MODE_COLORS_NONE;
NewtonCradle.brightness_min = 0;
NewtonCradle.brightness_max = 255;
NewtonCradle.brightness = brightness;
modes.push_back(NewtonCradle);
mode Meteor;
Meteor.name = "Meteor";
Meteor.value = REALTEK_BRIDGE_LED_EFF_METEOR;
Meteor.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Meteor.speed_min = REALTEK_BRIDGE_SPEED_MIN;
Meteor.speed_max = REALTEK_BRIDGE_SPEED_MAX;
Meteor.speed = REALTEK_BRIDGE_SPEED_NORMAL;
Meteor.colors_min = 1;
Meteor.colors_max = 1;
Meteor.color_mode = MODE_COLORS_MODE_SPECIFIC;
Meteor.colors.resize(1);
Meteor.brightness_min = 0;
Meteor.brightness_max = 255;
Meteor.brightness = brightness;
modes.push_back(Meteor);
}
void RGBController_RealtekBridge::SetupZones()
{
zone argb_zone;
argb_zone.name = "strip";
argb_zone.type = ZONE_TYPE_LINEAR;
argb_zone.leds_min = controller->get_argb_num();
argb_zone.leds_max = controller->get_argb_num();
argb_zone.leds_count = controller->get_argb_num();
argb_zone.matrix_map = NULL;
zones.push_back(argb_zone);
for(unsigned int led_idx = 0; led_idx < argb_zone.leds_count; led_idx++)
{
led StripLED;
StripLED.name = "led ";
StripLED.name.append(std::to_string(led_idx + 1));
leds.push_back(StripLED);
}
SetupColors();
}
void RGBController_RealtekBridge::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_RealtekBridge::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
}
void RGBController_RealtekBridge::UpdateZoneLEDs(int /*zone*/)
{
unsigned short brightness = 0xFF;
mode& curr_mode = modes[active_mode];
if(curr_mode.color_mode == MODE_COLORS_PER_LED &&
curr_mode.value == REALTEK_BRIDGE_LED_EFF_NONE) //direct mode
{
if(curr_mode.flags & MODE_FLAG_HAS_BRIGHTNESS)
{
brightness = curr_mode.brightness;
}
controller->set_argb_direct(colors, brightness);
}
else
{
UpdateSingleLED(0);
}
}
void RGBController_RealtekBridge::UpdateSingleLED(int /*led*/)
{
unsigned char speed = REALTEK_BRIDGE_SPEED_NORMAL;
unsigned char dir = 0;
unsigned short brightness = 0xFF;
mode& curr_mode = modes[active_mode];
std::vector<RGBColor> rtk_colors = curr_mode.colors;
if(curr_mode.flags & MODE_FLAG_HAS_SPEED)
{
speed = curr_mode.speed;
}
if(curr_mode.flags & MODE_FLAG_HAS_BRIGHTNESS)
{
brightness = curr_mode.brightness;
}
if(curr_mode.flags & MODE_FLAG_HAS_DIRECTION_LR)
{
if(curr_mode.direction == MODE_DIRECTION_RIGHT)
{
dir = 1;
}
}
if(curr_mode.color_mode == MODE_COLORS_PER_LED)
{
rtk_colors = colors;
}
else if(curr_mode.color_mode == MODE_COLORS_NONE)
{
rtk_colors.clear();
}
controller->set_argb_effect(curr_mode.value, rtk_colors, speed, brightness);
}
void RGBController_RealtekBridge::DeviceUpdateMode()
{
if(modes[active_mode].value != REALTEK_BRIDGE_LED_EFF_NONE)
{
DeviceUpdateLEDs();
}
}
@@ -0,0 +1,34 @@
/*---------------------------------------------------------*\
| RGBController_RealtekBridge.h |
| |
| Controller for Realtek USB to SSD Bridge ICs |
| |
| Jerry Fan (JerryFan0612) 13 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "RealtekBridgeController.h"
class RGBController_RealtekBridge : public RGBController
{
public:
RGBController_RealtekBridge(RealtekBridgeController* controller_ptr);
~RGBController_RealtekBridge();
void SetupModes();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
RealtekBridgeController* controller;
};
@@ -0,0 +1,802 @@
/*---------------------------------------------------------*\
| RealtekBridgeController.cpp |
| |
| Controller for Realtek USB to SSD Bridge ICs |
| |
| Jerry Fan (JerryFan0612) 13 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RealtekBridgeController.h"
#include "hsv.h"
#include <StringUtils.h>
#include <MathUtils.h>
static const unsigned char hid_set_packet[] =
{
0x56, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xE3,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char hid_get_packet[] =
{
0x56, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0xE2,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char hid_end_packet[] =
{
0x58, 0x53, 0x42, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
RealtekBridgeController::RealtekBridgeController(hid_device* dev, hid_device_info* info)
{
hdev = dev;
hidinfo = info;
brctl_data = (unsigned char*)calloc(REALTEK_BRIDGE_CTL_DATA_SIZE, 1);
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
set_write_unlock();
get_brctl_hdr();
get_brctl_data();
set_appctl(true);
}
RealtekBridgeController::~RealtekBridgeController()
{
if(hdev)
{
set_appctl(false);
hid_close(hdev);
hdev = NULL;
}
memset(brctl_hdr, 0, REALTEK_BRIDGE_CTL_HDR_SIZE);
free(brctl_data);
}
int RealtekBridgeController::usb_hid_ioctl(unsigned char* usb_buf, unsigned char* data, int data_len,
unsigned int offset, unsigned char is_in)
{
int id;
int ret = 0;
int buf_len = usb_hid_get_report(data_len, &id);
if(!is_in && data_len)
{
usb_buf[0x04] = data[0];
}
memcpy(&usb_buf[0x08], &data_len, sizeof(data_len));
memcpy(&usb_buf[0x1B], &data_len, sizeof(data_len));
ret = hid_send_feature_report(hdev, usb_buf, sizeof(hid_get_packet));
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, data, data_len);
usb_buf[0x00] = id;
if(is_in)
{
ret = hid_get_feature_report(hdev, usb_buf, buf_len);
memcpy(data, usb_buf + offset, data_len);
}
else
{
ret = hid_send_feature_report(hdev, usb_buf, buf_len);
}
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_end_packet, sizeof(hid_end_packet));
ret = hid_get_feature_report(hdev, usb_buf, sizeof(hid_end_packet));
free(usb_buf);
return (ret > 0) ? 0 : ret;
}
int RealtekBridgeController::usb_hid_get_report(int data_len, int* id)
{
int retlen = 0;
if(data_len <= REALTEK_BRIDGE_HID_DATALEN_CH2)
{
*id = REALTEK_BRIDGE_HID_ID_DATA_CH2;
retlen = REALTEK_BRIDGE_HID_DATALEN_CH2;
}
else if(data_len <= REALTEK_BRIDGE_HID_DATALEN_CH3)
{
*id = REALTEK_BRIDGE_HID_ID_DATA_CH3;
retlen = REALTEK_BRIDGE_HID_DATALEN_CH3;
}
else if(data_len <= REALTEK_BRIDGE_HID_DATALEN_CH4)
{
*id = REALTEK_BRIDGE_HID_ID_DATA_CH4;
retlen = REALTEK_BRIDGE_HID_DATALEN_CH4;
}
else if(data_len <= REALTEK_BRIDGE_HID_DATALEN_CH5)
{
*id = REALTEK_BRIDGE_HID_ID_DATA_CH5;
retlen = REALTEK_BRIDGE_HID_DATALEN_CH5;
}
else
{
*id = REALTEK_BRIDGE_HID_ID_DATA_CH1;
retlen = REALTEK_BRIDGE_HID_DATALEN_CH1;
}
return retlen;
}
int RealtekBridgeController::set_write_unlock()
{
int ret = 0;
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
int data_len = 96;
unsigned int addr = 0xAC004000;
unsigned char* data = (unsigned char*)calloc(data_len, 1);
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_get_packet, sizeof(hid_get_packet));
usb_buf[0x13] = 0x92;
memcpy(&usb_buf[0x17], &addr, sizeof(addr));
ret = usb_hid_ioctl(usb_buf, data, data_len, 0, true);
free(data);
return ret;
}
int RealtekBridgeController::get_brctl_hdr()
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_get_packet, sizeof(hid_get_packet));
usb_buf[0x13] = 0xCC;
usb_buf[0x14] = 0x02;
return usb_hid_ioctl(usb_buf, brctl_hdr, REALTEK_BRIDGE_CTL_HDR_SIZE, 0, true);
}
int RealtekBridgeController::set_brctl_hdr()
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_set_packet, sizeof(hid_set_packet));
usb_buf[0x13] = 0x4C;
usb_buf[0x14] = 0x02;
return usb_hid_ioctl(usb_buf, brctl_hdr, REALTEK_BRIDGE_CTL_HDR_SIZE, 0, false);
}
int RealtekBridgeController::get_brctl_data()
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
int offset = REALTEK_BRIDGE_CTL_HDR_SIZE;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_get_packet, sizeof(hid_get_packet));
usb_buf[0x13] = 0xCC;
usb_buf[0x14] = 0x02;
memcpy(&usb_buf[0x17], &offset, sizeof(offset));
return usb_hid_ioctl(usb_buf, brctl_data, REALTEK_BRIDGE_CTL_DATA_SIZE, 0, true);
}
int RealtekBridgeController::set_brctl_data()
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
int offset = REALTEK_BRIDGE_CTL_HDR_SIZE;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_set_packet, sizeof(hid_set_packet));
usb_buf[0x13] = 0x4C;
usb_buf[0x14] = 0x02;
memcpy(&usb_buf[0x17], &offset, sizeof(offset));
return usb_hid_ioctl(usb_buf, brctl_data, REALTEK_BRIDGE_CTL_DATA_SIZE, 0, false);
}
unsigned char RealtekBridgeController::get_support_openrgb()
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
unsigned char is_support = 0;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_get_packet, sizeof(hid_get_packet));
usb_buf[0x13] = 0xCC;
usb_buf[0x14] = 0x04;
usb_buf[0x15] = REALTEK_BRIDGE_SYNC_METHOD_OPENRGB;
if(usb_hid_ioctl(usb_buf, &is_support, sizeof(is_support), 0, true))
{
is_support = 0;
}
return is_support;
}
std::string RealtekBridgeController::get_manu_name()
{
return StringUtils::wchar_to_char(hidinfo->manufacturer_string);
}
std::string RealtekBridgeController::get_product_name()
{
return StringUtils::wchar_to_char(hidinfo->product_string);
}
std::string RealtekBridgeController::get_sn()
{
return StringUtils::wchar_to_char(hidinfo->serial_number);
}
std::string RealtekBridgeController::get_dev_loc()
{
return hidinfo->path;
}
std::string RealtekBridgeController::get_fw_ver()
{
struct RealtekBridgeControllerFWVersion fw_ver;
std::string ver = "";
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_get_packet, sizeof(hid_get_packet));
usb_buf[0x13] = 0xA5;
if(!usb_hid_ioctl(usb_buf, (unsigned char*)&fw_ver, sizeof(fw_ver), 0, true))
{
ver += std::to_string(fw_ver.fw_major_ver) + "." +
std::to_string(fw_ver.fw_minor_ver) + "." +
std::to_string(fw_ver.fw_extra_ver) + "." +
std::to_string(fw_ver.fw_build_date);
}
return ver;
}
int RealtekBridgeController::get_argb_num()
{
int num_rgb = 0;
memcpy(&num_rgb, &brctl_hdr[24], sizeof(num_rgb));
return num_rgb;
}
int RealtekBridgeController::get_argb_brightness()
{
int bright = 0;
memcpy(&bright, &brctl_hdr[28], 2);
return bright;
}
int RealtekBridgeController::set_argb_brightness(unsigned short bright)
{
memcpy(&brctl_hdr[28], &bright, sizeof(bright));
set_brctl_hdr();
return 0;
}
int RealtekBridgeController::set_appctl(unsigned char ctl_sts)
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_set_packet, sizeof(hid_set_packet));
usb_buf[0x13] = 0x4C;
usb_buf[0x14] = 0x01;
usb_buf[0x15] = ctl_sts;
return usb_hid_ioctl(usb_buf, &ctl_sts, sizeof(ctl_sts), 0, false);
}
int RealtekBridgeController::set_direct(unsigned char* color, int color_num)
{
int buf_len = REALTEK_BRIDGE_HID_DATALEN_CH1;
int data_len = color_num * REALTEK_BRIDGE_COLOR_DEPTH;
unsigned char* usb_buf = (unsigned char*)calloc(buf_len, 1);// will release in usb_hid_ioctl function
memset(usb_buf, 0x00, buf_len);
memcpy(usb_buf, hid_set_packet, sizeof(hid_set_packet));
usb_buf[0x13] = 0x4C;
usb_buf[0x14] = 0x03;
usb_buf[0x15] = REALTEK_BRIDGE_SYNC_METHOD_OPENRGB;
memcpy(&usb_buf[0x17], &color_num, sizeof(color_num));
return usb_hid_ioctl(usb_buf, color, data_len, 0, false);
}
int RealtekBridgeController::eff_set_always_on(RGBColor rgb)
{
int i;
int j;
int row = 1;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 1;
brctl_data[i * single_size + 1] = row;
for(j = 0; j < row; j++)
{
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_blink(RGBColor rgb, int cycle)
{
int i;
int j;
int row = 2;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 2;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 1;
for(j = 0; j < row; j++)
{
if((j & 0x1) == 0)
{
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_breathe(RGBColor rgb, int cycle)
{
int i;
int j;
int row = 2;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 4;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 2;
for(j = 0; j < row; j++)
{
if((j & 0x1) == 0)
{
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_spectrum(int cycle)
{
int i;
int j;
int row = 6;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
static const RGBColor rainbow_table[6] = {0x0000FF, 0x0050FF, 0x0080FF, 0x00FF00, 0xFF0000, 0xFF0080};
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 4;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 3;
for(j = 0; j < row; j++)
{
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rainbow_table[j]);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rainbow_table[j]);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rainbow_table[j]);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_scroll(RGBColor rgb, int cycle)
{
int i;
int j;
int start_idx = -1;
int row = get_argb_num() * 2 - 2;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 2;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 4;
if(start_idx == -1)
{
start_idx = i;
}
j = i - start_idx;
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
if(i != start_idx)
{
j = row - (i - start_idx);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_rainbow_scroll(int cycle)
{
int i;
int j;
int start_idx = -1;
int row = get_argb_num() * 2 - 2;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
RGBColor slide_table[REALTEK_BRIDGE_MAX_ARGB_NUM] = {0};
hsv_t hsv_color;
hsv_color.saturation = 255;
hsv_color.value = 255;
for(i = 0; i < get_argb_num(); i++)
{
hsv_color.hue = (i % get_argb_num()) * (360 / get_argb_num());
slide_table[i] = hsv2rgb(&hsv_color);
}
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 2;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 0x85;
if(start_idx == -1)
{
start_idx = i;
}
j = i - start_idx;
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(slide_table[i]);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(slide_table[i]);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(slide_table[i]);
if(i != start_idx)
{
j = row - (i - start_idx);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(slide_table[i]);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(slide_table[i]);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(slide_table[i]);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_running_water(RGBColor rgb, int cycle)
{
int i;
int j;
int start_idx = -1;
int row = get_argb_num() * 2;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 2;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 5;
if(start_idx == -1)
{
start_idx = i;
}
for(j = i - start_idx; j < row / 2; j++)
{
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_sliding(int cycle)
{
int i;
int j;
int start_idx = -1;
int row = get_argb_num();
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
RGBColor slide_table[REALTEK_BRIDGE_MAX_ARGB_NUM] = {0};
RGBColor rgb = 0;
hsv_t hsv_color;
hsv_color.saturation = 255;
hsv_color.value = 255;
for(i = 0; i < get_argb_num(); i++)
{
hsv_color.hue = (i % get_argb_num()) * (360 / get_argb_num());
slide_table[i] = hsv2rgb(&hsv_color);
}
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 4;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 0x83;
if(start_idx == -1)
{
start_idx = i;
}
for(j = 0; j < row; j++)
{
rgb = slide_table[(i - start_idx + j) % row];
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_newton_cradle(int cycle)
{
int i;
int j;
int start_idx = -1;
int row;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
RGBColor rgb = 0;
static const int const_ball_num = 3;
static const RGBColor ball_color[] = {0x0080FF, 0x0000FF, 0x00FF00, 0xFF0000};
static const int mid = get_argb_num() >> 1;
if(get_argb_num() <= const_ball_num)
{
return 0;
}
row = (get_argb_num() - const_ball_num) * 2;
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 2;
brctl_data[i * single_size + 1] = row;
memcpy(&brctl_data[i * single_size + 2], &cycle, 2);
brctl_data[i * single_size + 8] = 0x84;
if(start_idx == -1)
{
start_idx = i;
}
for(j = 0; j < row; j++)
{
rgb = 0;
if(i - start_idx > mid - 2 &&
i - start_idx < mid + 2)
{
if(j < mid - 1 || j > row - mid)
{
if(i - start_idx == mid - 1)
{
rgb = ball_color[1];
}
else if(i - start_idx == mid)
{
rgb = ball_color[2];
}
else
{
rgb = ball_color[3];
}
}
else
{
if(i - start_idx == mid - 1)
{
rgb = ball_color[0];
}
else if(i - start_idx == mid)
{
rgb = ball_color[1];
}
else
{
rgb = ball_color[2];
}
}
}
else if(i - start_idx < mid)
{
if(i - start_idx == j || i - start_idx + j == row - 1)
{
rgb = ball_color[0];
}
}
else if(i - start_idx > mid + 1)
{
if(i - start_idx - j == const_ball_num ||
i - start_idx + j == row - 1 + const_ball_num)
{
rgb = ball_color[3];
}
}
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
}
return set_brctl_data();
}
int RealtekBridgeController::eff_set_meteor(RGBColor rgb, int cycle)
{
int i;
int j;
int row = 2;
int maxrow = REALTEK_BRIDGE_MAX_APPCTL_ROW;
int single_size = maxrow * REALTEK_BRIDGE_COLOR_DEPTH + 32;
int stable_ms = cycle / row;
int latency = stable_ms / get_argb_num();
memset(brctl_data, 0, REALTEK_BRIDGE_CTL_DATA_SIZE);
for(i = 0; i < get_argb_num(); i++)
{
brctl_data[i * single_size + 0] = 4;
brctl_data[i * single_size + 1] = row;
brctl_data[i * single_size + 6] = stable_ms / 100;
brctl_data[i * single_size + 7] = stable_ms / 100;
brctl_data[i * single_size + 8] = 6;
memcpy(&brctl_data[i * single_size + 9], &latency, 2);
j = 0;
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 32] = RGBGetRValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 33] = RGBGetGValue(rgb);
brctl_data[i * single_size + j * REALTEK_BRIDGE_COLOR_DEPTH + 34] = RGBGetBValue(rgb);
}
return set_brctl_data();
}
int RealtekBridgeController::set_argb_direct(std::vector<RGBColor> color_buf, unsigned short brightness)
{
int ret = -1;
size_t color_num = color_buf.size();
size_t buf_len = color_num * REALTEK_BRIDGE_COLOR_DEPTH;
static unsigned short prev_bright = 0xFFFF;
unsigned char* buf;
if(color_num <= 0)
{
goto exit;
}
ret = set_appctl(true);
if(ret)
{
goto exit;
}
if(prev_bright != brightness)
{
prev_bright = brightness;
ret = set_argb_brightness(brightness << 8);
if(ret)
{
goto exit;
}
}
buf = (unsigned char*)malloc(buf_len);
memset(buf, 0, buf_len);
for(int i = 0; i < (int)color_num; i++)
{
buf[i * REALTEK_BRIDGE_COLOR_DEPTH + 0] = RGBGetRValue(color_buf[i]);
buf[i * REALTEK_BRIDGE_COLOR_DEPTH + 1] = RGBGetGValue(color_buf[i]);
buf[i * REALTEK_BRIDGE_COLOR_DEPTH + 2] = RGBGetBValue(color_buf[i]);
}
ret = set_direct(buf, (int)color_num);
free(buf);
if(ret)
{
goto exit;
}
exit:
return ret;
}
int RealtekBridgeController::set_argb_effect(unsigned char mode, std::vector<RGBColor> color_buf, int speed, unsigned short brightness)
{
int ret = -1;
int cycle = MathUtils::IntInterpolate(REALTEK_BRIDGE_CYCLE_MAX, REALTEK_BRIDGE_CYCLE_MIN, 0, REALTEK_BRIDGE_SPEED_MAX, speed);
RGBColor rgb = 0;
static unsigned short prev_bright = 0xFFFF;
if(color_buf.size() >= 1)
{
rgb = color_buf[0];
}
if(prev_bright != brightness)
{
prev_bright = brightness;
ret = set_argb_brightness(brightness << 8);
if(ret)
{
goto exit;
}
}
switch(mode)
{
case REALTEK_BRIDGE_LED_EFF_ALWAYS:
ret = eff_set_always_on(rgb);
break;
case REALTEK_BRIDGE_LED_EFF_BLINK:
ret = eff_set_blink(rgb, cycle);
break;
case REALTEK_BRIDGE_LED_EFF_BREATHE:
ret = eff_set_breathe(rgb, cycle);
break;
case REALTEK_BRIDGE_LED_EFF_SPECTRUM:
ret = eff_set_spectrum(cycle);
break;
case REALTEK_BRIDGE_LED_EFF_SCROLL:
ret = eff_set_scroll(rgb, cycle);
break;
case REALTEK_BRIDGE_LED_EFF_RAINBOW_SCROLL:
ret = eff_set_rainbow_scroll(cycle);
break;
case REALTEK_BRIDGE_LED_EFF_RUNNING_WATER:
ret = eff_set_running_water(rgb, cycle);
break;
case REALTEK_BRIDGE_LED_EFF_SLIDING:
ret = eff_set_sliding(cycle);
break;
case REALTEK_BRIDGE_LED_EFF_NEWTON_CRADLE:
ret = eff_set_newton_cradle(cycle);
break;
case REALTEK_BRIDGE_LED_EFF_METEOR:
ret = eff_set_meteor(rgb, cycle);
break;
default:
break;
}
if(!ret)
{
ret = set_appctl(false);
}
exit:
return ret;
}
@@ -0,0 +1,126 @@
/*---------------------------------------------------------*\
| RealtekBridgeController.h |
| |
| Controller for Realtek USB to SSD Bridge ICs |
| |
| Jerry Fan (JerryFan0612) 13 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <stdlib.h>
#include <stdint.h>
#include <cmath>
#include <cstring>
#include <vector>
#include <hidapi.h>
#include "RGBController.h"
#define REALTEK_BRIDGE_SYNC_METHOD_OPENRGB 6
#define REALTEK_BRIDGE_COLOR_DEPTH 3
#define REALTEK_BRIDGE_CTL_HDR_SIZE 64
#define REALTEK_BRIDGE_CTL_DATA_SIZE 3220
#define REALTEK_BRIDGE_MAX_ARGB_NUM 20
#define REALTEK_BRIDGE_MAX_APPCTL_ROW 43
#define REALTEK_BRIDGE_HID_DATALEN_CH1 4096
#define REALTEK_BRIDGE_HID_DATALEN_CH2 64
#define REALTEK_BRIDGE_HID_DATALEN_CH3 512
#define REALTEK_BRIDGE_HID_DATALEN_CH4 1200
#define REALTEK_BRIDGE_HID_DATALEN_CH5 2048
#define REALTEK_BRIDGE_HID_ID_DATA_CH1 0x57
#define REALTEK_BRIDGE_HID_ID_DATA_CH2 0x59
#define REALTEK_BRIDGE_HID_ID_DATA_CH3 0x5A
#define REALTEK_BRIDGE_HID_ID_DATA_CH4 0x5B
#define REALTEK_BRIDGE_HID_ID_DATA_CH5 0x5C
enum REALTEK_BRIDGE_LED_EFF
{
REALTEK_BRIDGE_LED_EFF_NONE,
REALTEK_BRIDGE_LED_EFF_ALWAYS,
REALTEK_BRIDGE_LED_EFF_BLINK,
REALTEK_BRIDGE_LED_EFF_BREATHE,
REALTEK_BRIDGE_LED_EFF_SPECTRUM,
REALTEK_BRIDGE_LED_EFF_SCROLL,
REALTEK_BRIDGE_LED_EFF_RAINBOW_SCROLL,
REALTEK_BRIDGE_LED_EFF_RUNNING_WATER,
REALTEK_BRIDGE_LED_EFF_SLIDING,
REALTEK_BRIDGE_LED_EFF_NEWTON_CRADLE,
REALTEK_BRIDGE_LED_EFF_METEOR,
REALTEK_BRIDGE_NUMBER_OF_LED_EFF_MODE,
};
enum REALTEK_BRIDGE_SPEED
{
REALTEK_BRIDGE_SPEED_MIN = 1,
REALTEK_BRIDGE_SPEED_NORMAL = 50,
REALTEK_BRIDGE_SPEED_MAX = 100,
};
enum REALTEK_BRIDGE_CYCLE_MS
{
REALTEK_BRIDGE_CYCLE_MIN = 200,
REALTEK_BRIDGE_CYCLE_NORMAL = 2000,
REALTEK_BRIDGE_CYCLE_MAX = 10000,
};
struct RealtekBridgeControllerFWVersion
{
unsigned int fw_major_ver;
unsigned int fw_minor_ver;
unsigned int fw_extra_ver;
unsigned int fw_build_ver;
unsigned int fw_build_date;
};
class RealtekBridgeController
{
public:
RealtekBridgeController(hid_device* dev, hid_device_info* info);
~RealtekBridgeController();
unsigned char get_support_openrgb();
std::string get_manu_name();
std::string get_product_name();
std::string get_sn();
std::string get_dev_loc();
std::string get_fw_ver();
int get_argb_num();
int get_argb_brightness();
int set_argb_brightness(unsigned short bright);
int set_argb_direct(std::vector<RGBColor> color_buf, unsigned short brightness);
int set_argb_effect(unsigned char mode, std::vector<RGBColor> color_buf, int speed, unsigned short brightness);
private:
hid_device* hdev;
hid_device_info* hidinfo = NULL;
unsigned char brctl_hdr[REALTEK_BRIDGE_CTL_HDR_SIZE] = {0};
unsigned char* brctl_data = NULL;
int usb_hid_ioctl(unsigned char* usb_buf, unsigned char* data, int data_len,
unsigned int offset, unsigned char is_in);
int usb_hid_get_report(int data_len, int* id);
int set_write_unlock();
int get_brctl_hdr();
int set_brctl_hdr();
int get_brctl_data();
int set_brctl_data();
int set_appctl(unsigned char ctl_sts);
int set_direct(unsigned char* color, int color_num);
int eff_set_always_on(RGBColor rgb);
int eff_set_blink(RGBColor rgb, int cycle);
int eff_set_breathe(RGBColor rgb, int cycle);
int eff_set_spectrum(int cycle);
int eff_set_scroll(RGBColor rgb, int cycle);
int eff_set_rainbow_scroll(int cycle);
int eff_set_running_water(RGBColor rgb, int cycle);
int eff_set_sliding(int cycle);
int eff_set_newton_cradle(int cycle);
int eff_set_meteor(RGBColor rgb, int cycle);
};
@@ -0,0 +1,61 @@
/*---------------------------------------------------------*\
| RealtekBridgeControllerDetect.cpp |
| |
| Controller for Realtek USB to SSD Bridge ICs |
| |
| Jerry Fan (JerryFan0612) 13 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "Detector.h"
#include "RGBController_RealtekBridge.h"
#define REALTEK_BRIDGE_VID 0x0BDA
#define REALTEK_BRIDGE_PID0 0x9220
#define REALTEK_BRIDGE_PID1 0x9201
#define REALTEK_BRIDGE_PID2 0x9210
#define REALTEK_HID2SCSI_PG 0xFF00
#define REALTEK_HID2SCSI_USAGE 0x0001
/******************************************************************************************\
* *
* DetectRealtekBridgeControllers *
* *
* Tests the USB address to see if an Realtek Bridge controller exists there *
* *
\******************************************************************************************/
void DetectRealtekBridgeControllers(hid_device_info* info, const std::string& /*name*/)
{
RealtekBridgeController* controller = NULL;
RGBController_RealtekBridge* rgb_controller = NULL;
hid_device* dev = hid_open_path(info->path);
if(dev)
{
controller = new RealtekBridgeController(dev, info);
if(controller->get_support_openrgb())
{
rgb_controller = new RGBController_RealtekBridge(controller);
if(rgb_controller->type != DEVICE_TYPE_UNKNOWN)
{
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
delete rgb_controller;
}
}
else
{
delete controller;
}
}
return;
}
REGISTER_HID_DETECTOR_PU("RTL9220", DetectRealtekBridgeControllers, REALTEK_BRIDGE_VID, REALTEK_BRIDGE_PID0, REALTEK_HID2SCSI_PG, REALTEK_HID2SCSI_USAGE);
REGISTER_HID_DETECTOR_PU("RTL9201", DetectRealtekBridgeControllers, REALTEK_BRIDGE_VID, REALTEK_BRIDGE_PID1, REALTEK_HID2SCSI_PG, REALTEK_HID2SCSI_USAGE);
REGISTER_HID_DETECTOR_PU("RTL9210", DetectRealtekBridgeControllers, REALTEK_BRIDGE_VID, REALTEK_BRIDGE_PID2, REALTEK_HID2SCSI_PG, REALTEK_HID2SCSI_USAGE);