Inital split for ASRock SMBus controllers

This commit is contained in:
TheRogueZeta 2022-07-04 20:15:58 +00:00 committed by Adam Honse
parent 6def6a7772
commit 3f79cc41c8
18 changed files with 1948 additions and 1381 deletions

View file

@ -1,353 +0,0 @@
/*-----------------------------------------*\
| ASRockPolychromeSMBusController.cpp |
| |
| Driver for for ASRock ASR LED and |
| Polychrome RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/14/2019 |
\*-----------------------------------------*/
#include "ASRockPolychromeSMBusController.h"
#include <cstring>
#include "dependencies/dmiinfo.h"
#include "LogManager.h"
#define ASROCK_ZONE_LED_COUNT_MESSAGE_EN "[%s] Zone %i LED count: %02d"
using namespace std::chrono_literals;
PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_dev_id dev)
{
this->bus = bus;
this->dev = dev;
DMIInfo dmi;
device_name = "ASRock " + dmi.getMainboard();
fw_version = ReadFirmwareVersion();
unsigned char major_version = fw_version >> 8;
/*-----------------------------------------------------*\
| Determine whether the device uses ASR LED or |
| Polychrome protocol by checking firmware version. |
| Versions: 1.xx are ASR RGB LED |
| 2.xx are Polychrome v1 |
| 3.xx are Polychrome v2 |
\*-----------------------------------------------------*/
switch(major_version)
{
case ASROCK_TYPE_ASRLED:
LOG_TRACE("[%s] Device type is ASR RGB LED", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_ASRLED;
memset(zone_led_count, 0, sizeof(zone_led_count));
break;
case ASROCK_TYPE_POLYCHROME_V1:
LOG_TRACE("[%s] Device type is Polychrome v1", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_POLYCHROME_V1;
ReadLEDConfiguration();
break;
case ASROCK_TYPE_POLYCHROME_V2:
LOG_TRACE("[%s] Device type is Polychrome v2", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_POLYCHROME_V2;
ReadLEDConfiguration();
break;
default:
LOG_TRACE("[%s] Got Unknown version!", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_UNKNOWN;
break;
}
}
PolychromeController::~PolychromeController()
{
}
unsigned int PolychromeController::GetASRockType()
{
return(asrock_type);
}
std::string PolychromeController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
}
std::string PolychromeController::GetDeviceName()
{
return(device_name);
}
std::string PolychromeController::GetFirmwareVersion()
{
unsigned char major_version = fw_version >> 8;
unsigned char minor_version = fw_version & 0xFF;
return(std::to_string(major_version) + "." + std::to_string(minor_version));
}
unsigned short PolychromeController::ReadFirmwareVersion()
{
// The firmware register holds two bytes, so the first read should return 2
// If not, report invalid firmware revision FFFF
LOG_DEBUG("[%s] Reading back device firmware version", ASROCK_CONTROLLER_NAME);
// Version response array needs to be 32 bytes to prevent non ASRock board from stack smashing
unsigned char asrock_version[I2C_SMBUS_BLOCK_MAX] = { 0x00, 0x00 };
if (bus->i2c_smbus_read_block_data(dev, ASROCK_REG_FIRMWARE_VER, asrock_version) == 0x02)
{
unsigned char major = asrock_version[0];
unsigned char minor = asrock_version[1];
LOG_DEBUG("[%s] Device firmware version: v%02d.%02d", ASROCK_CONTROLLER_NAME, major, minor);
return((major << 8) | minor);
}
else
{
LOG_WARNING("[%s] Firmware readback failed; Returning 0xFFFF", ASROCK_CONTROLLER_NAME);
return(0xFFFF);
}
}
void PolychromeController::ReadLEDConfiguration()
{
/*---------------------------------------------------------------------------------*\
| The LED configuration register holds 6 bytes, so the first read should return 6 |
| If not, set all zone sizes to zero |
\*---------------------------------------------------------------------------------*/
LOG_DEBUG("[%s] Reading LED config from controller", ASROCK_CONTROLLER_NAME);
unsigned char asrock_zone_count[I2C_SMBUS_BLOCK_MAX] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
if (bus->i2c_smbus_read_block_data(dev, POLYCHROME_REG_LED_CONFIG, asrock_zone_count) == 0x06)
{
zone_led_count[POLYCHROME_ZONE_1] = asrock_zone_count[0];
zone_led_count[POLYCHROME_ZONE_2] = asrock_zone_count[1];
zone_led_count[POLYCHROME_ZONE_3] = asrock_zone_count[2];
zone_led_count[POLYCHROME_ZONE_4] = asrock_zone_count[3];
zone_led_count[POLYCHROME_ZONE_5] = asrock_zone_count[4];
zone_led_count[POLYCHROME_ZONE_ADDRESSABLE] = asrock_zone_count[5];
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, ASROCK_CONTROLLER_NAME, POLYCHROME_ZONE_1, zone_led_count[POLYCHROME_ZONE_1]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, ASROCK_CONTROLLER_NAME, POLYCHROME_ZONE_2, zone_led_count[POLYCHROME_ZONE_2]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, ASROCK_CONTROLLER_NAME, POLYCHROME_ZONE_3, zone_led_count[POLYCHROME_ZONE_3]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, ASROCK_CONTROLLER_NAME, POLYCHROME_ZONE_4, zone_led_count[POLYCHROME_ZONE_4]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, ASROCK_CONTROLLER_NAME, POLYCHROME_ZONE_5, zone_led_count[POLYCHROME_ZONE_5]);
LOG_DEBUG("[%s] Addressable Zone LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_ADDRESSABLE]);
}
else
{
LOG_WARNING("[%s] LED config read failed", ASROCK_CONTROLLER_NAME);
memset(zone_led_count, 0, sizeof(zone_led_count));
}
}
unsigned int PolychromeController::GetMode()
{
return(active_mode);
}
void PolychromeController::SetColorsAndSpeed(unsigned char led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char color_speed_pkt[4] = { red, green, blue, active_speed };
unsigned char select_led_pkt[1] = { led };
switch(asrock_type)
{
case ASROCK_TYPE_ASRLED:
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
if(active_mode != ASRLED_MODE_OFF)
{
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
}
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case ASRLED_MODE_BREATHING:
case ASRLED_MODE_STROBE:
case ASRLED_MODE_SPECTRUM_CYCLE:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case ASRLED_MODE_STATIC:
case ASRLED_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case ASRLED_MODE_RANDOM:
case ASRLED_MODE_WAVE:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &active_speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case ASRLED_MODE_OFF:
break;
}
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V1:
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
if(active_mode != ASRLED_MODE_OFF)
{
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
}
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_BREATHING:
case POLYCHROME_V1_MODE_STROBE:
case POLYCHROME_V1_MODE_SPECTRUM_CYCLE:
case POLYCHROME_V1_MODE_SPRING:
case POLYCHROME_V1_MODE_METEOR:
case POLYCHROME_V1_MODE_STACK:
case POLYCHROME_V1_MODE_CRAM:
case POLYCHROME_V1_MODE_SCAN:
case POLYCHROME_V1_MODE_NEON:
case POLYCHROME_V1_MODE_WATER:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case POLYCHROME_V1_MODE_STATIC:
case POLYCHROME_V1_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_RANDOM:
case POLYCHROME_V1_MODE_WAVE:
case POLYCHROME_V1_MODE_RAINBOW:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &active_speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_OFF:
break;
}
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V2:
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
switch(active_mode)
{
case POLYCHROME_V2_MODE_OFF:
case POLYCHROME_V2_MODE_RAINBOW:
case POLYCHROME_V2_MODE_SPECTRUM_CYCLE:
break;
default:
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Polychrome firmware always writes color to fixed reg |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_COLOR, 3, color_speed_pkt);
std::this_thread::sleep_for(1ms);
break;
}
break;
}
}
void PolychromeController::SetMode(unsigned char zone,unsigned char mode, unsigned char speed)
{
unsigned char led_count_pkt[1] = { 0x00 };
active_zone = zone;
active_mode = mode;
active_speed = speed;
switch(asrock_type)
{
case ASROCK_TYPE_ASRLED:
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V1:
/*-----------------------------------------------------*\
| Make sure set all register is set to 0 |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V1_REG_SET_ALL, 1, led_count_pkt);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Set the zone we are working on |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_LED_SELECT, 1, &active_zone);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Write the mode |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
break;
case ASROCK_TYPE_POLYCHROME_V2:
bus->i2c_smbus_write_block_data(dev, ASROCK_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Select a single LED |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_LED_COUNT, 0, led_count_pkt);
std::this_thread::sleep_for(1ms);
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes don't take a speed |
\*-----------------------------------------------------*/
case POLYCHROME_V2_MODE_OFF:
case POLYCHROME_V2_MODE_STATIC:
break;
/*-----------------------------------------------------*\
| All other modes, write speed to active mode register |
\*-----------------------------------------------------*/
default:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
std::this_thread::sleep_for(1ms);
break;
}
break;
}
}

View file

@ -1,271 +0,0 @@
/*-----------------------------------------*\
| ASRockPolychromeSMBusController.h |
| |
| Definitions and types for ASRock |
| ASR LED and Polychrome RGB lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/13/2019 |
\*-----------------------------------------*/
#include "i2c_smbus.h"
#include <string>
#pragma once
typedef unsigned char polychrome_dev_id;
#define ASROCK_CONTROLLER_NAME "ASRock Polychrome SMBus Controller"
#define ASROCK_DETECTOR_NAME "ASRock Polychrome SMBus Detect"
#define VENDOR_NAME "ASRock"
#define SMBUS_ADDRESS 0x6A
enum
{
ASROCK_TYPE_UNKNOWN = 0x00, /* Unknown Type or Not ASRock Device */
ASROCK_TYPE_ASRLED = 0x01, /* ASRock Firmware 1.x - ASR LED */
ASROCK_TYPE_POLYCHROME_V1 = 0x02, /* ASRock Firmware 2.x - Polychrome V1 */
ASROCK_TYPE_POLYCHROME_V2 = 0x03, /* ASRock Firmware 3.x - Polychrome V2 */
};
enum
{
/*------------------------------------------------------------------------------------------*\
| ASRock Common Registers |
\*------------------------------------------------------------------------------------------*/
ASROCK_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
ASROCK_REG_MODE = 0x30, /* Mode selection register */
ASROCK_REG_LED_SELECT = 0x31, /* LED selection register */
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome V1/V2 Common Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_REG_LED_CONFIG = 0x33, /* LED configuration register */
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome V1 (Firmware 2.x) Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_REG_SET_ALL = 0x32, /* Set All register 0x1 = set all */
POLYCHROME_V1_REG_ARGB_GRB = 0x35, /* ARGB bistream reversing register */
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome V2 (Firmware 3.x) Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V2_REG_LED_COUNT = 0x32, /* Additional LED count register */
POLYCHROME_V2_REG_COLOR = 0x34, /* Color register: Red, Green, Blue */
POLYCHROME_V2_REG_ARGB_GRB = 0x35, /* ARGB bistream reversing register */
};
enum
{
POLYCHROME_ZONE_1 = 0x00, /* RGB LED 1 Header */
POLYCHROME_ZONE_2 = 0x01, /* RGB LED 2 Header */
POLYCHROME_ZONE_3 = 0x02, /* Audio/PCH Zone LEDs */
POLYCHROME_ZONE_4 = 0x03, /* Audio/PCH Zone LEDs */
POLYCHROME_ZONE_5 = 0x04, /* IO Cover Zone LEDs */
POLYCHROME_ZONE_ADDRESSABLE = 0x05, /* Addressable LED header */
POLYCHROME_ZONE_COUNT = 0x06, /* Total number of zones */
POLYCHROME_ZONE_ADDRESSABLE_MAX = 0x64, /* Maxinum number of ARGB LEDs */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for ASR LED |
\*----------------------------------------------------------------------------------------------*/
#define ASRLED_NUM_MODES 8 /* Number of ASR LED modes */
enum
{
ASRLED_MODE_OFF = 0x10, /* OFF mode */
ASRLED_MODE_STATIC = 0x11, /* Static color mode */
ASRLED_MODE_BREATHING = 0x12, /* Breathing effect mode */
ASRLED_MODE_STROBE = 0x13, /* Strobe effect mode */
ASRLED_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
ASRLED_MODE_RANDOM = 0x15, /* Random effect mode */
ASRLED_MODE_MUSIC = 0x17, /* Music effect mode */
ASRLED_MODE_WAVE = 0x18, /* Wave effect mode */
};
enum
{
ASRLED_SPEED_MIN = 0x05, /* Slowest speed */
ASRLED_SPEED_DEFAULT = 0x03, /* Default speed */
ASRLED_SPEED_MAX = 0x00, /* Fastest speed */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome V1 |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_V1_NUM_MODES 16 /* Number of Polychrome V1 modes */
enum
{
POLYCHROME_V1_MODE_OFF = 0x10, /* OFF mode */
POLYCHROME_V1_MODE_STATIC = 0x11, /* Static color mode */
POLYCHROME_V1_MODE_BREATHING = 0x12, /* Breating effect mode */
POLYCHROME_V1_MODE_STROBE = 0x13, /* Strobe effect mode */
POLYCHROME_V1_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
POLYCHROME_V1_MODE_RANDOM = 0x15, /* Random effect mode */
POLYCHROME_V1_MODE_MUSIC = 0x17, /* Music effect mode */
POLYCHROME_V1_MODE_WAVE = 0x18, /* Wave effect mode */
/*------------------------------------------------------------------------------------------*\
| Modes only available on ARGB headers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_MODE_SPRING = 0x19, /* Spring effect mode */
POLYCHROME_V1_MODE_METEOR = 0x1A, /* Meteor effect mode */
POLYCHROME_V1_MODE_STACK = 0x1B, /* Stack effect mode */
POLYCHROME_V1_MODE_CRAM = 0x1C, /* Cram effect mode */
POLYCHROME_V1_MODE_SCAN = 0x1D, /* Scan effect mode */
POLYCHROME_V1_MODE_NEON = 0x1E, /* Neon effect mode */
POLYCHROME_V1_MODE_WATER = 0x1F, /* Water effect mode */
POLYCHROME_V1_MODE_RAINBOW = 0x20, /* Rainbow chase effect mode */
};
enum
{
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_BREATHING |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_BREATHING = 0x0A, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_BREATHING = 0x02, /* Default speed */
POLYCHROME_V1_SPEED_MAX_BREATHING = 0x02, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_STROBE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_STROBE = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_STROBE = 0x14, /* Default speed */
POLYCHROME_V1_SPEED_MAX_STROBE = 0x05, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_SPECTRUM_CYCLE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_CYCLE = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_CYCLE = 0x14, /* Default speed */
POLYCHROME_V1_SPEED_MAX_CYCLE = 0x0A, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_RANDOM |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_RANDOM = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_RANDOM = 0x28, /* Default speed */
POLYCHROME_V1_SPEED_MAX_RANDOM = 0x05, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_WAVE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_WAVE = 0x06, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_WAVE = 0x02, /* Default speed */
POLYCHROME_V1_SPEED_MAX_WAVE = 0x01, /* Fastest speed */
POLYCHROME_V1_SPEED_DEFAULT_SPRING = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_METEOR = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_STACK = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_CRAM = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_SCAN = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_NEON = 0x20, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_WATER = 0x0A, /* Default speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_RAINBOW |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_RAINBOW = 0x12, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_RAINBOW = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_MAX_RAINBOW = 0x01, /* Fastest speed */
POLYCHROME_V1_SPEED_MIN_ARGB = 0x20, /* Slowest speed */
POLYCHROME_V1_SPEED_MAX_ARGB = 0x02, /* Fastest speed */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome V2 |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_V2_NUM_MODES 14 /* Number of Polychrome V2 modes */
enum
{
POLYCHROME_V2_MODE_OFF = 0x10, /* OFF mode */
POLYCHROME_V2_MODE_STATIC = 0x11, /* Static color mode */
POLYCHROME_V2_MODE_BREATHING = 0x12, /* Breating effect mode */
POLYCHROME_V2_MODE_STROBE = 0x13, /* Strobe effect mode */
POLYCHROME_V2_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
POLYCHROME_V2_MODE_RANDOM = 0x15, /* Random effect mode */
POLYCHROME_V2_MODE_WAVE = 0x17, /* Wave effect mode */
POLYCHROME_V2_MODE_SPRING = 0x18, /* Spring effect mode */
POLYCHROME_V2_MODE_STACK = 0x19, /* Stack effect mode */
POLYCHROME_V2_MODE_CRAM = 0x1A, /* Cram effect mode */
POLYCHROME_V2_MODE_SCAN = 0x1B, /* Scan effect mode */
POLYCHROME_V2_MODE_NEON = 0x1C, /* Neon effect mode */
POLYCHROME_V2_MODE_WATER = 0x1D, /* Water effect mode */
POLYCHROME_V2_MODE_RAINBOW = 0x1E, /* Rainbow effect mode */
};
enum
{
POLYCHROME_V2_BREATHING_SPEED_MIN = 0x0A, /* Slowest speed */
POLYCHROME_V2_BREATHING_SPEED_DEFAULT = 0x06, /* Default speed */
POLYCHROME_V2_BREATHING_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_STROBE_SPEED_MIN = 0xA0, /* Slowest speed */
POLYCHROME_V2_STROBE_SPEED_DEFAULT = 0x4D, /* Default speed */
POLYCHROME_V2_STROBE_SPEED_MAX = 0x05, /* Fastest speed */
POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MIN = 0xA0, /* Slowest speed */
POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_DEFAULT = 0x50, /* Default speed */
POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MAX = 0x0A, /* Fastest speed */
POLYCHROME_V2_RANDOM_SPEED_MIN = 0xA0, /* Slowest speed */
POLYCHROME_V2_RANDOM_SPEED_DEFAULT = 0x4D, /* Default speed */
POLYCHROME_V2_RANDOM_SPEED_MAX = 0x05, /* Fastest speed */
POLYCHROME_V2_WAVE_SPEED_MIN = 0x06, /* Slowest speed */
POLYCHROME_V2_WAVE_SPEED_DEFAULT = 0x03, /* Default speed */
POLYCHROME_V2_WAVE_SPEED_MAX = 0x01, /* Fastest speed */
POLYCHROME_V2_SPRING_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_SPRING_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_SPRING_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_STACK_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_STACK_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_STACK_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_CRAM_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_CRAM_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_CRAM_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_SCAN_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_SCAN_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_SCAN_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_NEON_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_NEON_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_NEON_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_WATER_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_WATER_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_WATER_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_RAINBOW_SPEED_MIN = 0x12, /* Slowest speed */
POLYCHROME_V2_RAINBOW_SPEED_DEFAULT = 0x08, /* Default speed */
POLYCHROME_V2_RAINBOW_SPEED_MAX = 0x02, /* Fastest speed */
};
class PolychromeController
{
public:
PolychromeController(i2c_smbus_interface* bus, polychrome_dev_id dev);
~PolychromeController();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetFirmwareVersion();
unsigned int GetMode();
unsigned int GetASRockType();
void SetColorsAndSpeed(unsigned char led, unsigned char red, unsigned char green, unsigned char blue);
void SetMode(unsigned char zone, unsigned char mode, unsigned char speed);
unsigned char zone_led_count[6];
private:
unsigned int asrock_type;
unsigned short fw_version;
std::string device_name;
unsigned char active_zone;
unsigned char active_mode;
unsigned char active_speed;
i2c_smbus_interface* bus;
polychrome_dev_id dev;
unsigned short ReadFirmwareVersion();
void ReadLEDConfiguration();
};

View file

@ -1,89 +0,0 @@
#include "Detector.h"
#include "ASRockPolychromeSMBusController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_ASRockPolychromeSMBus.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/******************************************************************************************\
* *
* TestForPolychromeSMBusController *
* *
* Tests the given address to see if an ASRock Polychrome RGB controller exists there.*
* First does a quick write to test for a response *
* *
\******************************************************************************************/
bool TestForPolychromeSMBusController(i2c_smbus_interface* bus, unsigned char address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
}
return(pass);
} /* TestForPolychromeController() */
/******************************************************************************************\
* *
* DetectPolychromeControllers *
* *
* Detect ASRock Polychrome RGB SMBus controllers on the enumerated I2C busses at *
* address 0x6A. *
* *
* bus - pointer to i2c_smbus_interface where Polychrome device is connected *
* dev - I2C address of Polychrome device *
* *
\******************************************************************************************/
void DetectPolychromeSMBusControllers(std::vector<i2c_smbus_interface*>& busses)
{
for(unsigned int bus = 0; bus < busses.size(); bus++)
{
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
if(busses[bus]->pci_subsystem_vendor == ASROCK_SUB_VEN)
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_MESSAGE_EN, ASROCK_DETECTOR_NAME, bus, VENDOR_NAME, SMBUS_ADDRESS);
// Check for Polychrome controller at 0x6A
if(TestForPolychromeSMBusController(busses[bus], SMBUS_ADDRESS))
{
LOG_DEBUG("[%s] Detected a device at address %02X, testing for a known controller", ASROCK_DETECTOR_NAME, SMBUS_ADDRESS);
PolychromeController* controller = new PolychromeController(busses[bus], SMBUS_ADDRESS);
if(controller->GetASRockType() != ASROCK_TYPE_UNKNOWN)
{
LOG_DEBUG("[%s] Found a known Polychrome device", ASROCK_DETECTOR_NAME);
RGBController_Polychrome* rgb_controller = new RGBController_Polychrome(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
LOG_DEBUG("[%s] Not a Polychrome device or unknown type", ASROCK_DETECTOR_NAME);
delete controller;
}
}
else
{
LOG_DEBUG("[%s] Bus %02d no response at %02X", ASROCK_DETECTOR_NAME, bus, SMBUS_ADDRESS);
}
}
else
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_FAILURE_EN, ASROCK_DETECTOR_NAME, bus, VENDOR_NAME);
}
}
}
} /* DetectSMBusPolychromeControllers() */
REGISTER_I2C_DETECTOR("ASRock Polychrome SMBus", DetectPolychromeSMBusControllers);

View file

@ -1,657 +0,0 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeSMBus.cpp |
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#include "RGBController_ASRockPolychromeSMBus.h"
#define ASROCK_MAX_ZONES 4
#define ASROCK_MAX_LEDS 22
static const char* polychrome_v1_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"PCH",
"IO Cover",
"Audio",
"Addressable Header"
};
static const char* polychrome_v2_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"Audio",
"PCH",
"IO Cover",
"Addressable Header"
};
/**------------------------------------------------------------------*\
@name ASRock Polychrome SMBus
@category Motherboard
@type SMBus
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectPolychromeSMBusControllers
@comment ASRock Polychrome controllers will save with each update.
Per ARGB LED support is not possible with these devices.
\*-------------------------------------------------------------------*/
RGBController_Polychrome::RGBController_Polychrome(PolychromeController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetDeviceName();
vendor = "ASRock";
version = controller->GetFirmwareVersion();
type = DEVICE_TYPE_MOTHERBOARD;
location = controller->GetDeviceLocation();
switch(controller->GetASRockType())
{
case ASROCK_TYPE_ASRLED:
{
description = "ASRock ASR RGB LED Device";
mode Off;
Off.name = "Off";
Off.value = ASRLED_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = ASRLED_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ASRLED_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = ASRLED_SPEED_MIN;
Breathing.speed_max = ASRLED_SPEED_MAX;
Breathing.speed = ASRLED_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = ASRLED_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = ASRLED_SPEED_MIN;
Strobe.speed_max = ASRLED_SPEED_MAX;
Strobe.speed = ASRLED_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = ASRLED_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = ASRLED_SPEED_MIN;
SpectrumCycle.speed_max = ASRLED_SPEED_MAX;
SpectrumCycle.speed = ASRLED_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = ASRLED_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = ASRLED_SPEED_MIN;
Random.speed_max = ASRLED_SPEED_MAX;
Random.speed = ASRLED_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Music.name = "Music";
Music.value = ASRLED_MODE_MUSIC;
Music.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Music.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Music);
mode Wave;
Wave.name = "Wave";
Wave.value = ASRLED_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = ASRLED_SPEED_MIN;
Wave.speed_max = ASRLED_SPEED_MAX;
Wave.speed = ASRLED_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
}
break;
case ASROCK_TYPE_POLYCHROME_V1:
{
description = "ASRock Polychrome v1 Device";
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_V1_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_V1_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_V1_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_V1_SPEED_MIN_BREATHING;
Breathing.speed_max = POLYCHROME_V1_SPEED_MAX_BREATHING;
Breathing.speed = POLYCHROME_V1_SPEED_DEFAULT_BREATHING;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_V1_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_V1_SPEED_MIN_STROBE;
Strobe.speed_max = POLYCHROME_V1_SPEED_MAX_STROBE;
Strobe.speed = POLYCHROME_V1_SPEED_DEFAULT_STROBE;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_V1_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_V1_SPEED_MIN_CYCLE;
SpectrumCycle.speed_max = POLYCHROME_V1_SPEED_MAX_CYCLE;
SpectrumCycle.speed = POLYCHROME_V1_SPEED_DEFAULT_CYCLE;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_V1_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_V1_SPEED_MIN_RANDOM;
Random.speed_max = POLYCHROME_V1_SPEED_MAX_RANDOM;
Random.speed = POLYCHROME_V1_SPEED_DEFAULT_RANDOM;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Music.name = "Music";
Music.value = POLYCHROME_V1_MODE_MUSIC;
Music.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Music.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Music);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_V1_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_V1_SPEED_MIN_WAVE;
Wave.speed_max = POLYCHROME_V1_SPEED_MAX_WAVE;
Wave.speed = POLYCHROME_V1_SPEED_DEFAULT_WAVE;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
/*---------------------------------------------------------------------*\
| Comment out until per zone modes are working. These are only for ARGB |
\*---------------------------------------------------------------------*/
/*
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_V1_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Spring.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Spring.speed = POLYCHROME_V1_SPEED_DEFAULT_SPRING;
Spring.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_V1_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Stack.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Stack.speed = POLYCHROME_V1_SPEED_DEFAULT_STACK;
Stack.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_V1_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Cram.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Cram.speed = POLYCHROME_V1_SPEED_DEFAULT_CRAM;
Cram.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_V1_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Scan.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Scan.speed = POLYCHROME_V1_SPEED_DEFAULT_SCAN;
Scan.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_V1_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED;
Neon.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Neon.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Neon.speed = POLYCHROME_V1_SPEED_DEFAULT_NEON;
Neon.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_V1_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Water.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Water.speed = POLYCHROME_V1_SPEED_DEFAULT_WATER;
Water.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_V1_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_V1_SPEED_MIN_RAINBOW;
Rainbow.speed_max = POLYCHROME_V1_SPEED_MAX_RAINBOW;
Rainbow.speed = POLYCHROME_V1_SPEED_DEFAULT_RAINBOW;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
*/
}
break;
case ASROCK_TYPE_POLYCHROME_V2:
{
description = "ASRock Polychrome v2 Device";
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_V2_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_V2_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_V2_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_V2_BREATHING_SPEED_MIN;
Breathing.speed_max = POLYCHROME_V2_BREATHING_SPEED_MAX;
Breathing.speed = POLYCHROME_V2_BREATHING_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_V2_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_V2_STROBE_SPEED_MIN;
Strobe.speed_max = POLYCHROME_V2_STROBE_SPEED_MAX;
Strobe.speed = POLYCHROME_V2_STROBE_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_V2_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MIN;
SpectrumCycle.speed_max = POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MAX;
SpectrumCycle.speed = POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_V2_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_V2_RANDOM_SPEED_MIN;
Random.speed_max = POLYCHROME_V2_RANDOM_SPEED_MAX;
Random.speed = POLYCHROME_V2_RANDOM_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_V2_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_V2_WAVE_SPEED_MIN;
Wave.speed_max = POLYCHROME_V2_WAVE_SPEED_MAX;
Wave.speed = POLYCHROME_V2_WAVE_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_V2_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_V2_SPRING_SPEED_MIN;
Spring.speed_max = POLYCHROME_V2_SPRING_SPEED_MAX;
Spring.speed = POLYCHROME_V2_SPRING_SPEED_DEFAULT;
Spring.color_mode = MODE_COLORS_NONE;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_V2_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_V2_STACK_SPEED_MIN;
Stack.speed_max = POLYCHROME_V2_STACK_SPEED_MAX;
Stack.speed = POLYCHROME_V2_STACK_SPEED_DEFAULT;
Stack.color_mode = MODE_COLORS_NONE;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_V2_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_V2_CRAM_SPEED_MIN;
Cram.speed_max = POLYCHROME_V2_CRAM_SPEED_MAX;
Cram.speed = POLYCHROME_V2_CRAM_SPEED_DEFAULT;
Cram.color_mode = MODE_COLORS_NONE;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_V2_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_V2_SCAN_SPEED_MIN;
Scan.speed_max = POLYCHROME_V2_SCAN_SPEED_MAX;
Scan.speed = POLYCHROME_V2_SCAN_SPEED_DEFAULT;
Scan.color_mode = MODE_COLORS_NONE;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_V2_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED;
Neon.speed_min = POLYCHROME_V2_NEON_SPEED_MIN;
Neon.speed_max = POLYCHROME_V2_NEON_SPEED_MAX;
Neon.speed = POLYCHROME_V2_NEON_SPEED_DEFAULT;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_V2_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_V2_WATER_SPEED_MIN;
Water.speed_max = POLYCHROME_V2_WATER_SPEED_MAX;
Water.speed = POLYCHROME_V2_WATER_SPEED_DEFAULT;
Water.color_mode = MODE_COLORS_NONE;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_V2_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_V2_RAINBOW_SPEED_MIN;
Rainbow.speed_max = POLYCHROME_V2_RAINBOW_SPEED_MAX;
Rainbow.speed = POLYCHROME_V2_RAINBOW_SPEED_DEFAULT;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
}
break;
}
SetupZones();
}
RGBController_Polychrome::~RGBController_Polychrome()
{
delete controller;
}
void RGBController_Polychrome::SetupZones()
{
switch(controller->GetASRockType())
{
/*---------------------------------------------------------*\
| ASR LED motherboards only have a single zone/LED |
\*---------------------------------------------------------*/
case ASROCK_TYPE_ASRLED:
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set single zone name to "Motherboard" |
\*---------------------------------------------------------*/
new_zone->name = "Motherboard";
new_zone->type = ZONE_TYPE_SINGLE;
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
led* new_led = new led();
/*---------------------------------------------------------*\
| Set single LED name to "Motherboard" |
\*---------------------------------------------------------*/
new_led->name = "Motherboard";
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
}
break;
/*---------------------------------------------------------*\
| Polychrome motherboards should set up zones based on LED |
| configuration register read from device |
\*---------------------------------------------------------*/
case ASROCK_TYPE_POLYCHROME_V1:
case ASROCK_TYPE_POLYCHROME_V2:
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < POLYCHROME_ZONE_COUNT; zone_idx++)
{
if(controller->zone_led_count[zone_idx] > 0)
{
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set zone name to channel name |
\*---------------------------------------------------------*/
if(controller->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
new_zone->name = polychrome_v1_zone_names[zone_idx];
}
else
{
new_zone->name = polychrome_v2_zone_names[zone_idx];
}
if(zone_idx == POLYCHROME_ZONE_ADDRESSABLE)
{
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
}
else
{
new_zone->leds_min = controller->zone_led_count[zone_idx];
new_zone->leds_max = controller->zone_led_count[zone_idx];
new_zone->leds_count = controller->zone_led_count[zone_idx];
}
if(new_zone->leds_count > 1)
{
new_zone->type = ZONE_TYPE_LINEAR;
}
else
{
new_zone->type = ZONE_TYPE_SINGLE;
}
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
}
}
unsigned int led_count = 0;
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < POLYCHROME_ZONE_COUNT; zone_idx++)
{
if(controller->zone_led_count[zone_idx] > 0)
{
for(unsigned int led_idx = 0; led_idx < controller->zone_led_count[zone_idx]; led_idx++)
{
/*---------------------------------------------------------*\
| Each zone only has one LED |
\*---------------------------------------------------------*/
led* new_led = new led();
if(controller->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
new_led->name = polychrome_v1_zone_names[zone_idx];
}
else
{
new_led->name = polychrome_v2_zone_names[zone_idx];
}
new_led->name.append(" " + std::to_string(led_idx + 1));
new_led->value = 0;
if(controller->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
new_led->value = zone_idx;
}
else if(zone_idx == POLYCHROME_ZONE_ADDRESSABLE)
{
new_led->value = 0x19;
}
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
led_count++;
if(zone_idx == POLYCHROME_ZONE_ADDRESSABLE)
{
break;
}
}
}
}
}
break;
}
SetupColors();
}
void RGBController_Polychrome::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_Polychrome::DeviceUpdateLEDs()
{
for (std::size_t led = 0; led < colors.size(); led++)
{
UpdateSingleLED(led);
}
}
void RGBController_Polychrome::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_Polychrome::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
/*---------------------------------------------------------*\
| If the LED value is non-zero, this LED overrides the LED |
| index |
\*---------------------------------------------------------*/
if(leds[led].value != 0)
{
led = leds[led].value;
}
controller->SetColorsAndSpeed(led, red, grn, blu);
}
void RGBController_Polychrome::SetCustomMode()
{
active_mode = 1;
}
void RGBController_Polychrome::DeviceUpdateMode()
{
if(controller->GetASRockType() == ASROCK_TYPE_POLYCHROME_V1)
{
for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++)
{
controller->SetMode(led_idx, modes[active_mode].value, modes[active_mode].speed);
}
}
else
{
controller->SetMode(0, modes[active_mode].value, modes[active_mode].speed);
}
DeviceUpdateLEDs();
}

View file

@ -0,0 +1,122 @@
/*-----------------------------------------*\
| ASRockPolychromeSMBusController.cpp |
| |
| Driver for for ASRock ASR LED and |
| Polychrome RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/14/2019 |
\*-----------------------------------------*/
#include "ASRockASRRGBSMBusController.h"
#include <cstring>
#include "dependencies/dmiinfo.h"
#include "LogManager.h"
#define ASROCK_ZONE_LED_COUNT_MESSAGE_EN "[%s] Zone %i LED count: %02d"
using namespace std::chrono_literals;
ASRockASRRGBSMBusController::ASRockASRRGBSMBusController(i2c_smbus_interface* bus, polychrome_dev_id dev)
{
this->bus = bus;
this->dev = dev;
DMIInfo dmi;
device_name = "ASRock " + dmi.getMainboard();
}
ASRockASRRGBSMBusController::~ASRockASRRGBSMBusController()
{
}
std::string ASRockASRRGBSMBusController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
}
std::string ASRockASRRGBSMBusController::GetDeviceName()
{
return(device_name);
}
std::string ASRockASRRGBSMBusController::GetFirmwareVersion()
{
uint8_t major_version = fw_version >> 8;
uint8_t minor_version = fw_version & 0xFF;
return(std::to_string(major_version) + "." + std::to_string(minor_version));
}
uint8_t ASRockASRRGBSMBusController::GetMode()
{
return(active_mode);
}
void ASRockASRRGBSMBusController::SetColorsAndSpeed(uint8_t led, uint8_t red, uint8_t green, uint8_t blue)
{
uint8_t color_speed_pkt[4] = { red, green, blue, active_speed };
uint8_t select_led_pkt[1] = { led };
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
if(active_mode != ASRLED_MODE_OFF)
{
bus->i2c_smbus_write_block_data(dev, ASROCK_ASR_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
}
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case ASRLED_MODE_BREATHING:
case ASRLED_MODE_STROBE:
case ASRLED_MODE_SPECTRUM_CYCLE:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case ASRLED_MODE_STATIC:
case ASRLED_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case ASRLED_MODE_RANDOM:
case ASRLED_MODE_WAVE:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &active_speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case ASRLED_MODE_OFF:
break;
}
std::this_thread::sleep_for(1ms);
}
void ASRockASRRGBSMBusController::SetMode(uint8_t zone,uint8_t mode, uint8_t speed)
{
active_zone = zone;
active_mode = mode;
active_speed = speed;
bus->i2c_smbus_write_block_data(dev, ASROCK_ASR_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
}

View file

@ -0,0 +1,76 @@
/*-----------------------------------------*\
| ASRockASRRGBSMBusController.h |
| |
| Definitions and types for ASRock |
| ASR LED and Polychrome RGB lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/13/2019 |
\*-----------------------------------------*/
#include "i2c_smbus.h"
#include <string>
#pragma once
typedef uint8_t polychrome_dev_id;
#define ASROCK_ASR_CONTROLLER_NAME "ASRock ASR RGB SMBus Controller"
enum
{
/*------------------------------------------------------------------------------------------*\
| ASRock Common Registers |
\*------------------------------------------------------------------------------------------*/
ASROCK_ASR_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
ASROCK_ASR_REG_MODE = 0x30, /* Mode selection register */
ASROCK_ASR_REG_LED_SELECT = 0x31, /* LED selection register */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for ASR LED |
\*----------------------------------------------------------------------------------------------*/
#define ASRLED_NUM_MODES 8 /* Number of ASR LED modes */
enum
{
ASRLED_MODE_OFF = 0x10, /* OFF mode */
ASRLED_MODE_STATIC = 0x11, /* Static color mode */
ASRLED_MODE_BREATHING = 0x12, /* Breathing effect mode */
ASRLED_MODE_STROBE = 0x13, /* Strobe effect mode */
ASRLED_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
ASRLED_MODE_RANDOM = 0x15, /* Random effect mode */
ASRLED_MODE_MUSIC = 0x17, /* Music effect mode */
ASRLED_MODE_WAVE = 0x18, /* Wave effect mode */
};
enum
{
ASRLED_SPEED_MIN = 0x05, /* Slowest speed */
ASRLED_SPEED_DEFAULT = 0x03, /* Default speed */
ASRLED_SPEED_MAX = 0x00, /* Fastest speed */
};
class ASRockASRRGBSMBusController
{
public:
ASRockASRRGBSMBusController(i2c_smbus_interface* bus, polychrome_dev_id dev);
~ASRockASRRGBSMBusController();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetFirmwareVersion();
uint8_t GetMode();
void SetColorsAndSpeed(uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
void SetMode(uint8_t zone, uint8_t mode, uint8_t speed);
uint16_t fw_version;
private:
std::string device_name;
uint8_t active_zone;
uint8_t active_mode;
uint8_t active_speed;
i2c_smbus_interface* bus;
polychrome_dev_id dev;
};

View file

@ -0,0 +1,180 @@
/*-----------------------------------------*\
| ASRockPolychromeV1SMBusController.cpp |
| |
| Driver for for ASRock ASR LED and |
| Polychrome RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/14/2019 |
\*-----------------------------------------*/
#include "ASRockPolychromeV1SMBusController.h"
#include <cstring>
#include "dependencies/dmiinfo.h"
#include "LogManager.h"
#define ASROCK_ZONE_LED_COUNT_MESSAGE_EN "[%s] Zone %i LED count: %02d"
using namespace std::chrono_literals;
ASRockPolychromeV1SMBusController::ASRockPolychromeV1SMBusController(i2c_smbus_interface* bus, polychrome_dev_id dev)
{
this->bus = bus;
this->dev = dev;
DMIInfo dmi;
device_name = "ASRock " + dmi.getMainboard();
ReadLEDConfiguration();
}
ASRockPolychromeV1SMBusController::~ASRockPolychromeV1SMBusController()
{
}
std::string ASRockPolychromeV1SMBusController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
}
std::string ASRockPolychromeV1SMBusController::GetDeviceName()
{
return(device_name);
}
std::string ASRockPolychromeV1SMBusController::GetFirmwareVersion()
{
uint8_t major_version = fw_version >> 8;
uint8_t minor_version = fw_version & 0xFF;
return(std::to_string(major_version) + "." + std::to_string(minor_version));
}
void ASRockPolychromeV1SMBusController::ReadLEDConfiguration()
{
/*---------------------------------------------------------------------------------*\
| The LED configuration register holds 6 bytes, so the first read should return 6 |
| If not, set all zone sizes to zero |
\*---------------------------------------------------------------------------------*/
LOG_DEBUG("[%s] Reading LED config from controller", device_name.c_str());
uint8_t asrock_zone_count[I2C_SMBUS_BLOCK_MAX] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
if (bus->i2c_smbus_read_block_data(dev, POLYCHROME_V1_REG_LED_CONFIG, asrock_zone_count) == 0x06)
{
zone_led_count[POLYCHROME_V1_ZONE_1] = asrock_zone_count[0];
zone_led_count[POLYCHROME_V1_ZONE_2] = asrock_zone_count[1];
zone_led_count[POLYCHROME_V1_ZONE_3] = asrock_zone_count[2];
zone_led_count[POLYCHROME_V1_ZONE_4] = asrock_zone_count[3];
zone_led_count[POLYCHROME_V1_ZONE_5] = asrock_zone_count[4];
zone_led_count[POLYCHROME_V1_ZONE_ADDRESSABLE] = asrock_zone_count[5];
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V1_ZONE_1, zone_led_count[POLYCHROME_V1_ZONE_1]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V1_ZONE_2, zone_led_count[POLYCHROME_V1_ZONE_2]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V1_ZONE_3, zone_led_count[POLYCHROME_V1_ZONE_3]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V1_ZONE_4, zone_led_count[POLYCHROME_V1_ZONE_4]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V1_ZONE_5, zone_led_count[POLYCHROME_V1_ZONE_5]);
LOG_DEBUG("[%s] Addressable Zone LED count: %02d", device_name.c_str(), zone_led_count[POLYCHROME_V1_ZONE_ADDRESSABLE]);
}
else
{
LOG_WARNING("[%s] LED config read failed", device_name.c_str());
memset(zone_led_count, 0, sizeof(zone_led_count));
}
}
uint8_t ASRockPolychromeV1SMBusController::GetMode()
{
return(active_mode);
}
void ASRockPolychromeV1SMBusController::SetColorsAndSpeed(uint8_t led, uint8_t red, uint8_t green, uint8_t blue)
{
uint8_t color_speed_pkt[4] = { red, green, blue, active_speed };
uint8_t select_led_pkt[1] = { led };
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
if(active_mode != POLYCHROME_V1_MODE_OFF)
{
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V1_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
}
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes take 4 bytes in R/G/B/S order |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_BREATHING:
case POLYCHROME_V1_MODE_STROBE:
case POLYCHROME_V1_MODE_SPECTRUM_CYCLE:
case POLYCHROME_V1_MODE_SPRING:
case POLYCHROME_V1_MODE_METEOR:
case POLYCHROME_V1_MODE_STACK:
case POLYCHROME_V1_MODE_CRAM:
case POLYCHROME_V1_MODE_SCAN:
case POLYCHROME_V1_MODE_NEON:
case POLYCHROME_V1_MODE_WATER:
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 3 bytes in R/G/B order |
\*-----------------------------------------------------*/
default:
case POLYCHROME_V1_MODE_STATIC:
case POLYCHROME_V1_MODE_MUSIC:
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
break;
/*-----------------------------------------------------*\
| These modes take 1 byte - speed |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_RANDOM:
case POLYCHROME_V1_MODE_WAVE:
case POLYCHROME_V1_MODE_RAINBOW:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &active_speed);
break;
/*-----------------------------------------------------*\
| These modes take no bytes |
\*-----------------------------------------------------*/
case POLYCHROME_V1_MODE_OFF:
break;
}
std::this_thread::sleep_for(1ms);
}
void ASRockPolychromeV1SMBusController::SetMode(uint8_t zone,uint8_t mode, uint8_t speed)
{
uint8_t led_count_pkt[1] = { 0x00 };
active_zone = zone;
active_mode = mode;
active_speed = speed;
/*-----------------------------------------------------*\
| Make sure set all register is set to 0 |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V1_REG_SET_ALL, 1, led_count_pkt);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Set the zone we are working on |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V1_REG_LED_SELECT, 1, &active_zone);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Write the mode |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V1_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
}

View file

@ -0,0 +1,147 @@
/*-----------------------------------------*\
| ASRockPolychromeV1SMBusController.h |
| |
| Definitions and types for ASRock |
| ASR LED and Polychrome RGB lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/13/2019 |
\*-----------------------------------------*/
#include "i2c_smbus.h"
#include <string>
#pragma once
typedef uint8_t polychrome_dev_id;
#define ASROCK_V1_CONTROLLER_NAME "ASRock Polychrome v1 SMBus Controller"
enum
{
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome v1 Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
POLYCHROME_V1_REG_MODE = 0x30, /* Mode selection register */
POLYCHROME_V1_REG_LED_SELECT = 0x31, /* LED selection register */
POLYCHROME_V1_REG_SET_ALL = 0x32, /* Set All register 0x1 = set all */
POLYCHROME_V1_REG_LED_CONFIG = 0x33, /* LED configuration register */
POLYCHROME_V1_REG_ARGB_GRB = 0x35, /* ARGB bistream reversing register */
};
enum
{
POLYCHROME_V1_ZONE_1 = 0x00, /* RGB LED 1 Header */
POLYCHROME_V1_ZONE_2 = 0x01, /* RGB LED 2 Header */
POLYCHROME_V1_ZONE_3 = 0x02, /* Audio/PCH Zone LEDs */
POLYCHROME_V1_ZONE_4 = 0x03, /* Audio/PCH Zone LEDs */
POLYCHROME_V1_ZONE_5 = 0x04, /* IO Cover Zone LEDs */
POLYCHROME_V1_ZONE_ADDRESSABLE = 0x05, /* Addressable LED header */
POLYCHROME_V1_ZONE_COUNT = 0x06, /* Total number of zones */
POLYCHROME_V1_ZONE_ADDRESSABLE_MAX = 0x64, /* Maxinum number of ARGB LEDs */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome V1 |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_V1_NUM_MODES 16 /* Number of Polychrome V1 modes */
enum
{
POLYCHROME_V1_MODE_OFF = 0x10, /* OFF mode */
POLYCHROME_V1_MODE_STATIC = 0x11, /* Static color mode */
POLYCHROME_V1_MODE_BREATHING = 0x12, /* Breating effect mode */
POLYCHROME_V1_MODE_STROBE = 0x13, /* Strobe effect mode */
POLYCHROME_V1_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
POLYCHROME_V1_MODE_RANDOM = 0x15, /* Random effect mode */
POLYCHROME_V1_MODE_MUSIC = 0x17, /* Music effect mode */
POLYCHROME_V1_MODE_WAVE = 0x18, /* Wave effect mode */
/*------------------------------------------------------------------------------------------*\
| Modes only available on ARGB headers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_MODE_SPRING = 0x19, /* Spring effect mode */
POLYCHROME_V1_MODE_METEOR = 0x1A, /* Meteor effect mode */
POLYCHROME_V1_MODE_STACK = 0x1B, /* Stack effect mode */
POLYCHROME_V1_MODE_CRAM = 0x1C, /* Cram effect mode */
POLYCHROME_V1_MODE_SCAN = 0x1D, /* Scan effect mode */
POLYCHROME_V1_MODE_NEON = 0x1E, /* Neon effect mode */
POLYCHROME_V1_MODE_WATER = 0x1F, /* Water effect mode */
POLYCHROME_V1_MODE_RAINBOW = 0x20, /* Rainbow chase effect mode */
};
enum
{
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_BREATHING |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_BREATHING = 0x0A, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_BREATHING = 0x02, /* Default speed */
POLYCHROME_V1_SPEED_MAX_BREATHING = 0x02, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_STROBE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_STROBE = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_STROBE = 0x14, /* Default speed */
POLYCHROME_V1_SPEED_MAX_STROBE = 0x05, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_SPECTRUM_CYCLE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_CYCLE = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_CYCLE = 0x14, /* Default speed */
POLYCHROME_V1_SPEED_MAX_CYCLE = 0x0A, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_RANDOM |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_RANDOM = 0xA0, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_RANDOM = 0x28, /* Default speed */
POLYCHROME_V1_SPEED_MAX_RANDOM = 0x05, /* Fastest speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_WAVE |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_WAVE = 0x06, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_WAVE = 0x02, /* Default speed */
POLYCHROME_V1_SPEED_MAX_WAVE = 0x01, /* Fastest speed */
POLYCHROME_V1_SPEED_DEFAULT_SPRING = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_METEOR = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_STACK = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_CRAM = 0x04, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_SCAN = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_NEON = 0x20, /* Default speed */
POLYCHROME_V1_SPEED_DEFAULT_WATER = 0x0A, /* Default speed */
/*------------------------------------------------------------------------------------------*\
| POLYCHROME_V1_MODE_RAINBOW |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V1_SPEED_MIN_RAINBOW = 0x12, /* Slowest speed */
POLYCHROME_V1_SPEED_DEFAULT_RAINBOW = 0x0A, /* Default speed */
POLYCHROME_V1_SPEED_MAX_RAINBOW = 0x01, /* Fastest speed */
POLYCHROME_V1_SPEED_MIN_ARGB = 0x20, /* Slowest speed */
POLYCHROME_V1_SPEED_MAX_ARGB = 0x02, /* Fastest speed */
};
class ASRockPolychromeV1SMBusController
{
public:
ASRockPolychromeV1SMBusController(i2c_smbus_interface* bus, polychrome_dev_id dev);
~ASRockPolychromeV1SMBusController();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetFirmwareVersion();
uint8_t GetMode();
void SetColorsAndSpeed(uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
void SetMode(uint8_t zone, uint8_t mode, uint8_t speed);
uint8_t zone_led_count[6];
uint16_t fw_version;
private:
std::string device_name;
uint8_t active_zone;
uint8_t active_mode;
uint8_t active_speed;
i2c_smbus_interface* bus;
polychrome_dev_id dev;
void ReadLEDConfiguration();
};

View file

@ -0,0 +1,156 @@
/*-----------------------------------------*\
| ASRockPolychromeV2SMBusController.cpp |
| |
| Driver for for ASRock ASR LED and |
| Polychrome RGB lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/14/2019 |
\*-----------------------------------------*/
#include "ASRockPolychromeV2SMBusController.h"
#include <cstring>
#include "dependencies/dmiinfo.h"
#include "LogManager.h"
#define ASROCK_ZONE_LED_COUNT_MESSAGE_EN "[%s] Zone %i LED count: %02d"
using namespace std::chrono_literals;
ASRockPolychromeV2SMBusController::ASRockPolychromeV2SMBusController(i2c_smbus_interface* bus, polychrome_dev_id dev)
{
this->bus = bus;
this->dev = dev;
DMIInfo dmi;
device_name = "ASRock " + dmi.getMainboard();
ReadLEDConfiguration();
}
ASRockPolychromeV2SMBusController::~ASRockPolychromeV2SMBusController()
{
}
std::string ASRockPolychromeV2SMBusController::GetDeviceLocation()
{
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
return_string.append(addr);
return("I2C: " + return_string);
}
std::string ASRockPolychromeV2SMBusController::GetDeviceName()
{
return(device_name);
}
std::string ASRockPolychromeV2SMBusController::GetFirmwareVersion()
{
uint8_t major_version = fw_version >> 8;
uint8_t minor_version = fw_version & 0xFF;
return(std::to_string(major_version) + "." + std::to_string(minor_version));
}
void ASRockPolychromeV2SMBusController::ReadLEDConfiguration()
{
/*---------------------------------------------------------------------------------*\
| The LED configuration register holds 6 bytes, so the first read should return 6 |
| If not, set all zone sizes to zero |
\*---------------------------------------------------------------------------------*/
LOG_DEBUG("[%s] Reading LED config from controller", device_name.c_str());
uint8_t asrock_zone_count[I2C_SMBUS_BLOCK_MAX] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
if (bus->i2c_smbus_read_block_data(dev, POLYCHROME_V2_REG_LED_CONFIG, asrock_zone_count) == 0x06)
{
zone_led_count[POLYCHROME_V2_ZONE_1] = asrock_zone_count[0];
zone_led_count[POLYCHROME_V2_ZONE_2] = asrock_zone_count[1];
zone_led_count[POLYCHROME_V2_ZONE_3] = asrock_zone_count[2];
zone_led_count[POLYCHROME_V2_ZONE_4] = asrock_zone_count[3];
zone_led_count[POLYCHROME_V2_ZONE_5] = asrock_zone_count[4];
zone_led_count[POLYCHROME_V2_ZONE_ADDRESSABLE] = asrock_zone_count[5];
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V2_ZONE_1, zone_led_count[POLYCHROME_V2_ZONE_1]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V2_ZONE_2, zone_led_count[POLYCHROME_V2_ZONE_2]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V2_ZONE_3, zone_led_count[POLYCHROME_V2_ZONE_3]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V2_ZONE_4, zone_led_count[POLYCHROME_V2_ZONE_4]);
LOG_DEBUG(ASROCK_ZONE_LED_COUNT_MESSAGE_EN, device_name.c_str(), POLYCHROME_V2_ZONE_5, zone_led_count[POLYCHROME_V2_ZONE_5]);
LOG_DEBUG("[%s] Addressable Zone LED count: %02d", device_name.c_str(), zone_led_count[POLYCHROME_V2_ZONE_ADDRESSABLE]);
}
else
{
LOG_WARNING("[%s] LED config read failed", device_name.c_str());
memset(zone_led_count, 0, sizeof(zone_led_count));
}
}
uint8_t ASRockPolychromeV2SMBusController::GetMode()
{
return(active_mode);
}
void ASRockPolychromeV2SMBusController::SetColorsAndSpeed(uint8_t led, uint8_t red, uint8_t green, uint8_t blue)
{
uint8_t color_speed_pkt[4] = { red, green, blue, active_speed };
uint8_t select_led_pkt[1] = { led };
/*-----------------------------------------------------*\
| Select LED |
\*-----------------------------------------------------*/
switch(active_mode)
{
case POLYCHROME_V2_MODE_OFF:
case POLYCHROME_V2_MODE_RAINBOW:
case POLYCHROME_V2_MODE_SPECTRUM_CYCLE:
break;
default:
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_LED_SELECT, 1, select_led_pkt);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Polychrome firmware always writes color to fixed reg |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_COLOR, 3, color_speed_pkt);
std::this_thread::sleep_for(1ms);
break;
}
}
void ASRockPolychromeV2SMBusController::SetMode(uint8_t zone,uint8_t mode, uint8_t speed)
{
uint8_t led_count_pkt[1] = { 0x00 };
active_zone = zone;
active_mode = mode;
active_speed = speed;
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_MODE, 1, &active_mode);
std::this_thread::sleep_for(1ms);
/*-----------------------------------------------------*\
| Select a single LED |
\*-----------------------------------------------------*/
bus->i2c_smbus_write_block_data(dev, POLYCHROME_V2_REG_LED_COUNT, 0, led_count_pkt);
std::this_thread::sleep_for(1ms);
switch(active_mode)
{
/*-----------------------------------------------------*\
| These modes don't take a speed |
\*-----------------------------------------------------*/
case POLYCHROME_V2_MODE_OFF:
case POLYCHROME_V2_MODE_STATIC:
break;
/*-----------------------------------------------------*\
| All other modes, write speed to active mode register |
\*-----------------------------------------------------*/
default:
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
std::this_thread::sleep_for(1ms);
break;
}
}

View file

@ -0,0 +1,145 @@
/*-----------------------------------------*\
| ASRockPolychromeSMBusController.h |
| |
| Definitions and types for ASRock |
| ASR LED and Polychrome RGB lighting |
| controller |
| |
| Adam Honse (CalcProgrammer1) 12/13/2019 |
\*-----------------------------------------*/
#include "i2c_smbus.h"
#include <string>
#pragma once
typedef uint8_t polychrome_dev_id;
#define ASROCK_V2_CONTROLLER_NAME "ASRock Polychrome v2 SMBus Controller"
enum
{
/*------------------------------------------------------------------------------------------*\
| ASRock Polychrome v2 Registers |
\*------------------------------------------------------------------------------------------*/
POLYCHROME_V2_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
POLYCHROME_V2_REG_MODE = 0x30, /* Mode selection register */
POLYCHROME_V2_REG_LED_SELECT = 0x31, /* LED selection register */
POLYCHROME_V2_REG_LED_COUNT = 0x32, /* Additional LED count register */
POLYCHROME_V2_REG_LED_CONFIG = 0x33, /* LED configuration register */
POLYCHROME_V2_REG_COLOR = 0x34, /* Color register: Red, Green, Blue */
POLYCHROME_V2_REG_ARGB_GRB = 0x35, /* ARGB bistream reversing register */
};
enum
{
POLYCHROME_V2_ZONE_1 = 0x00, /* RGB LED 1 Header */
POLYCHROME_V2_ZONE_2 = 0x01, /* RGB LED 2 Header */
POLYCHROME_V2_ZONE_3 = 0x02, /* Audio/PCH Zone LEDs */
POLYCHROME_V2_ZONE_4 = 0x03, /* Audio/PCH Zone LEDs */
POLYCHROME_V2_ZONE_5 = 0x04, /* IO Cover Zone LEDs */
POLYCHROME_V2_ZONE_ADDRESSABLE = 0x05, /* Addressable LED header */
POLYCHROME_V2_ZONE_COUNT = 0x06, /* Total number of zones */
POLYCHROME_V2_ZONE_ADDRESSABLE_MAX = 0x64, /* Maxinum number of ARGB LEDs */
};
/*----------------------------------------------------------------------------------------------*\
| Definitions for Polychrome V2 |
\*----------------------------------------------------------------------------------------------*/
#define POLYCHROME_V2_NUM_MODES 14 /* Number of Polychrome V2 modes */
enum
{
POLYCHROME_V2_MODE_OFF = 0x10, /* OFF mode */
POLYCHROME_V2_MODE_STATIC = 0x11, /* Static color mode */
POLYCHROME_V2_MODE_BREATHING = 0x12, /* Breating effect mode */
POLYCHROME_V2_MODE_STROBE = 0x13, /* Strobe effect mode */
POLYCHROME_V2_MODE_SPECTRUM_CYCLE = 0x14, /* Spectrum Cycle effect mode */
POLYCHROME_V2_MODE_RANDOM = 0x15, /* Random effect mode */
POLYCHROME_V2_MODE_WAVE = 0x17, /* Wave effect mode */
POLYCHROME_V2_MODE_SPRING = 0x18, /* Spring effect mode */
POLYCHROME_V2_MODE_STACK = 0x19, /* Stack effect mode */
POLYCHROME_V2_MODE_CRAM = 0x1A, /* Cram effect mode */
POLYCHROME_V2_MODE_SCAN = 0x1B, /* Scan effect mode */
POLYCHROME_V2_MODE_NEON = 0x1C, /* Neon effect mode */
POLYCHROME_V2_MODE_WATER = 0x1D, /* Water effect mode */
POLYCHROME_V2_MODE_RAINBOW = 0x1E, /* Rainbow effect mode */
};
enum
{
POLYCHROME_V2_BREATHING_SPEED_MIN = 0x0A, /* Slowest speed */
POLYCHROME_V2_BREATHING_SPEED_DEFAULT = 0x06, /* Default speed */
POLYCHROME_V2_BREATHING_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_STROBE_SPEED_MIN = 0xA0, /* Slowest speed */
POLYCHROME_V2_STROBE_SPEED_DEFAULT = 0x4D, /* Default speed */
POLYCHROME_V2_STROBE_SPEED_MAX = 0x05, /* Fastest speed */
POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MIN = 0xA0, /* Slowest speed */
POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_DEFAULT = 0x50, /* Default speed */
POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MAX = 0x0A, /* Fastest speed */
POLYCHROME_V2_RANDOM_SPEED_MIN = 0xA0, /* Slowest speed */
POLYCHROME_V2_RANDOM_SPEED_DEFAULT = 0x4D, /* Default speed */
POLYCHROME_V2_RANDOM_SPEED_MAX = 0x05, /* Fastest speed */
POLYCHROME_V2_WAVE_SPEED_MIN = 0x06, /* Slowest speed */
POLYCHROME_V2_WAVE_SPEED_DEFAULT = 0x03, /* Default speed */
POLYCHROME_V2_WAVE_SPEED_MAX = 0x01, /* Fastest speed */
POLYCHROME_V2_SPRING_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_SPRING_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_SPRING_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_STACK_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_STACK_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_STACK_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_CRAM_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_CRAM_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_CRAM_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_SCAN_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_SCAN_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_SCAN_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_NEON_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_NEON_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_NEON_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_WATER_SPEED_MIN = 0x20, /* Slowest speed */
POLYCHROME_V2_WATER_SPEED_DEFAULT = 0x11, /* Default speed */
POLYCHROME_V2_WATER_SPEED_MAX = 0x02, /* Fastest speed */
POLYCHROME_V2_RAINBOW_SPEED_MIN = 0x12, /* Slowest speed */
POLYCHROME_V2_RAINBOW_SPEED_DEFAULT = 0x08, /* Default speed */
POLYCHROME_V2_RAINBOW_SPEED_MAX = 0x02, /* Fastest speed */
};
class ASRockPolychromeV2SMBusController
{
public:
ASRockPolychromeV2SMBusController(i2c_smbus_interface* bus, polychrome_dev_id dev);
~ASRockPolychromeV2SMBusController();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetFirmwareVersion();
uint8_t GetMode();
void SetColorsAndSpeed(uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
void SetMode(uint8_t zone, uint8_t mode, uint8_t speed);
uint8_t zone_led_count[6];
uint16_t fw_version;
private:
std::string device_name;
uint8_t active_zone;
uint8_t active_mode;
uint8_t active_speed;
i2c_smbus_interface* bus;
polychrome_dev_id dev;
void ReadLEDConfiguration();
};

View file

@ -0,0 +1,168 @@
#include "Detector.h"
#include "ASRockASRRGBSMBusController.h"
#include "ASRockPolychromeV1SMBusController.h"
#include "ASRockPolychromeV2SMBusController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_ASRockASRRGBSMBus.h"
#include "RGBController_ASRockPolychromeV1SMBus.h"
#include "RGBController_ASRockPolychromeV2SMBus.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
/*******************************************************************************************\
* *
* TestForPolychromeSMBusController *
* *
* Tests the given address to see if an ASRock RGB controller exists there. *
* First does a quick write to test for a response *
* *
\*******************************************************************************************/
#define ASROCK_DETECTOR_NAME "ASRock SMBus Detectector"
#define VENDOR_NAME "ASRock"
#define SMBUS_ADDRESS 0x6A
enum
{
ASROCK_TYPE_UNKNOWN = 0x00, /* Unknown Type or Not ASRock Device */
ASROCK_TYPE_ASRLED = 0x01, /* ASRock Firmware 1.x - ASR LED */
ASROCK_TYPE_POLYCHROME_V1 = 0x02, /* ASRock Firmware 2.x - Polychrome V1 */
ASROCK_TYPE_POLYCHROME_V2 = 0x03, /* ASRock Firmware 3.x - Polychrome V2 */
ASROCK_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
};
union u16_to_u8
{
uint16_t u16;
struct
{
uint8_t lsb;
uint8_t msb;
};
};
bool TestForPolychromeSMBusController(i2c_smbus_interface* bus, uint8_t address)
{
bool pass = false;
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
}
return(pass);
} /* TestForPolychromeController() */
uint16_t GetFirmwareVersion(i2c_smbus_interface* bus, uint8_t address)
{
// The firmware register holds two bytes, so the first read should return 2
// If not, report invalid firmware revision
LOG_DEBUG("[%s] Reading back device firmware version", ASROCK_DETECTOR_NAME);
u16_to_u8 asrock_version_u16;
// Version response array needs to be 32 bytes to prevent non ASRock board from stack smashing
uint8_t asrock_version[I2C_SMBUS_BLOCK_MAX] = { 0x00, 0x00 };
if (bus->i2c_smbus_read_block_data(address, ASROCK_REG_FIRMWARE_VER, asrock_version) == 0x02)
{
asrock_version_u16.msb = asrock_version[0];
asrock_version_u16.lsb = asrock_version[1];
LOG_DEBUG("[%s] Device firmware version: v%02d.%02d", ASROCK_DETECTOR_NAME, asrock_version_u16.msb, asrock_version_u16.lsb);
return(asrock_version_u16.u16);
}
else
{
LOG_WARNING("[%s] Firmware readback failed; Returning Unknown Version", ASROCK_DETECTOR_NAME);
return(ASROCK_TYPE_UNKNOWN);
}
}
/******************************************************************************************\
* *
* DetectPolychromeControllers *
* *
* Detect ASRock Polychrome RGB SMBus controllers on the enumerated I2C busses at *
* address 0x6A. *
* *
* bus - pointer to i2c_smbus_interface where Polychrome device is connected *
* dev - I2C address of Polychrome device *
* *
\******************************************************************************************/
void DetectASRockSMBusControllers(std::vector<i2c_smbus_interface*>& busses)
{
for(unsigned int bus = 0; bus < busses.size(); bus++)
{
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
if(busses[bus]->pci_subsystem_vendor == ASROCK_SUB_VEN)
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_MESSAGE_EN, ASROCK_DETECTOR_NAME, bus, VENDOR_NAME, SMBUS_ADDRESS);
// Check for Polychrome controller at 0x6A
if(TestForPolychromeSMBusController(busses[bus], SMBUS_ADDRESS))
{
LOG_DEBUG("[%s] Detected a device at address 0x%02X, testing for a known controller", ASROCK_DETECTOR_NAME, SMBUS_ADDRESS);
u16_to_u8 version;
version.u16 = GetFirmwareVersion(busses[bus], SMBUS_ADDRESS);
switch (version.msb)
{
case ASROCK_TYPE_ASRLED:
{
LOG_DEBUG("[%s] Found a ASR RGB LED Controller", ASROCK_DETECTOR_NAME);
ASRockASRRGBSMBusController* controller = new ASRockASRRGBSMBusController(busses[bus], SMBUS_ADDRESS);
controller-> fw_version = version.u16;
RGBController_ASRockASRRGBSMBus* rgb_controller = new RGBController_ASRockASRRGBSMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
break;
case ASROCK_TYPE_POLYCHROME_V1:
{
LOG_DEBUG("[%s] Found a Polychrome v1 Controller", ASROCK_DETECTOR_NAME);
ASRockPolychromeV1SMBusController* controller = new ASRockPolychromeV1SMBusController(busses[bus], SMBUS_ADDRESS);
controller-> fw_version = version.u16;
RGBController_ASRockPolychromeV1SMBus* rgb_controller = new RGBController_ASRockPolychromeV1SMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
break;
case ASROCK_TYPE_POLYCHROME_V2:
{
LOG_DEBUG("[%s] Found a Polychrome v2 Controller", ASROCK_DETECTOR_NAME);
ASRockPolychromeV2SMBusController* controller = new ASRockPolychromeV2SMBusController(busses[bus], SMBUS_ADDRESS);
controller-> fw_version = version.u16;
RGBController_ASRockPolychromeV2SMBus* rgb_controller = new RGBController_ASRockPolychromeV2SMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
break;
default:
LOG_DEBUG("[%s] Not a Polychrome device or unknown type", ASROCK_DETECTOR_NAME);
break;
}
}
else
{
LOG_DEBUG("[%s] Bus %02d has no response at 0x%02X", ASROCK_DETECTOR_NAME, bus, SMBUS_ADDRESS);
}
}
else
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_FAILURE_EN, ASROCK_DETECTOR_NAME, bus, VENDOR_NAME);
}
}
}
} /* DetectSMBusPolychromeControllers() */
REGISTER_I2C_DETECTOR("ASRock Motherboard SMBus Controllers", DetectASRockSMBusControllers);

View file

@ -0,0 +1,210 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeSMBus.cpp |
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#include "RGBController_ASRockASRRGBSMBus.h"
#define ASROCK_MAX_ZONES 4
#define ASROCK_MAX_LEDS 22
/**------------------------------------------------------------------*\
@name ASRock ASR RGB SMBus
@category Motherboard
@type SMBus
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectASRockSMBusControllers
@comment ASRock ASR RGB LED controllers will save with each update.
Per ARGB LED support is not possible with these devices.
\*-------------------------------------------------------------------*/
RGBController_ASRockASRRGBSMBus::RGBController_ASRockASRRGBSMBus(ASRockASRRGBSMBusController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetDeviceName();
vendor = "ASRock";
version = controller->GetFirmwareVersion();
type = DEVICE_TYPE_MOTHERBOARD;
description = "ASRock ASR RGB LED Device";
location = controller->GetDeviceLocation();
mode Off;
Off.name = "Off";
Off.value = ASRLED_MODE_OFF;
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = ASRLED_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ASRLED_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Breathing.speed_min = ASRLED_SPEED_MIN;
Breathing.speed_max = ASRLED_SPEED_MAX;
Breathing.speed = ASRLED_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = ASRLED_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Strobe.speed_min = ASRLED_SPEED_MIN;
Strobe.speed_max = ASRLED_SPEED_MAX;
Strobe.speed = ASRLED_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = ASRLED_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
SpectrumCycle.speed_min = ASRLED_SPEED_MIN;
SpectrumCycle.speed_max = ASRLED_SPEED_MAX;
SpectrumCycle.speed = ASRLED_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = ASRLED_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Random.speed_min = ASRLED_SPEED_MIN;
Random.speed_max = ASRLED_SPEED_MAX;
Random.speed = ASRLED_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Music.name = "Music";
Music.value = ASRLED_MODE_MUSIC;
Music.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Music.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Music);
mode Wave;
Wave.name = "Wave";
Wave.value = ASRLED_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Wave.speed_min = ASRLED_SPEED_MIN;
Wave.speed_max = ASRLED_SPEED_MAX;
Wave.speed = ASRLED_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
SetupZones();
}
RGBController_ASRockASRRGBSMBus::~RGBController_ASRockASRRGBSMBus()
{
delete controller;
}
void RGBController_ASRockASRRGBSMBus::SetupZones()
{
/*---------------------------------------------------------*\
| ASR LED motherboards only have a single zone/LED |
\*---------------------------------------------------------*/
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set single zone name to "Motherboard" |
\*---------------------------------------------------------*/
new_zone->name = "Motherboard";
new_zone->type = ZONE_TYPE_SINGLE;
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
led* new_led = new led();
/*---------------------------------------------------------*\
| Set single LED name to "Motherboard" |
\*---------------------------------------------------------*/
new_led->name = "Motherboard";
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
SetupColors();
}
void RGBController_ASRockASRRGBSMBus::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_ASRockASRRGBSMBus::DeviceUpdateLEDs()
{
for (std::size_t led = 0; led < colors.size(); led++)
{
UpdateSingleLED(led);
}
}
void RGBController_ASRockASRRGBSMBus::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_ASRockASRRGBSMBus::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
/*---------------------------------------------------------*\
| If the LED value is non-zero, this LED overrides the LED |
| index |
\*---------------------------------------------------------*/
if(leds[led].value != 0)
{
led = leds[led].value;
}
controller->SetColorsAndSpeed(led, red, grn, blu);
}
void RGBController_ASRockASRRGBSMBus::SetCustomMode()
{
active_mode = 1;
}
void RGBController_ASRockASRRGBSMBus::DeviceUpdateMode()
{
controller->SetMode(0, modes[active_mode].value, modes[active_mode].speed);
DeviceUpdateLEDs();
}

View file

@ -10,13 +10,13 @@
#pragma once
#include "RGBController.h"
#include "ASRockPolychromeSMBusController.h"
#include "ASRockASRRGBSMBusController.h"
class RGBController_Polychrome : public RGBController
class RGBController_ASRockASRRGBSMBus : public RGBController
{
public:
RGBController_Polychrome(PolychromeController* controller_ptr);
~RGBController_Polychrome();
RGBController_ASRockASRRGBSMBus(ASRockASRRGBSMBusController* controller_ptr);
~RGBController_ASRockASRRGBSMBus();
void SetupZones();
@ -30,5 +30,5 @@ public:
void DeviceUpdateMode();
private:
PolychromeController* controller;
ASRockASRRGBSMBusController* controller;
};

View file

@ -0,0 +1,327 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeSMBus.cpp |
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#include "RGBController_ASRockPolychromeV1SMBus.h"
static const char* polychrome_v1_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"PCH",
"IO Cover",
"Audio",
"Addressable Header"
};
/**------------------------------------------------------------------*\
@name ASRock Polychrome v1 SMBus
@category Motherboard
@type SMBus
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectASRockSMBusControllers
@comment ASRock Polychrome v1 controllers will save with each update.
Per ARGB LED support is not possible with these devices.
\*-------------------------------------------------------------------*/
RGBController_ASRockPolychromeV1SMBus::RGBController_ASRockPolychromeV1SMBus(ASRockPolychromeV1SMBusController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetDeviceName();
vendor = "ASRock";
version = controller->GetFirmwareVersion();
type = DEVICE_TYPE_MOTHERBOARD;
description = "ASRock Polychrome v1 Device";
location = controller->GetDeviceLocation();
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_V1_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_V1_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_V1_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = POLYCHROME_V1_SPEED_MIN_BREATHING;
Breathing.speed_max = POLYCHROME_V1_SPEED_MAX_BREATHING;
Breathing.speed = POLYCHROME_V1_SPEED_DEFAULT_BREATHING;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_V1_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Strobe.speed_min = POLYCHROME_V1_SPEED_MIN_STROBE;
Strobe.speed_max = POLYCHROME_V1_SPEED_MAX_STROBE;
Strobe.speed = POLYCHROME_V1_SPEED_DEFAULT_STROBE;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_V1_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = POLYCHROME_V1_SPEED_MIN_CYCLE;
SpectrumCycle.speed_max = POLYCHROME_V1_SPEED_MAX_CYCLE;
SpectrumCycle.speed = POLYCHROME_V1_SPEED_DEFAULT_CYCLE;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_V1_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED;
Random.speed_min = POLYCHROME_V1_SPEED_MIN_RANDOM;
Random.speed_max = POLYCHROME_V1_SPEED_MAX_RANDOM;
Random.speed = POLYCHROME_V1_SPEED_DEFAULT_RANDOM;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Music;
Music.name = "Music";
Music.value = POLYCHROME_V1_MODE_MUSIC;
Music.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Music.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Music);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_V1_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED;
Wave.speed_min = POLYCHROME_V1_SPEED_MIN_WAVE;
Wave.speed_max = POLYCHROME_V1_SPEED_MAX_WAVE;
Wave.speed = POLYCHROME_V1_SPEED_DEFAULT_WAVE;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
/*---------------------------------------------------------------------*\
| Comment out until per zone modes are working. These are only for ARGB |
\*---------------------------------------------------------------------*/
/*
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_V1_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED;
Spring.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Spring.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Spring.speed = POLYCHROME_V1_SPEED_DEFAULT_SPRING;
Spring.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_V1_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED;
Stack.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Stack.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Stack.speed = POLYCHROME_V1_SPEED_DEFAULT_STACK;
Stack.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_V1_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED;
Cram.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Cram.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Cram.speed = POLYCHROME_V1_SPEED_DEFAULT_CRAM;
Cram.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_V1_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED;
Scan.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Scan.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Scan.speed = POLYCHROME_V1_SPEED_DEFAULT_SCAN;
Scan.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_V1_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED;
Neon.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Neon.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Neon.speed = POLYCHROME_V1_SPEED_DEFAULT_NEON;
Neon.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_V1_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED;
Water.speed_min = POLYCHROME_V1_SPEED_MIN_ARGB;
Water.speed_max = POLYCHROME_V1_SPEED_MAX_ARGB;
Water.speed = POLYCHROME_V1_SPEED_DEFAULT_WATER;
Water.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_V1_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = POLYCHROME_V1_SPEED_MIN_RAINBOW;
Rainbow.speed_max = POLYCHROME_V1_SPEED_MAX_RAINBOW;
Rainbow.speed = POLYCHROME_V1_SPEED_DEFAULT_RAINBOW;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
*/
SetupZones();
}
RGBController_ASRockPolychromeV1SMBus::~RGBController_ASRockPolychromeV1SMBus()
{
delete controller;
}
void RGBController_ASRockPolychromeV1SMBus::SetupZones()
{
/*---------------------------------------------------------*\
| Polychrome motherboards should set up zones based on LED |
| configuration register read from device |
\*---------------------------------------------------------*/
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(uint8_t zone_idx = 0; zone_idx < POLYCHROME_V1_ZONE_COUNT; zone_idx++)
{
if(controller->zone_led_count[zone_idx] > 0)
{
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set zone name to channel name |
\*---------------------------------------------------------*/
new_zone->name = polychrome_v1_zone_names[zone_idx];
new_zone->leds_min = 1;
new_zone->leds_max = 1;
//new_zone->leds_count = zone_led_count[zone_idx];
new_zone->leds_count = 1;
new_zone->type = ZONE_TYPE_SINGLE;
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
}
}
uint8_t led_count = 0;
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
for(uint8_t zone_idx = 0; zone_idx < POLYCHROME_V1_ZONE_COUNT; zone_idx++)
{
if(controller->zone_led_count[zone_idx] > 0)
{
for(uint8_t led_idx = 0; led_idx < controller->zone_led_count[zone_idx]; led_idx++)
{
/*---------------------------------------------------------*\
| Each zone only has one LED |
\*---------------------------------------------------------*/
led* new_led = new led();
new_led->name = polychrome_v1_zone_names[zone_idx];
new_led->name.append(" " + std::to_string(led_idx + 1));
new_led->value = 0;
new_led->value = zone_idx;
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
led_count++;
if(zone_idx == POLYCHROME_V1_ZONE_ADDRESSABLE)
{
break;
}
}
}
}
SetupColors();
}
void RGBController_ASRockPolychromeV1SMBus::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_ASRockPolychromeV1SMBus::DeviceUpdateLEDs()
{
for (std::size_t led = 0; led < colors.size(); led++)
{
UpdateSingleLED(led);
}
}
void RGBController_ASRockPolychromeV1SMBus::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_ASRockPolychromeV1SMBus::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
/*---------------------------------------------------------*\
| If the LED value is non-zero, this LED overrides the LED |
| index |
\*---------------------------------------------------------*/
if(leds[led].value != 0)
{
led = leds[led].value;
}
controller->SetColorsAndSpeed(led, red, grn, blu);
}
void RGBController_ASRockPolychromeV1SMBus::SetCustomMode()
{
active_mode = 1;
}
void RGBController_ASRockPolychromeV1SMBus::DeviceUpdateMode()
{
for(uint8_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
controller->SetMode(led_idx, modes[active_mode].value, modes[active_mode].speed);
}
DeviceUpdateLEDs();
}

View file

@ -0,0 +1,34 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeV1SMBus.h |
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "ASRockPolychromeV1SMBusController.h"
class RGBController_ASRockPolychromeV1SMBus : public RGBController
{
public:
RGBController_ASRockPolychromeV1SMBus(ASRockPolychromeV1SMBusController* controller_ptr);
~RGBController_ASRockPolychromeV1SMBus();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
ASRockPolychromeV1SMBusController* controller;
};

View file

@ -0,0 +1,330 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromeV2SMBus.cpp|
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#include "RGBController_ASRockPolychromeV2SMBus.h"
static const char* polychrome_v2_zone_names[] =
{
"RGB LED 1 Header",
"RGB LED 2 Header",
"Audio",
"PCH",
"IO Cover",
"Addressable Header"
};
/**------------------------------------------------------------------*\
@name ASRock Polychrome v2 SMBus
@category Motherboard
@type SMBus
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectASRockSMBusControllers
@comment ASRock Polychrome v2 controllers will save with each update.
Per ARGB LED support is not possible with these devices.
\*-------------------------------------------------------------------*/
RGBController_ASRockPolychromeV2SMBus::RGBController_ASRockPolychromeV2SMBus(ASRockPolychromeV2SMBusController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetDeviceName();
vendor = "ASRock";
version = controller->GetFirmwareVersion();
type = DEVICE_TYPE_MOTHERBOARD;
description = "ASRock Polychrome v2 Device";
location = controller->GetDeviceLocation();
mode Off;
Off.name = "Off";
Off.value = POLYCHROME_V2_MODE_OFF;
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = POLYCHROME_V2_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = POLYCHROME_V2_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Breathing.speed_min = POLYCHROME_V2_BREATHING_SPEED_MIN;
Breathing.speed_max = POLYCHROME_V2_BREATHING_SPEED_MAX;
Breathing.speed = POLYCHROME_V2_BREATHING_SPEED_DEFAULT;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode Strobe;
Strobe.name = "Strobe";
Strobe.value = POLYCHROME_V2_MODE_STROBE;
Strobe.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
Strobe.speed_min = POLYCHROME_V2_STROBE_SPEED_MIN;
Strobe.speed_max = POLYCHROME_V2_STROBE_SPEED_MAX;
Strobe.speed = POLYCHROME_V2_STROBE_SPEED_DEFAULT;
Strobe.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Strobe);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = POLYCHROME_V2_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
SpectrumCycle.speed_min = POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MIN;
SpectrumCycle.speed_max = POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_MAX;
SpectrumCycle.speed = POLYCHROME_V2_SPECTRUM_CYCLE_SPEED_DEFAULT;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Random;
Random.name = "Random";
Random.value = POLYCHROME_V2_MODE_RANDOM;
Random.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Random.speed_min = POLYCHROME_V2_RANDOM_SPEED_MIN;
Random.speed_max = POLYCHROME_V2_RANDOM_SPEED_MAX;
Random.speed = POLYCHROME_V2_RANDOM_SPEED_DEFAULT;
Random.color_mode = MODE_COLORS_NONE;
modes.push_back(Random);
mode Wave;
Wave.name = "Wave";
Wave.value = POLYCHROME_V2_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Wave.speed_min = POLYCHROME_V2_WAVE_SPEED_MIN;
Wave.speed_max = POLYCHROME_V2_WAVE_SPEED_MAX;
Wave.speed = POLYCHROME_V2_WAVE_SPEED_DEFAULT;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
mode Spring;
Spring.name = "Spring";
Spring.value = POLYCHROME_V2_MODE_SPRING;
Spring.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Spring.speed_min = POLYCHROME_V2_SPRING_SPEED_MIN;
Spring.speed_max = POLYCHROME_V2_SPRING_SPEED_MAX;
Spring.speed = POLYCHROME_V2_SPRING_SPEED_DEFAULT;
Spring.color_mode = MODE_COLORS_NONE;
modes.push_back(Spring);
mode Stack;
Stack.name = "Stack";
Stack.value = POLYCHROME_V2_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Stack.speed_min = POLYCHROME_V2_STACK_SPEED_MIN;
Stack.speed_max = POLYCHROME_V2_STACK_SPEED_MAX;
Stack.speed = POLYCHROME_V2_STACK_SPEED_DEFAULT;
Stack.color_mode = MODE_COLORS_NONE;
modes.push_back(Stack);
mode Cram;
Cram.name = "Cram";
Cram.value = POLYCHROME_V2_MODE_CRAM;
Cram.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Cram.speed_min = POLYCHROME_V2_CRAM_SPEED_MIN;
Cram.speed_max = POLYCHROME_V2_CRAM_SPEED_MAX;
Cram.speed = POLYCHROME_V2_CRAM_SPEED_DEFAULT;
Cram.color_mode = MODE_COLORS_NONE;
modes.push_back(Cram);
mode Scan;
Scan.name = "Scan";
Scan.value = POLYCHROME_V2_MODE_SCAN;
Scan.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Scan.speed_min = POLYCHROME_V2_SCAN_SPEED_MIN;
Scan.speed_max = POLYCHROME_V2_SCAN_SPEED_MAX;
Scan.speed = POLYCHROME_V2_SCAN_SPEED_DEFAULT;
Scan.color_mode = MODE_COLORS_NONE;
modes.push_back(Scan);
mode Neon;
Neon.name = "Neon";
Neon.value = POLYCHROME_V2_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Neon.speed_min = POLYCHROME_V2_NEON_SPEED_MIN;
Neon.speed_max = POLYCHROME_V2_NEON_SPEED_MAX;
Neon.speed = POLYCHROME_V2_NEON_SPEED_DEFAULT;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Water;
Water.name = "Water";
Water.value = POLYCHROME_V2_MODE_WATER;
Water.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Water.speed_min = POLYCHROME_V2_WATER_SPEED_MIN;
Water.speed_max = POLYCHROME_V2_WATER_SPEED_MAX;
Water.speed = POLYCHROME_V2_WATER_SPEED_DEFAULT;
Water.color_mode = MODE_COLORS_NONE;
modes.push_back(Water);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = POLYCHROME_V2_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
Rainbow.speed_min = POLYCHROME_V2_RAINBOW_SPEED_MIN;
Rainbow.speed_max = POLYCHROME_V2_RAINBOW_SPEED_MAX;
Rainbow.speed = POLYCHROME_V2_RAINBOW_SPEED_DEFAULT;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
SetupZones();
}
RGBController_ASRockPolychromeV2SMBus::~RGBController_ASRockPolychromeV2SMBus()
{
delete controller;
}
void RGBController_ASRockPolychromeV2SMBus::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < POLYCHROME_V2_ZONE_COUNT; zone_idx++)
{
if(controller->zone_led_count[zone_idx] > 0)
{
zone* new_zone = new zone();
/*---------------------------------------------------------*\
| Set zone name to channel name |
\*---------------------------------------------------------*/
new_zone->name = polychrome_v2_zone_names[zone_idx];
if(zone_idx == POLYCHROME_V2_ZONE_ADDRESSABLE)
{
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
}
else
{
new_zone->leds_min = controller->zone_led_count[zone_idx];
new_zone->leds_max = controller->zone_led_count[zone_idx];
new_zone->leds_count = controller->zone_led_count[zone_idx];
}
if(new_zone->leds_count > 1)
{
new_zone->type = ZONE_TYPE_LINEAR;
}
else
{
new_zone->type = ZONE_TYPE_SINGLE;
}
new_zone->matrix_map = NULL;
/*---------------------------------------------------------*\
| Push new zone to zones vector |
\*---------------------------------------------------------*/
zones.push_back(*new_zone);
}
}
unsigned int led_count = 0;
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < POLYCHROME_V2_ZONE_COUNT; zone_idx++)
{
if(controller->zone_led_count[zone_idx] > 0)
{
for(unsigned int led_idx = 0; led_idx < controller->zone_led_count[zone_idx]; led_idx++)
{
/*---------------------------------------------------------*\
| Each zone only has one LED |
\*---------------------------------------------------------*/
led* new_led = new led();
new_led->name = polychrome_v2_zone_names[zone_idx];
new_led->name.append(" " + std::to_string(led_idx + 1));
new_led->value = 0;
if(zone_idx == POLYCHROME_V2_ZONE_ADDRESSABLE)
{
new_led->value = 0x19;
}
/*---------------------------------------------------------*\
| Push new LED to LEDs vector |
\*---------------------------------------------------------*/
leds.push_back(*new_led);
led_count++;
if(zone_idx == POLYCHROME_V2_ZONE_ADDRESSABLE)
{
break;
}
}
}
}
SetupColors();
}
void RGBController_ASRockPolychromeV2SMBus::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_ASRockPolychromeV2SMBus::DeviceUpdateLEDs()
{
for (std::size_t led = 0; led < colors.size(); led++)
{
UpdateSingleLED(led);
}
}
void RGBController_ASRockPolychromeV2SMBus::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_ASRockPolychromeV2SMBus::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
/*---------------------------------------------------------*\
| If the LED value is non-zero, this LED overrides the LED |
| index |
\*---------------------------------------------------------*/
if(leds[led].value != 0)
{
led = leds[led].value;
}
controller->SetColorsAndSpeed(led, red, grn, blu);
}
void RGBController_ASRockPolychromeV2SMBus::SetCustomMode()
{
active_mode = 1;
}
void RGBController_ASRockPolychromeV2SMBus::DeviceUpdateMode()
{
controller->SetMode(0, modes[active_mode].value, modes[active_mode].speed);
DeviceUpdateLEDs();
}

View file

@ -0,0 +1,34 @@
/*-----------------------------------------*\
| RGBController_ASRockPolychromev2SMBus.h |
| |
| Generic RGB Interface for OpenRGB |
| ASRock ASR LED and Polychrome RGB Driver |
| |
| Adam Honse (CalcProgrammer1) 12/15/2019 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "ASRockPolychromeV2SMBusController.h"
class RGBController_ASRockPolychromeV2SMBus : public RGBController
{
public:
RGBController_ASRockPolychromeV2SMBus(ASRockPolychromeV2SMBusController* controller_ptr);
~RGBController_ASRockPolychromeV2SMBus();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
ASRockPolychromeV2SMBusController* controller;
};

View file

@ -79,8 +79,8 @@ INCLUDEPATH +=
Controllers/AlienwareController/ \
Controllers/AlienwareKeyboardController/ \
Controllers/AMDWraithPrismController/ \
Controllers/ASRockPolychromeSMBusController/ \
Controllers/ASRockPolychromeUSBController/ \
Controllers/ASRockSMBusController/ \
Controllers/AsusAuraCoreController/ \
Controllers/AsusAuraGPUController/ \
Controllers/AsusAuraUSBController/ \
@ -245,10 +245,14 @@ HEADERS +=
Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.h \
Controllers/AnnePro2Controller/AnnePro2Controller.h \
Controllers/AnnePro2Controller/RGBController_AnnePro2.h \
Controllers/ASRockPolychromeSMBusController/ASRockPolychromeSMBusController.h \
Controllers/ASRockPolychromeSMBusController/RGBController_ASRockPolychromeSMBus.h \
Controllers/ASRockPolychromeUSBController/ASRockPolychromeUSBController.h \
Controllers/ASRockPolychromeUSBController/RGBController_ASRockPolychromeUSB.h \
Controllers/ASRockSMBusController/ASRockASRRGBSMBusController.h \
Controllers/ASRockSMBusController/RGBController_ASRockASRRGBSMBus.h \
Controllers/ASRockSMBusController/ASRockPolychromeV1SMBusController.h \
Controllers/ASRockSMBusController/RGBController_ASRockPolychromeV1SMBus.h \
Controllers/ASRockSMBusController/ASRockPolychromeV2SMBusController.h \
Controllers/ASRockSMBusController/RGBController_ASRockPolychromeV2SMBus.h \
Controllers/AsusAuraCoreController/AsusAuraCoreController.h \
Controllers/AsusAuraCoreController/RGBController_AsusAuraCore.h \
Controllers/AsusAuraGPUController/AsusAuraGPUController.h \
@ -699,12 +703,16 @@ SOURCES +=
Controllers/AnnePro2Controller/AnnePro2Controller.cpp \
Controllers/AnnePro2Controller/AnnePro2ControllerDetect.cpp \
Controllers/AnnePro2Controller/RGBController_AnnePro2.cpp \
Controllers/ASRockPolychromeSMBusController/ASRockPolychromeSMBusController.cpp \
Controllers/ASRockPolychromeSMBusController/ASRockPolychromeSMBusControllerDetect.cpp \
Controllers/ASRockPolychromeSMBusController/RGBController_ASRockPolychromeSMBus.cpp \
Controllers/ASRockPolychromeUSBController/ASRockPolychromeUSBController.cpp \
Controllers/ASRockPolychromeUSBController/ASRockPolychromeUSBControllerDetect.cpp \
Controllers/ASRockPolychromeUSBController/RGBController_ASRockPolychromeUSB.cpp \
Controllers/ASRockSMBusController/ASRockASRRGBSMBusController.cpp \
Controllers/ASRockSMBusController/ASRockPolychromeV1SMBusController.cpp \
Controllers/ASRockSMBusController/ASRockPolychromeV2SMBusController.cpp \
Controllers/ASRockSMBusController/ASRockSMBusControllerDetect.cpp \
Controllers/ASRockSMBusController/RGBController_ASRockASRRGBSMBus.cpp \
Controllers/ASRockSMBusController/RGBController_ASRockPolychromeV1SMBus.cpp \
Controllers/ASRockSMBusController/RGBController_ASRockPolychromeV2SMBus.cpp \
Controllers/AsusAuraCoreController/AsusAuraCoreController.cpp \
Controllers/AsusAuraCoreController/AsusAuraCoreControllerDetect.cpp \
Controllers/AsusAuraCoreController/RGBController_AsusAuraCore.cpp \