Add support for Patriot Viper Steel Direct mode

This commit is contained in:
Diego Vargas 2022-05-02 20:51:25 +00:00 committed by Adam Honse
parent 2f720615c2
commit 45755c79ae
6 changed files with 350 additions and 0 deletions

View file

@ -0,0 +1,88 @@
/*-----------------------------------------*\
| PatriotViperSteelController.cpp |
| |
| Definitions and types for Patriot Viper |
| Steel RGB RAM lighting controller |
\*-----------------------------------------*/
#include "PatriotViperSteelController.h"
#include <cstring>
PatriotViperSteelController::PatriotViperSteelController(i2c_smbus_interface *bus, viper_dev_id dev)
{
this->bus = bus;
this->dev = dev;
strcpy(device_name, "Patriot Viper Steel RGB");
led_count = 5;
}
PatriotViperSteelController::~PatriotViperSteelController()
{
}
std::string PatriotViperSteelController::GetDeviceName()
{
return(device_name);
}
std::string PatriotViperSteelController::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);
}
unsigned int PatriotViperSteelController::GetLEDCount()
{
return(led_count);
}
unsigned int PatriotViperSteelController::GetSlotCount()
{
unsigned int slot_count = 0;
for(int slot = 0; slot < 4; slot++)
{
if((slots_valid & (1 << slot)) != 0)
{
slot_count++;
}
}
return(slot_count);
}
unsigned int PatriotViperSteelController::GetMode()
{
return(mode);
}
void PatriotViperSteelController::SetAllColors(unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_STEEL_REG_LED0_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_STEEL_REG_LED1_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_STEEL_REG_LED2_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_STEEL_REG_LED3_DIRECT_COLOR, red, blue, green);
ViperRegisterWrite(VIPER_STEEL_REG_LED4_DIRECT_COLOR, red, blue, green);
}
void PatriotViperSteelController::SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_STEEL_REG_LED0_DIRECT_COLOR + led, red, blue, green);
}
void PatriotViperSteelController::SetLEDColor(unsigned int /*slot*/, unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
ViperRegisterWrite(VIPER_STEEL_REG_LED0_DIRECT_COLOR + led, red, blue, green);
}
void PatriotViperSteelController::ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2)
{
bus->i2c_smbus_write_byte_data(dev, reg, val0);
bus->i2c_smbus_write_byte_data(dev, val2, val1);
}

View file

@ -0,0 +1,52 @@
/*-----------------------------------------*\
| PatriotViperController.h |
| |
| Definitions and types for Patriot Viper |
| RGB RAM lighting controller |
\*-----------------------------------------*/
#include <string>
#include "i2c_smbus.h"
#pragma once
typedef unsigned char viper_dev_id;
typedef unsigned short viper_register;
enum
{
VIPER_STEEL_REG_LED0_DIRECT_COLOR = 0x17, /* LED 0 Color (R, B, G) */
VIPER_STEEL_REG_LED1_DIRECT_COLOR = 0x18, /* LED 1 Color (R, B, G) */
VIPER_STEEL_REG_LED2_DIRECT_COLOR = 0x19, /* LED 2 Color (R, B, G) */
VIPER_STEEL_REG_LED3_DIRECT_COLOR = 0x1a, /* LED 3 Color (R, B, G) */
VIPER_STEEL_REG_LED4_DIRECT_COLOR = 0x1b, /* LED 4 Color (R, B, G) */
};
class PatriotViperSteelController
{
public:
PatriotViperSteelController(i2c_smbus_interface *bus, viper_dev_id dev);
~PatriotViperSteelController();
std::string GetDeviceName();
std::string GetDeviceLocation();
unsigned int GetLEDCount();
unsigned int GetSlotCount();
unsigned int GetMode();
void SetAllColors(unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColor(unsigned int slot, unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void ViperRegisterWrite(viper_register reg, unsigned char val0, unsigned char val1, unsigned char val2);
bool direct;
private:
char device_name[32];
unsigned int led_count;
unsigned char slots_valid;
i2c_smbus_interface *bus;
viper_dev_id dev;
unsigned char mode;
unsigned char speed;
};

View file

@ -0,0 +1,54 @@
#include "Detector.h"
#include "PatriotViperSteelController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_PatriotViperSteel.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
using namespace std::chrono_literals;
#define PATRIOT_CONTROLLER_NAME "Patriot Viper Steel"
/******************************************************************************************\
* *
* DetectPatriotViperSteelControllers *
* *
* Detect Patriot Viper Steel RGB controllers on the enumerated I2C busses. *
* *
* bus - pointer to i2c_smbus_interface where Aura device is connected *
* dev - I2C address of Aura device *
* *
\******************************************************************************************/
void DetectPatriotViperSteelControllers(std::vector<i2c_smbus_interface *> &busses)
{
PatriotViperSteelController *new_viper;
RGBController_PatriotViperSteel *new_controller;
for(unsigned int bus = 0; bus < busses.size(); bus++)
{
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
int res = busses[bus]->i2c_smbus_read_byte_data(0x20, 0x1D);
std::this_thread::sleep_for(1ms);
if((busses[bus]->i2c_smbus_read_byte_data(0x20, 0x1D) == 0x0F)
&&(busses[bus]->i2c_smbus_read_byte_data(0x20, 0x1E) == 0x0C)
&&(busses[bus]->i2c_smbus_read_byte_data(0x20, 0x39) == 0x0F)
&&(busses[bus]->i2c_smbus_read_byte_data(0x20, 0x3A) == 0x0C))
{
new_viper = new PatriotViperSteelController(busses[bus], 0x77);
new_controller = new RGBController_PatriotViperSteel(new_viper);
ResourceManager::get()->RegisterRGBController(new_controller);
}
}
}
} /* DetectPatriotViperSteelControllers() */
REGISTER_I2C_DETECTOR(PATRIOT_CONTROLLER_NAME, DetectPatriotViperSteelControllers);

View file

@ -0,0 +1,118 @@
/*-----------------------------------------*\
| RGBController_PatriotViperSteel.cpp |
| |
| Generic RGB Interface for OpenRGB |
| Patriot Viper Steel RGB interface |
\*-----------------------------------------*/
#include "RGBController_PatriotViperSteel.h"
/**------------------------------------------------------------------*\
@name Patriot Viper Steel
@type I2C
@save :x:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectPatriotViperSteelControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_PatriotViperSteel::RGBController_PatriotViperSteel(PatriotViperSteelController *viper_ptr)
{
controller = viper_ptr;
name = controller->GetDeviceName();
vendor = "Patriot";
type = DEVICE_TYPE_DRAM;
description = "Patriot Viper Steel Device";
location = controller->GetDeviceLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.speed_min = 0;
Direct.speed_max = 0;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.speed = 0;
modes.push_back(Direct);
SetupZones();
}
RGBController_PatriotViperSteel::~RGBController_PatriotViperSteel()
{
delete controller;
}
void RGBController_PatriotViperSteel::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
zone *new_zone = new zone;
new_zone->name = "Patriot Viper Steel RGB";
new_zone->type = ZONE_TYPE_LINEAR;
new_zone->leds_min = 5;
new_zone->leds_max = 5;
new_zone->leds_count = 5;
new_zone->matrix_map = NULL;
zones.push_back(*new_zone);
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
{
led *new_led = new led();
new_led->name = "Patriot Viper RGB LED ";
new_led->name.append(std::to_string(led_idx + 1));
leds.push_back(*new_led);
}
SetupColors();
}
void RGBController_PatriotViperSteel::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_PatriotViperSteel::DeviceUpdateLEDs()
{
for(int led = 0; led < 5; led++)
{
RGBColor color = colors[led];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
controller->SetLEDColor(led, red, grn, blu);
}
}
void RGBController_PatriotViperSteel::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_PatriotViperSteel::UpdateSingleLED(int led)
{
RGBColor color = colors[led];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
controller->SetLEDColor(led, red, grn, blu);
}
void RGBController_PatriotViperSteel::SetCustomMode()
{
}
void RGBController_PatriotViperSteel::DeviceUpdateMode()
{
}

View file

@ -0,0 +1,32 @@
/*---------------------------------------------*\
| RGBController_PatriotViperSteel.h |
| |
| Generic RGB Interface for OpenRGB |
| Patriot Viper Steel RGB interface |
\*---------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "PatriotViperSteelController.h"
class RGBController_PatriotViperSteel : public RGBController
{
public:
RGBController_PatriotViperSteel(PatriotViperSteelController *controller_ptr);
~RGBController_PatriotViperSteel();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
PatriotViperSteelController *controller;
};