MSI X870 Tomahawk WIFI support
This commit is contained in:
parent
5589aad730
commit
9f82afa485
6 changed files with 1167 additions and 5 deletions
|
|
@ -0,0 +1,437 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| MSIMysticLight185Controller.cpp |
|
||||
| |
|
||||
| Driver for MSI Mystic Light 761-byte motherboard |
|
||||
| |
|
||||
| Direct mode functionality has been implemented based on |
|
||||
| the SignalRGB project |
|
||||
| (https://signalrgb.com/) |
|
||||
| |
|
||||
| rom4ster 11 Jun 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
#include "MSIMysticLight761Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
|
||||
#define NUM_CONFS sizeof(board_configs) / sizeof(mystic_light_761_config)
|
||||
#define COLOR_BLACK {0, 0, 0}
|
||||
#define IS_JARGB(X) (X == MSI_ZONE_JARGB_1 || X == MSI_ZONE_JARGB_2 || X == MSI_ZONE_JARGB_3)
|
||||
#define GET_CHAR_PTR_REF(X) (unsigned char *) &(X)
|
||||
|
||||
struct mystic_light_761_config
|
||||
{
|
||||
unsigned short pid; // PID of the board
|
||||
int numof_onboard_leds; // number of onboard leds
|
||||
int numof_pipe1_leds; // number of pipe 1 leds (used in per LED mode only)
|
||||
int numof_pipe2_leds; // number of pipe 2 leds (used in per LED mode only)
|
||||
int numof_JRGBs; // number of supported JRGB headers (used in per LED mode only)
|
||||
const std::vector<MSI_ZONE>* supported_zones; // pointer to vector of supported zones
|
||||
MSIMysticLight761Controller::DIRECT_MODE per_led_mode; // type of direct mode support
|
||||
};
|
||||
|
||||
const std::vector<MSI_ZONE> x870tomawhawk_zones =
|
||||
{
|
||||
MSI_ZONE_JAF,
|
||||
MSI_ZONE_JARGB_1,
|
||||
MSI_ZONE_JARGB_2,
|
||||
MSI_ZONE_JARGB_3,
|
||||
};
|
||||
|
||||
static const mystic_light_761_config board_configs[] =
|
||||
{
|
||||
{ 0x0076, 0, 0, 0, 1, &x870tomawhawk_zones, MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED }, // MSI X870 TOMAHAWK WIFI
|
||||
};
|
||||
|
||||
void init_packet(FeaturePacket_Zone_761 * packet)
|
||||
{
|
||||
packet->packet.fixed1 = 0x09;
|
||||
packet->packet.fixed2 = 0x00;
|
||||
packet->packet.fixed3 = 0x00;
|
||||
packet->packet.hdr2 = 240;
|
||||
|
||||
for(int i = 0; i < NUM_LEDS_761; i++)
|
||||
{
|
||||
packet->packet.colors[i] = 0x0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MSIMysticLight761Controller::MSIMysticLight761Controller
|
||||
(
|
||||
hid_device* handle,
|
||||
const char *path,
|
||||
unsigned short pid
|
||||
)
|
||||
{
|
||||
dev = handle;
|
||||
|
||||
supported_zones = new std::vector<MSI_ZONE>;
|
||||
const mystic_light_761_config * board_config = nullptr;
|
||||
|
||||
for(int i = 0; i < NUM_CONFS; i++)
|
||||
{
|
||||
if(board_configs[i].pid == pid)
|
||||
{
|
||||
board_config = &board_configs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(board_config != nullptr)
|
||||
{
|
||||
supported_zones = (std::vector<MSI_ZONE>*) board_config->supported_zones;
|
||||
unsigned int max = 0;
|
||||
for(int i = 0; i < board_config->supported_zones[0].size(); i++)
|
||||
{
|
||||
unsigned int curr_val = (unsigned int) (board_config->supported_zones[0][i]);
|
||||
if( (unsigned int) curr_val > max )
|
||||
{
|
||||
max = curr_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(MSI_ZONE supp_zone : *supported_zones )
|
||||
{
|
||||
ZoneConfig conf;
|
||||
conf.msi_zone = supp_zone;
|
||||
ZoneData * dat = new ZoneData;
|
||||
conf.zone_data = dat;
|
||||
zone_configs.push_back(conf);
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
location = path;
|
||||
|
||||
ReadName();
|
||||
ReadFwVersion();
|
||||
ReadSettings();
|
||||
data = new FeaturePacket_761;
|
||||
|
||||
data->jaf.zone = MSI_ZONE_JAF;
|
||||
data->jargb1.zone = MSI_ZONE_JARGB_1;
|
||||
data->jargb2.zone = MSI_ZONE_JARGB_2;
|
||||
data->jargb3.zone = MSI_ZONE_JARGB_3;
|
||||
|
||||
data->jaf.packet.hdr0 = 0x08;
|
||||
data->jargb1.packet.hdr0 = 0x04;
|
||||
data->jargb2.packet.hdr0 = 0x04;
|
||||
data->jargb3.packet.hdr0 = 0x04;
|
||||
|
||||
|
||||
data->jaf.packet.hdr1 = 0x00;
|
||||
data->jargb1.packet.hdr1 = 0x00;
|
||||
data->jargb2.packet.hdr1 = 0x01;
|
||||
data->jargb3.packet.hdr1 = 0x02;
|
||||
|
||||
init_packet(&data->jaf);
|
||||
init_packet(&data->jargb1);
|
||||
init_packet(&data->jargb2);
|
||||
init_packet(&data->jargb3);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MSIMysticLight761Controller::~MSIMysticLight761Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void MSIMysticLight761Controller::SetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE mode,
|
||||
MSI_SPEED speed,
|
||||
MSI_BRIGHTNESS brightness,
|
||||
bool rainbow_color
|
||||
)
|
||||
{
|
||||
return; // Only supporting direct for now
|
||||
}
|
||||
|
||||
std::string MSIMysticLight761Controller::GetDeviceName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string MSIMysticLight761Controller::GetFWVersion()
|
||||
{
|
||||
return std::string("AP/LD ").append(version_APROM).append(" / ").append(version_LDROM);
|
||||
}
|
||||
|
||||
std::string MSIMysticLight761Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string MSIMysticLight761Controller::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
bool MSIMysticLight761Controller::ReadSettings()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet from hardware, return true if successful |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char buffer [500];
|
||||
buffer[0] = 0x51;
|
||||
return (hid_get_feature_report(dev, buffer, 500)) > 0 ;
|
||||
}
|
||||
|
||||
bool MSIMysticLight761Controller::Update
|
||||
(
|
||||
bool save
|
||||
)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
bool flag = true;
|
||||
ret = hid_send_feature_report(dev, GET_CHAR_PTR_REF(data->jaf.packet) , sizeof(FeaturePacket_PerLED_761));
|
||||
if(ret < 0) { flag = false;}
|
||||
ret = hid_send_feature_report(dev, GET_CHAR_PTR_REF(data->jargb1.packet) , sizeof(FeaturePacket_PerLED_761));
|
||||
if(ret < 0) { flag = false;}
|
||||
ret = hid_send_feature_report(dev, GET_CHAR_PTR_REF(data->jargb2.packet) , sizeof(FeaturePacket_PerLED_761));
|
||||
if(ret < 0) { flag = false;}
|
||||
ret = hid_send_feature_report(dev, GET_CHAR_PTR_REF(data->jargb3.packet) , sizeof(FeaturePacket_PerLED_761));
|
||||
if(ret < 0) { flag = false;}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MSIMysticLight761Controller::SetZoneColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
)
|
||||
{
|
||||
for(int i = 0; i < zone_configs.size(); i++)
|
||||
{
|
||||
if(zone_configs[i].msi_zone == zone)
|
||||
{
|
||||
zone_configs[i].zone_data->color.R = red1;
|
||||
zone_configs[i].zone_data->color.G = grn1;
|
||||
zone_configs[i].zone_data->color.B = blu1;
|
||||
zone_configs[i].zone_data->color2.R = red2;
|
||||
zone_configs[i].zone_data->color2.G = grn2;
|
||||
zone_configs[i].zone_data->color2.B = blu2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_data_color(FeaturePacket_Zone_761 * packet, int index, unsigned char color_val )
|
||||
{
|
||||
if(packet == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
packet->packet.colors[index] = color_val;
|
||||
}
|
||||
|
||||
void MSIMysticLight761Controller::SetLedColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
int index,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
)
|
||||
{
|
||||
|
||||
FeaturePacket_Zone_761 * ptr = nullptr;
|
||||
switch(zone)
|
||||
{
|
||||
case MSI_ZONE_JAF:
|
||||
ptr = &data->jaf;
|
||||
break;
|
||||
case MSI_ZONE_JARGB_1:
|
||||
ptr = &data->jargb1;
|
||||
break;
|
||||
case MSI_ZONE_JARGB_2:
|
||||
ptr = &data->jargb2;
|
||||
break;
|
||||
case MSI_ZONE_JARGB_3:
|
||||
ptr = &data->jargb3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
size_t candidate_index = index*3;
|
||||
|
||||
if(candidate_index + 2 <= GetMaxDirectLeds(zone) && candidate_index >= 0)
|
||||
{
|
||||
set_data_color(ptr, candidate_index, red);
|
||||
set_data_color(ptr, candidate_index+1, grn);
|
||||
set_data_color(ptr, candidate_index+2, blu);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ZoneData *MSIMysticLight761Controller::GetZoneData
|
||||
(
|
||||
FeaturePacket_761& data_packet,
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
for(ZoneConfig zd : zone_configs)
|
||||
{
|
||||
if(zd.msi_zone == zone)
|
||||
{
|
||||
return zd.zone_data;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Color *MSIMysticLight761Controller::GetPerLedZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
return &(GetZoneData(*data, zone)->color);
|
||||
}
|
||||
|
||||
RainbowZoneData *MSIMysticLight761Controller::GetRainbowZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MSIMysticLight761Controller::ReadFwVersion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void MSIMysticLight761Controller::ReadName()
|
||||
{
|
||||
wchar_t tname[256];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the manufacturer string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_manufacturer_string(dev, tname, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert to std::string |
|
||||
\*-----------------------------------------------------*/
|
||||
name = StringUtils::wstring_to_string(tname);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the product string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_product_string(dev, tname, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Append the product string to the manufacturer string |
|
||||
\*-----------------------------------------------------*/
|
||||
name.append(" ").append(StringUtils::wstring_to_string(tname));
|
||||
}
|
||||
|
||||
MSI_MODE MSIMysticLight761Controller::GetMode()
|
||||
{
|
||||
return MSI_MODE_DIRECT_DUMMY;
|
||||
}
|
||||
|
||||
void MSIMysticLight761Controller::GetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE &mode,
|
||||
MSI_SPEED &speed,
|
||||
MSI_BRIGHTNESS &brightness,
|
||||
bool &rainbow_color,
|
||||
unsigned int &color
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get data for given zone |
|
||||
\*-----------------------------------------------------*/
|
||||
ZoneData *zone_data = GetZoneData(*data, zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Return if zone is invalid |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!zone_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update pointers with data |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
// Actual support of non direct modes needs to be further investigated
|
||||
mode = (MSI_MODE)zone_data->effect;
|
||||
speed = (MSI_SPEED)(zone_data->speedAndBrightnessFlags & 0x03);
|
||||
brightness = (MSI_BRIGHTNESS)((zone_data->speedAndBrightnessFlags >> 2) & 0x1F);
|
||||
rainbow_color = (zone_data->colorFlags & 0x80) == 0 ? true : false;
|
||||
color = ToRGBColor(zone_data->color.R, zone_data->color.G, zone_data->color.B);
|
||||
}
|
||||
|
||||
void MSIMysticLight761Controller::SetCycleCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char cycle_num
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void MSIMysticLight761Controller::SetDirectMode
|
||||
(
|
||||
bool mode
|
||||
)
|
||||
{
|
||||
SelectPerLedProtocol();
|
||||
}
|
||||
|
||||
|
||||
size_t MSIMysticLight761Controller::GetMaxDirectLeds
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch(zone)
|
||||
{
|
||||
case MSI_ZONE_JAF:
|
||||
case MSI_ZONE_JARGB_1:
|
||||
case MSI_ZONE_JARGB_2:
|
||||
case MSI_ZONE_JARGB_3:
|
||||
return 240;
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MSIMysticLight761Controller::SelectPerLedProtocol()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| MSIMysticLight185Controller.cpp |
|
||||
| |
|
||||
| Driver for MSI Mystic Light 761-byte motherboard |
|
||||
| |
|
||||
| Direct mode functionality has been implemented based on |
|
||||
| the SignalRGB project |
|
||||
| (https://signalrgb.com/) |
|
||||
| |
|
||||
| rom4ster 11 Jun 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <hidapi.h>
|
||||
#include "MSIMysticLightCommon.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
class MSIMysticLight761Controller
|
||||
{
|
||||
public:
|
||||
MSIMysticLight761Controller
|
||||
(
|
||||
hid_device* handle,
|
||||
const char *path,
|
||||
unsigned short pid
|
||||
);
|
||||
~MSIMysticLight761Controller();
|
||||
|
||||
void SetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE mode,
|
||||
MSI_SPEED speed,
|
||||
MSI_BRIGHTNESS brightness,
|
||||
bool rainbow_color
|
||||
);
|
||||
|
||||
MSI_MODE GetMode();
|
||||
|
||||
void GetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE &mode,
|
||||
MSI_SPEED &speed,
|
||||
MSI_BRIGHTNESS &brightness,
|
||||
bool &rainbow_color,
|
||||
unsigned int &color
|
||||
);
|
||||
|
||||
void SetZoneColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
);
|
||||
|
||||
void SetLedColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
int index,
|
||||
unsigned char red,
|
||||
unsigned char grn,
|
||||
unsigned char blu
|
||||
);
|
||||
|
||||
void SetCycleCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char cycle_num
|
||||
);
|
||||
|
||||
bool Update
|
||||
(
|
||||
bool save
|
||||
);
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetFWVersion();
|
||||
std::string GetSerial();
|
||||
|
||||
void SetDirectMode
|
||||
(
|
||||
bool mode
|
||||
);
|
||||
bool IsDirectModeActive() { return true; }
|
||||
size_t GetMaxDirectLeds
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
const std::vector<MSI_ZONE>*
|
||||
GetSupportedZones() { return supported_zones; }
|
||||
|
||||
enum DIRECT_MODE
|
||||
{
|
||||
DIRECT_MODE_DISABLED,
|
||||
DIRECT_MODE_PER_LED,
|
||||
DIRECT_MODE_ZONE_BASED
|
||||
};
|
||||
|
||||
DIRECT_MODE GetSupportedDirectMode() { return DIRECT_MODE_PER_LED; }
|
||||
|
||||
struct ZoneConfig
|
||||
{
|
||||
MSI_ZONE msi_zone;
|
||||
ZoneData * zone_data;
|
||||
};
|
||||
|
||||
private:
|
||||
bool ReadSettings();
|
||||
bool ReadFwVersion();
|
||||
void ReadName();
|
||||
std::string name;
|
||||
std::vector<MSIMysticLight761Controller::ZoneConfig> zone_configs;
|
||||
|
||||
ZoneData* GetZoneData
|
||||
(
|
||||
FeaturePacket_761& data_packet,
|
||||
MSI_ZONE zone
|
||||
);
|
||||
RainbowZoneData* GetRainbowZoneData(MSI_ZONE zone);
|
||||
Color* GetPerLedZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
void SelectPerLedProtocol();
|
||||
|
||||
std::vector<MSI_ZONE>* supported_zones;
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string version_APROM;
|
||||
std::string version_LDROM;
|
||||
FeaturePacket_761* data;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
@ -0,0 +1,467 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| MSIMysticLight185Controller.cpp |
|
||||
| |
|
||||
| RGBController for MSI Mystic Light 761-byte motherboard |
|
||||
| |
|
||||
| |
|
||||
| rom4ster 11 Jun 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_MSIMysticLight761.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
struct ZoneDescription
|
||||
{
|
||||
std::string name;
|
||||
MSI_ZONE zone_type;
|
||||
};
|
||||
|
||||
#define NUMOF_ZONES (sizeof(led_zones) / sizeof(ZoneDescription))
|
||||
|
||||
const ZoneDescription led_zones[] =
|
||||
{
|
||||
ZoneDescription{ "JAF", MSI_ZONE_JAF },
|
||||
ZoneDescription{ "JARGB 1", MSI_ZONE_JARGB_1 },
|
||||
ZoneDescription{ "JARGB 2", MSI_ZONE_JARGB_2 },
|
||||
ZoneDescription{ "JARGB 3", MSI_ZONE_JARGB_3 },
|
||||
};
|
||||
|
||||
static std::vector<const ZoneDescription*> zone_description;
|
||||
|
||||
static int IndexOfZoneForType(MSI_ZONE zone_type)
|
||||
{
|
||||
for(size_t i = 0; i < zone_description.size(); ++i)
|
||||
{
|
||||
if(zone_description[i]->zone_type == zone_type)
|
||||
{
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
RGBController_MSIMysticLight761::RGBController_MSIMysticLight761
|
||||
(
|
||||
MSIMysticLight761Controller* controller_ptr
|
||||
)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "MSI";
|
||||
type = DEVICE_TYPE_MOTHERBOARD;
|
||||
description = "MSI Mystic Light Device (761-byte)";
|
||||
version = controller->GetFWVersion();
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerial();
|
||||
|
||||
const std::vector<MSI_ZONE>* supported_zones = controller->GetSupportedZones();
|
||||
|
||||
for(std::size_t i = 0; i < supported_zones->size(); ++i)
|
||||
{
|
||||
for(std::size_t j = 0; j < NUMOF_ZONES; ++j)
|
||||
{
|
||||
if(led_zones[j].zone_type == (*supported_zones)[i])
|
||||
{
|
||||
zone_description.push_back(&led_zones[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_resizable_zone = MSI_ZONE_NONE;
|
||||
SetupModes();
|
||||
SetupZones();
|
||||
active_mode = GetDeviceMode();
|
||||
}
|
||||
|
||||
RGBController_MSIMysticLight761::~RGBController_MSIMysticLight761()
|
||||
{
|
||||
zone_description.clear();
|
||||
delete controller;
|
||||
}
|
||||
|
||||
int RGBController_MSIMysticLight761::GetDeviceMode()
|
||||
{
|
||||
MSI_MODE mode = controller->GetMode();
|
||||
|
||||
for(unsigned int i = 0; i < modes.size(); ++i)
|
||||
{
|
||||
if(mode == modes[i].value)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::SetupZones()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
|
||||
bool first_run = false;
|
||||
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zone_description.size(); ++zone_idx)
|
||||
{
|
||||
const ZoneDescription* zd = zone_description[zone_idx];
|
||||
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = zd->name;
|
||||
new_zone.flags = 0;
|
||||
|
||||
int maxLeds = (int)controller->GetMaxDirectLeds(zd->zone_type);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| This is a fixed size zone |
|
||||
\*-------------------------------------------------*/
|
||||
if(((zd->zone_type != MSI_ZONE_J_RAINBOW_1)
|
||||
&& (zd->zone_type != MSI_ZONE_J_RAINBOW_2)
|
||||
&& (zd->zone_type != MSI_ZONE_J_RAINBOW_3)
|
||||
&& (zd->zone_type != MSI_ZONE_JAF)
|
||||
&& (zd->zone_type != MSI_ZONE_JARGB_1)
|
||||
&& (zd->zone_type != MSI_ZONE_JARGB_2)
|
||||
&& (zd->zone_type != MSI_ZONE_JARGB_3)
|
||||
&& (zd->zone_type != MSI_ZONE_J_CORSAIR)))
|
||||
{
|
||||
new_zone.leds_min = maxLeds;
|
||||
new_zone.leds_max = maxLeds;
|
||||
new_zone.leds_count = maxLeds;
|
||||
}
|
||||
/*--------------------------------------------------\
|
||||
| This is a resizable zone on a board that does not |
|
||||
| support per-LED direct mode |
|
||||
\*-------------------------------------------------*/
|
||||
else if(controller->GetSupportedDirectMode() == MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED)
|
||||
{
|
||||
new_zone.leds_min = 0;
|
||||
new_zone.leds_max = 30;//maxLeds;
|
||||
new_zone.leds_count = 0;
|
||||
last_resizable_zone = zd->zone_type;
|
||||
new_zone.flags |= ZONE_FLAG_RESIZE_EFFECTS_ONLY;
|
||||
}
|
||||
/*--------------------------------------------------\
|
||||
| This is a resizable zone on a board that does |
|
||||
| support per-LED direct mode |
|
||||
\*-------------------------------------------------*/
|
||||
else
|
||||
{
|
||||
new_zone.leds_min = 0;
|
||||
new_zone.leds_max = maxLeds;
|
||||
new_zone.leds_count = 0;
|
||||
last_resizable_zone = zd->zone_type;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Determine zone type based on max number of LEDs |
|
||||
\*-------------------------------------------------*/
|
||||
if((new_zone.leds_max == 1) || (new_zone.flags & ZONE_FLAG_RESIZE_EFFECTS_ONLY))
|
||||
{
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
}
|
||||
|
||||
new_zone.matrix_map = NULL;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zone_description.size(); ++zone_idx)
|
||||
{
|
||||
controller->SetCycleCount(zone_description[zone_idx]->zone_type, zones[zone_idx].leds_count);
|
||||
|
||||
if((zones[zone_idx].flags & ZONE_FLAG_RESIZE_EFFECTS_ONLY) == 0)
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; ++led_idx)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = zones[zone_idx].name;
|
||||
|
||||
if(zones[zone_idx].leds_count > 1)
|
||||
{
|
||||
new_led.name.append(" LED " + std::to_string(led_idx + 1));
|
||||
}
|
||||
|
||||
new_led.value = zone_description[zone_idx]->zone_type;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
else if(zones[zone_idx].leds_count > 0)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = zones[zone_idx].name;
|
||||
|
||||
new_led.value = zone_description[zone_idx]->zone_type;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
|
||||
void RGBController_MSIMysticLight761::ResizeZone
|
||||
(
|
||||
int zone,
|
||||
int new_size
|
||||
)
|
||||
{
|
||||
if((size_t)zone >= zones.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
|
||||
{
|
||||
zones[zone].leds_count = new_size;
|
||||
SetupZones();
|
||||
|
||||
if(zone_description[zone]->zone_type == last_resizable_zone)
|
||||
{
|
||||
GetDeviceConfig();
|
||||
last_resizable_zone = MSI_ZONE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); ++zone_idx)
|
||||
{
|
||||
for(int led_idx = zones[zone_idx].leds_count - 1; led_idx >= 0; led_idx--)
|
||||
{
|
||||
UpdateLed((int)zone_idx, led_idx);
|
||||
}
|
||||
}
|
||||
controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0);
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
for(int led_idx = zones[zone].leds_count - 1; led_idx >= 0; led_idx--)
|
||||
{
|
||||
UpdateLed(zone, led_idx);
|
||||
}
|
||||
controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0);
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::UpdateSingleLED
|
||||
(
|
||||
int led
|
||||
)
|
||||
{
|
||||
int zone_index = IndexOfZoneForType((MSI_ZONE)leds[led].value);
|
||||
|
||||
if(zone_index == -1)
|
||||
{
|
||||
LOG_DEBUG("[%s]: could not find zone for type %d", controller->GetDeviceName().c_str(), leds[led].value);
|
||||
return;
|
||||
}
|
||||
|
||||
int led_index = led - zones[zone_index].start_idx;
|
||||
UpdateLed(zone_index, led_index);
|
||||
controller->Update((modes[active_mode].flags & MODE_FLAG_AUTOMATIC_SAVE) != 0);
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].value == MSI_MODE_DIRECT_DUMMY)
|
||||
{
|
||||
controller->SetDirectMode(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetDirectMode(false);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::DeviceSaveMode()
|
||||
{
|
||||
controller->Update(true);
|
||||
}
|
||||
|
||||
|
||||
void RGBController_MSIMysticLight761::SetupModes()
|
||||
{
|
||||
constexpr unsigned int PER_LED_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
constexpr unsigned int RANDOM_ONLY = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_MANUAL_SAVE;
|
||||
constexpr unsigned int COMMON = RANDOM_ONLY | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
|
||||
if(controller->GetSupportedDirectMode() != MSIMysticLight761Controller::DIRECT_MODE_DISABLED)
|
||||
{
|
||||
SetupMode("Direct", MSI_MODE_DIRECT_DUMMY, MODE_FLAG_HAS_PER_LED_COLOR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::UpdateLed
|
||||
(
|
||||
int zone,
|
||||
int led
|
||||
)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(zones[zone].colors[led]);
|
||||
unsigned char grn = RGBGetGValue(zones[zone].colors[led]);
|
||||
unsigned char blu = RGBGetBValue(zones[zone].colors[led]);
|
||||
|
||||
if(controller->IsDirectModeActive())
|
||||
{
|
||||
controller->SetLedColor((MSI_ZONE)(zones[zone].leds[led].value), led, red, grn, blu);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(led == 0)
|
||||
{
|
||||
bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM;
|
||||
MSI_MODE mode = (MSI_MODE)modes[active_mode].value;
|
||||
MSI_SPEED speed = (MSI_SPEED)modes[active_mode].speed;
|
||||
MSI_BRIGHTNESS brightness = (MSI_BRIGHTNESS)modes[active_mode].brightness;
|
||||
|
||||
controller->SetMode((MSI_ZONE)zones[zone].leds[led].value, mode, speed, brightness, random);
|
||||
controller->SetZoneColor((MSI_ZONE)zones[zone].leds[led].value, red, grn, blu, red, grn, blu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::SetupMode
|
||||
(
|
||||
const char *name,
|
||||
MSI_MODE mod,
|
||||
unsigned int flags
|
||||
)
|
||||
{
|
||||
mode Mode;
|
||||
Mode.name = name;
|
||||
Mode.value = mod;
|
||||
Mode.flags = flags;
|
||||
|
||||
if(flags & MODE_FLAG_HAS_PER_LED_COLOR)
|
||||
{
|
||||
Mode.color_mode = MODE_COLORS_PER_LED;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
}
|
||||
|
||||
if(flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
Mode.speed = MSI_SPEED_MEDIUM;
|
||||
Mode.speed_max = MSI_SPEED_HIGH;
|
||||
Mode.speed_min = MSI_SPEED_LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| For modes without speed this needs to be set to avoid |
|
||||
| bad values in the saved profile which in turn corrupts |
|
||||
| the brightness calculation when loading the profile |
|
||||
\*---------------------------------------------------------*/
|
||||
Mode.speed = 0;
|
||||
Mode.speed_max = 0;
|
||||
Mode.speed_min = 0;
|
||||
}
|
||||
|
||||
if(flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
Mode.brightness = MSI_BRIGHTNESS_LEVEL_100;
|
||||
Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100;
|
||||
Mode.brightness_min = MSI_BRIGHTNESS_OFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode.brightness = MSI_BRIGHTNESS_LEVEL_100;
|
||||
Mode.brightness_max = MSI_BRIGHTNESS_LEVEL_100;
|
||||
Mode.brightness_min = MSI_BRIGHTNESS_LEVEL_100;
|
||||
}
|
||||
|
||||
modes.push_back(Mode);
|
||||
}
|
||||
|
||||
void RGBController_MSIMysticLight761::GetDeviceConfig()
|
||||
{
|
||||
if(controller->GetMode() != MSI_MODE_DIRECT_DUMMY)
|
||||
{
|
||||
MSI_MODE mode;
|
||||
MSI_SPEED speed;
|
||||
MSI_BRIGHTNESS brightness;
|
||||
bool rainbow;
|
||||
unsigned int color;
|
||||
|
||||
for(size_t i = 0; i < zone_description.size(); ++i)
|
||||
{
|
||||
controller->GetMode(zone_description[i]->zone_type, mode, speed, brightness, rainbow, color);
|
||||
|
||||
if(zones[i].colors != nullptr)
|
||||
{
|
||||
for(size_t j = 0; j < zones[i].leds_count; ++j)
|
||||
{
|
||||
zones[i].colors[j] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
controller->GetMode(zone_description[0]->zone_type, mode, speed, brightness, rainbow, color);
|
||||
|
||||
for(size_t i = 0; i < modes.size(); ++i)
|
||||
{
|
||||
if(mode == modes[i].value)
|
||||
{
|
||||
if(modes[i].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[i].speed = speed;
|
||||
}
|
||||
if(modes[i].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
modes[i].brightness = brightness;
|
||||
}
|
||||
if(rainbow)
|
||||
{
|
||||
if(modes[i].flags & (MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR))
|
||||
{
|
||||
if(rainbow)
|
||||
{
|
||||
modes[i].color_mode = MODE_COLORS_RANDOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
modes[i].color_mode = MODE_COLORS_PER_LED;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*---------------------------------------------------------*\
|
||||
| MSIMysticLight185Controller.cpp |
|
||||
| |
|
||||
| RGBController for MSI Mystic Light 761-byte motherboard |
|
||||
| |
|
||||
| |
|
||||
| rom4ster 11 Jun 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "MSIMysticLight761Controller.h"
|
||||
|
||||
class RGBController_MSIMysticLight761: public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_MSIMysticLight761(MSIMysticLight761Controller* controller_ptr);
|
||||
~RGBController_MSIMysticLight761();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
void SetupModes();
|
||||
void UpdateLed
|
||||
(
|
||||
int zone,
|
||||
int led
|
||||
);
|
||||
void SetupMode
|
||||
(
|
||||
const char *name,
|
||||
MSI_MODE mode,
|
||||
unsigned int flags
|
||||
);
|
||||
int GetDeviceMode();
|
||||
void GetDeviceConfig();
|
||||
|
||||
MSIMysticLight761Controller* controller;
|
||||
MSI_ZONE last_resizable_zone;
|
||||
};
|
||||
|
|
@ -35,7 +35,11 @@ enum MSI_ZONE
|
|||
MSI_ZONE_ON_BOARD_LED_7 = 17,
|
||||
MSI_ZONE_ON_BOARD_LED_8 = 18,
|
||||
MSI_ZONE_ON_BOARD_LED_9 = 19,
|
||||
MSI_ZONE_ON_BOARD_LED_10 = 20
|
||||
MSI_ZONE_ON_BOARD_LED_10 = 20,
|
||||
MSI_ZONE_JAF = 21,
|
||||
MSI_ZONE_JARGB_1 = 22,
|
||||
MSI_ZONE_JARGB_2 = 23,
|
||||
MSI_ZONE_JARGB_3 = 24,
|
||||
};
|
||||
|
||||
enum MSI_MODE
|
||||
|
|
@ -113,6 +117,7 @@ enum MSI_BRIGHTNESS
|
|||
};
|
||||
|
||||
#define NUMOF_PER_LED_MODE_LEDS 240
|
||||
#define NUM_LEDS_761 720
|
||||
|
||||
#define SYNC_SETTING_ONBOARD 0x01
|
||||
#define SYNC_SETTING_JRAINBOW1 0x02
|
||||
|
|
@ -241,4 +246,30 @@ struct FeaturePacket_PerLED_185
|
|||
Color leds[NUMOF_PER_LED_MODE_LEDS];
|
||||
};
|
||||
|
||||
struct FeaturePacket_PerLED_761
|
||||
{
|
||||
unsigned char report_id = 0x51; // Report ID
|
||||
unsigned char fixed1 = 0x09; // Always 9?
|
||||
unsigned char hdr0; // 0x08 for ez 0x04 for ARGB 0x06 for LED
|
||||
unsigned char hdr1; // 0 for LED/EZ and argb num for ARGB?
|
||||
unsigned char fixed2 = 0x00; // IDK what this is
|
||||
unsigned char fixed3 = 0x00; // IDK what this is
|
||||
unsigned char hdr2; // Led Count
|
||||
unsigned char colors [NUM_LEDS_761];
|
||||
};
|
||||
|
||||
struct FeaturePacket_Zone_761
|
||||
{
|
||||
MSI_ZONE zone;
|
||||
FeaturePacket_PerLED_761 packet;
|
||||
};
|
||||
|
||||
struct FeaturePacket_761
|
||||
{
|
||||
FeaturePacket_Zone_761 jargb1;
|
||||
FeaturePacket_Zone_761 jargb2;
|
||||
FeaturePacket_Zone_761 jargb3;
|
||||
FeaturePacket_Zone_761 jaf;
|
||||
};
|
||||
|
||||
#define MSI_USB_PID_COMMON 0x0076 // Common PID for a certain set of 185-byte boards
|
||||
|
|
|
|||
|
|
@ -12,10 +12,12 @@
|
|||
#include "MSIMysticLight112Controller.h"
|
||||
#include "MSIMysticLight162Controller.h"
|
||||
#include "MSIMysticLight185Controller.h"
|
||||
#include "MSIMysticLight761Controller.h"
|
||||
#include "RGBController_MSIMysticLight64.h"
|
||||
#include "RGBController_MSIMysticLight112.h"
|
||||
#include "RGBController_MSIMysticLight162.h"
|
||||
#include "RGBController_MSIMysticLight185.h"
|
||||
#include "RGBController_MSIMysticLight761.h"
|
||||
#include "dmiinfo.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
|
|
@ -52,7 +54,7 @@ void DetectMSIMysticLightControllers
|
|||
size_t packet_length = hid_get_feature_report(dev, temp_buffer, 200);
|
||||
DMIInfo dmi;
|
||||
|
||||
if((packet_length >= sizeof(FeaturePacket_185)) && (packet_length <= (sizeof(FeaturePacket_185) + 1)))
|
||||
if((packet_length >= sizeof(FeaturePacket_185)) && (packet_length <= (sizeof(FeaturePacket_185) + 1))) //WHY r we doing this ? why not ==
|
||||
{
|
||||
MSIMysticLight185Controller* controller = new MSIMysticLight185Controller(dev, info->path, info->product_id);
|
||||
RGBController_MSIMysticLight185* rgb_controller = new RGBController_MSIMysticLight185(controller);
|
||||
|
|
@ -75,9 +77,31 @@ void DetectMSIMysticLightControllers
|
|||
}
|
||||
else // no supported length returned
|
||||
{
|
||||
std::string name = "MSI " + dmi.getMainboard();
|
||||
LOG_INFO("No matching driver found for %s, packet length = %d", name.c_str(), packet_length);
|
||||
return;
|
||||
|
||||
unsigned char second_buffer [1000];
|
||||
second_buffer[0] = 0x51;
|
||||
|
||||
for(int i = 1; i < 1000; i++)
|
||||
{
|
||||
second_buffer[i] = 0x0;
|
||||
}
|
||||
|
||||
size_t packet_length_new_attempt = hid_get_feature_report(dev, second_buffer, 1000);
|
||||
|
||||
if(packet_length_new_attempt >=290 && packet_length_new_attempt <= 291)
|
||||
{
|
||||
MSIMysticLight761Controller* controller = new MSIMysticLight761Controller(dev, info->path, info->product_id);
|
||||
RGBController_MSIMysticLight761* rgb_controller = new RGBController_MSIMysticLight761(controller);
|
||||
rgb_controller->name = "MSI " + dmi.getMainboard();
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = "MSI " + dmi.getMainboard();
|
||||
LOG_INFO("No matching driver found for %s, packet length = %d", name.c_str(), packet_length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -196,6 +220,7 @@ REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7E10", DetectMSIMysticLightCont
|
|||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_B926", DetectMSIMysticLightControllers, MSI_USB_VID, 0xB926, 0x0001, 0x00);
|
||||
// Detector for the set of common boards
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light Common", DetectMSIMysticLightControllers, MSI_USB_VID_COMMON, MSI_USB_PID_COMMON, 0x0001, 0x00);
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light X870", DetectMSIMysticLightControllers, MSI_USB_VID_COMMON, MSI_USB_PID_COMMON, 0xFF00, 0x01);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Dummy entries for boards using commwn VID and PID |
|
||||
| |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue