Rework TUF WMI Laptop, implementing additional brightness and persistent saving

This commit is contained in:
Nexrem 2023-03-06 22:39:48 +00:00 committed by Adam Honse
parent 36ebdbec2c
commit 2575c6adf4
6 changed files with 310 additions and 98 deletions

View file

@ -0,0 +1,111 @@
#ifdef _WIN32
#include "AsusTUFLaptopController.h"
#include "acpiwmi.h"
AsusTUFLaptopController::AsusTUFLaptopController()
{
/*---------------------------------------------------*\
| Call AsWMI_Open at least once during initialization.|
| Since it's part of the firmware it's guaranteed to |
| always be there. This is necessary to issue further |
| commands. |
\*---------------------------------------------------*/
AsWMI_Open();
}
AsusTUFLaptopController::~AsusTUFLaptopController()
{
}
void AsusTUFLaptopController::SetMode(unsigned char red,
unsigned char green,
unsigned char blue,
unsigned char mode,
unsigned char speed,
bool save)
{
/*--------------------------------------------------------*\
| Use switch case since our speed values are magic numbers |
| Default to Medium/Normal speed |
\*--------------------------------------------------------*/
unsigned char speed_val;
switch(speed)
{
case(1):
speed_val = ASUS_WMI_KEYBOARD_SPEED_SLOW;
break;
default:
case(2):
speed_val = ASUS_WMI_KEYBOARD_SPEED_NORMAL;
break;
case(3):
speed_val = ASUS_WMI_KEYBOARD_SPEED_FAST;
break;
}
/*----------------------------------------------------------*\
| We need to use a magic value to save to firmware in order |
| To persist reboots. Save is normal op with different magic |
\*---------------------------------------------------------*/
unsigned char save_val = ASUS_WMI_KEYBOARD_MAGIC_USE;
if (save)
{
save_val = ASUS_WMI_KEYBOARD_MAGIC_SAVE;
}
// B3 is store value
unsigned int high = save_val | (mode<<8) | (red<<16) | (green<<24);
unsigned int low = blue | (speed_val<<8);
AsWMI_NB_DeviceControl_2arg(ASUS_WMI_DEVID_TUF_RGB_MODE, high, low);
}
unsigned char AsusTUFLaptopController::GetBrightness()
{
int backlight_state = 0;
AsWMI_NB_GetDeviceStatus(ASUS_WMI_DEVID_KBD_BACKLIGHT, &backlight_state);
/*----------------------------------------------*\
| Only lowest two bits indicate brightness level |
\*----------------------------------------------*/
return backlight_state & 0x7F;
}
void AsusTUFLaptopController::SetBrightness(unsigned char brightness)
{
/*-----------------------------------------------------*\
| Only calls in this format persistently set brightness |
\*-----------------------------------------------------*/
int ctrl_param = 0x80 | (brightness & 0x7F);
AsWMI_NB_DeviceControl(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param);
}
/*-----------------------------------------------------------*\
| These settings will not persist a reboot unless save is set |
\*-----------------------------------------------------------*/
void AsusTUFLaptopController::SetPowerState(bool boot,
bool awake,
bool sleep,
bool shutdown,
bool save)
{
unsigned int state = 0xBD;
if (boot) state = state | ASUS_WMI_KEYBOARD_POWER_BOOT;
if (awake) state = state | ASUS_WMI_KEYBOARD_POWER_AWAKE;
if (sleep) state = state | ASUS_WMI_KEYBOARD_POWER_SLEEP;
if (shutdown) state = state | ASUS_WMI_KEYBOARD_POWER_SHUTDOWN;
if (save) state = state | ASUS_WMI_KEYBOARD_POWER_SAVE;
AsWMI_NB_DeviceControl(ASUS_WMI_DEVID_TUF_RGB_STATE, state);
}
#endif // _WIN32

View file

@ -0,0 +1,60 @@
#ifdef _WIN32
#ifndef ASUSTUFLAPTOPCONTROLLER_H
#define ASUSTUFLAPTOPCONTROLLER_H
#define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021
#define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056
#define ASUS_WMI_DEVID_TUF_RGB_STATE 0x00100057
#define ASUS_WMI_KEYBOARD_SPEED_SLOW 0xE1
#define ASUS_WMI_KEYBOARD_SPEED_NORMAL 0xEB
#define ASUS_WMI_KEYBOARD_SPEED_FAST 0xF5
#define ASUS_WMI_KEYBOARD_SPEED_MIN 1
#define ASUS_WMI_KEYBOARD_SPEED_MAX 3
#define ASUS_WMI_KEYBOARD_MODE_STATIC 0x00
#define ASUS_WMI_KEYBOARD_MODE_BREATHING 0x01
#define ASUS_WMI_KEYBOARD_MODE_COLORCYCLE 0x02
#define ASUS_WMI_KEYBOARD_MODE_STROBING 0x0A
#define ASUS_WMI_KEYBOARD_BRIGHTNESS_MIN 0
#define ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX 3
#define ASUS_WMI_KEYBOARD_MAGIC_USE 0xB3
#define ASUS_WMI_KEYBOARD_MAGIC_SAVE 0xB4
#define ASUS_WMI_KEYBOARD_POWER_BOOT 0x03<<16
#define ASUS_WMI_KEYBOARD_POWER_AWAKE 0x0C<<16
#define ASUS_WMI_KEYBOARD_POWER_SLEEP 0x30<<16
#define ASUS_WMI_KEYBOARD_POWER_SHUTDOWN 0xC0<<16
#define ASUS_WMI_KEYBOARD_POWER_SAVE 0x01<<8
class AsusTUFLaptopController
{
public:
AsusTUFLaptopController();
~AsusTUFLaptopController();
void SetMode(unsigned char red,
unsigned char green,
unsigned char blue,
unsigned char mode,
unsigned char speed,
bool save);
unsigned char GetBrightness();
void SetBrightness(unsigned char brightness);
void SetPowerState(bool boot,
bool awake,
bool sleep,
bool shutdown,
bool save);
};
#endif // ASUSTUFLAPTOPCONTROLLER_H
#endif // _WIN32

View file

@ -1,5 +1,6 @@
#ifdef _WIN32
#include "AsusTUFLaptopController.h"
#include "RGBController_AsusTUFLaptopWMI.h"
#include "acpiwmi.h"
@ -29,6 +30,7 @@ static void DetectAsusTUFLaptopWMIControllers()
return;
}
std::string& name = systemProduct[0]["Name"];
if(name.find("TUF Gaming") == name.npos)
{
return;
@ -36,7 +38,9 @@ static void DetectAsusTUFLaptopWMIControllers()
if(AsWMI_Open())
{
RGBController* new_controller = new RGBController_AsusTUFLaptopWMI();
AsusTUFLaptopController* asus_wmi_controller = new AsusTUFLaptopController();
RGBController* new_controller = new RGBController_AsusTUFLaptopWMI(asus_wmi_controller);
ResourceManager::get()->RegisterRGBController(new_controller);
// Success! No more if's
}

View file

@ -2,12 +2,6 @@
#include "RGBController_AsusTUFLaptopWMI.h"
#include "acpiwmi.h"
#include "ResourceManager.h"
#include "Detector.h"
#include "wmi.h"
#include <string>
using namespace std::chrono_literals;
/**------------------------------------------------------------------*\
@ -21,72 +15,91 @@ using namespace std::chrono_literals;
@comment
\*-------------------------------------------------------------------*/
RGBController_AsusTUFLaptopWMI::RGBController_AsusTUFLaptopWMI()
RGBController_AsusTUFLaptopWMI::RGBController_AsusTUFLaptopWMI(AsusTUFLaptopController* controller_ptr)
{
name = "ASUS TUF Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "WMI Device";
location = "\\\\.\\ATKACPI";
name = "ASUS TUF Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "WMI Device";
location = "\\\\.\\ATKACPI";
modes.resize(5);
modes[0].name = "Direct";
modes[0].value = 4;
modes[0].flags = MODE_FLAG_HAS_PER_LED_COLOR;
modes[0].color_mode = MODE_COLORS_PER_LED;
mode Static;
Static.name = "Static";
Static.value = ASUS_WMI_KEYBOARD_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
Static.color_mode = MODE_COLORS_PER_LED;
Static.brightness_max = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
Static.brightness_min = ASUS_WMI_KEYBOARD_BRIGHTNESS_MIN;
Static.brightness = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
modes.push_back(Static);
modes[1].name = "Static";
modes[1].value = 0;
modes[1].flags = MODE_FLAG_HAS_PER_LED_COLOR;
modes[1].color_mode = MODE_COLORS_PER_LED;
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ASUS_WMI_KEYBOARD_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = ASUS_WMI_KEYBOARD_SPEED_MIN;
Breathing.speed_max = ASUS_WMI_KEYBOARD_SPEED_MAX;
Breathing.speed = 2;
Breathing.brightness_max = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
Breathing.brightness_min = ASUS_WMI_KEYBOARD_BRIGHTNESS_MIN;
Breathing.brightness = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
modes.push_back(Breathing);
modes[2].name = "Breathing";
modes[2].value = 1;
modes[2].flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
modes[2].speed_min = 0;
modes[2].speed_max = 2;
modes[2].color_mode = MODE_COLORS_PER_LED;
modes[2].speed = 1;
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = ASUS_WMI_KEYBOARD_MODE_COLORCYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed_min = ASUS_WMI_KEYBOARD_SPEED_MIN;
ColorCycle.speed_max = ASUS_WMI_KEYBOARD_SPEED_MAX;
ColorCycle.speed = 2;
ColorCycle.brightness_max = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
ColorCycle.brightness_min = ASUS_WMI_KEYBOARD_BRIGHTNESS_MIN;
ColorCycle.brightness = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
modes.push_back(ColorCycle);
modes[3].name = "Color Cycle";
modes[3].value = 2;
modes[3].flags = MODE_FLAG_HAS_SPEED;
modes[3].speed_min = 0;
modes[3].speed_max = 2;
modes[3].color_mode = MODE_COLORS_NONE;
modes[3].speed = 1;
modes[4].name = "Strobe";
modes[4].value = 0x0A;
modes[4].flags = MODE_FLAG_HAS_PER_LED_COLOR;
modes[4].color_mode = MODE_COLORS_PER_LED;
mode Strobing;
Strobing.name = "Strobing";
Strobing.value = ASUS_WMI_KEYBOARD_MODE_STROBING;
Strobing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
Strobing.color_mode = MODE_COLORS_PER_LED;
Strobing.brightness_max = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
Strobing.brightness_min = ASUS_WMI_KEYBOARD_BRIGHTNESS_MIN;
Strobing.brightness = ASUS_WMI_KEYBOARD_BRIGHTNESS_MAX;
modes.push_back(Strobing);
SetupZones();
controller = controller_ptr;
ReadConfiguration();
}
RGBController_AsusTUFLaptopWMI::~RGBController_AsusTUFLaptopWMI()
{
AsWMI_Close();
delete controller;
}
void RGBController_AsusTUFLaptopWMI::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zone |
| Device only has one zone and one led |
\*---------------------------------------------------------*/
zones.resize(1);
zones[0].type = ZONE_TYPE_SINGLE;
zones[0].name = "Keyboard Backlight zone";
zones[0].leds_min = 1;
zones[0].leds_max = 1;
zones[0].leds_count = 1;
zones[0].matrix_map = NULL;
zone* new_zone = new zone();
led* new_led = new led();
/*---------------------------------------------------------*\
| Set up LED |
\*---------------------------------------------------------*/
leds.resize(1);
leds[0].name = "Keyboard Backlight LED";
new_zone->type = ZONE_TYPE_SINGLE;
new_zone->name = "Keyboard Backlight zone";
new_zone->leds_min = 1;
new_zone->leds_max = 1;
new_zone->leds_count = 1;
new_zone->matrix_map = NULL;
new_led->name = "Keyboard Backlight LED";
zones.push_back(*new_zone);
leds.push_back(*new_led);
SetupColors();
}
@ -98,52 +111,66 @@ void RGBController_AsusTUFLaptopWMI::ResizeZone(int /*zone*/, int /*new_size*/)
\*---------------------------------------------------------*/
}
/*---------------------------------------------------------*\
| Break this function off since we have to call save in the |
same operation as doing everything else. |
\*---------------------------------------------------------*/
void RGBController_AsusTUFLaptopWMI::ControllerSetMode(bool save)
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char green = RGBGetGValue(colors[0]);
unsigned char blue = RGBGetBValue(colors[0]);
unsigned char mode = (unsigned char)modes[(unsigned int)active_mode].value;
/*------------------------------------------------------------*\
| Use speed only if the mode supports it. Otherwise set normal |
\*------------------------------------------------------------*/
unsigned char speed = ASUS_WMI_KEYBOARD_SPEED_NORMAL;
if (modes[(unsigned int)active_mode].flags & MODE_FLAG_HAS_SPEED)
{
speed = (unsigned char)modes[(unsigned int)active_mode].speed;
}
controller->SetMode(red, green, blue, mode, speed, save);
}
void RGBController_AsusTUFLaptopWMI::DeviceUpdateLEDs()
{
uint8_t red = RGBGetRValue(colors[0]);
uint8_t green = RGBGetGValue(colors[0]);
uint8_t blue = RGBGetBValue(colors[0]);
uint8_t speed_byte = 0;
uint8_t mode = modes[active_mode].value;
uint8_t inv = 0;
if(mode == 4)
{
mode = 1;
inv = 4; // Any invalid mode, i.e. anything other than 0, 1, 2 and 10
}
if(mode == 1 || mode == 2)
{
switch(modes[active_mode].speed)
{
case 0: speed_byte = 0xE1; break;
case 1: speed_byte = 0xEB; break;
case 2: speed_byte = 0xF5; break;
}
}
int high = ((mode | ((red | (green << 8)) << 8)) << 8) | 0xB3;
int low = blue | (speed_byte << 8);
AsWMI_NB_DeviceControl_2arg(0x100056, high, low);
if(inv)
{
//std::this_thread::sleep_for(10ms);
high = ((inv | ((red | (green << 8)) << 8)) << 8) | 0xB3;
AsWMI_NB_DeviceControl_2arg(0x100056, high, low);
}
ControllerSetMode(false);
}
void RGBController_AsusTUFLaptopWMI::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
ControllerSetMode(false);
}
void RGBController_AsusTUFLaptopWMI::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
ControllerSetMode(false);
}
void RGBController_AsusTUFLaptopWMI::DeviceUpdateMode()
{
DeviceUpdateLEDs();
if (modes[(unsigned int)active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
controller->SetBrightness((unsigned char)modes[(unsigned int)active_mode].brightness);
}
ControllerSetMode(false);
}
void RGBController_AsusTUFLaptopWMI::ReadConfiguration()
{
if (modes[(unsigned int)active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
modes[(unsigned int)active_mode].brightness = controller->GetBrightness();
}
}
void RGBController_AsusTUFLaptopWMI::DeviceSaveMode()
{
ControllerSetMode(true);
}
#endif

View file

@ -1,27 +1,35 @@
#ifdef _WIN32
#ifndef RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
#define RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
#ifdef _WIN32
#include "AsusTUFLaptopController.h"
#include "RGBController.h"
class RGBController_AsusTUFLaptopWMI : public RGBController
{
public:
RGBController_AsusTUFLaptopWMI();
RGBController_AsusTUFLaptopWMI(AsusTUFLaptopController* controller_ptr);
virtual ~RGBController_AsusTUFLaptopWMI();
void SetupZones() override;
void SetupZones();
void ResizeZone(int zone, int new_size) override;
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs() override;
void UpdateZoneLEDs(int zone) override;
void UpdateSingleLED(int led) override;
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode() override;
void DeviceUpdateMode();
void DeviceSaveMode();
private:
AsusTUFLaptopController* controller;
void ReadConfiguration();
void ControllerSetMode(bool save);
};
#endif
#endif // RGBCONTROLLER_ASUSTUFLAPTOPWMI_H
#endif // _WIN32

View file

@ -1506,6 +1506,7 @@ win32:SOURCES +=
wmi/wmi.cpp \
wmi/acpiwmi.cpp \
AutoStart/AutoStart-Windows.cpp \
Controllers/AsusTUFLaptopController/AsusTUFLaptopController.cpp \
Controllers/AsusTUFLaptopController/AsusTUFLaptopWMIDetect.cpp \
Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.cpp \
Controllers/ENESMBusController/XPGSpectrixS40GDetect_Windows.cpp \
@ -1530,6 +1531,7 @@ win32:HEADERS +=
wmi/wmi.h \
wmi/acpiwmi.h \
AutoStart/AutoStart-Windows.h \
Controllers/AsusTUFLaptopController/AsusTUFLaptopController.h \
Controllers/AsusTUFLaptopController/RGBController_AsusTUFLaptopWMI.h \
Controllers/ENESMBusController/ENESMBusInterface/ENESMBusInterface_SpectrixS40G_Windows.h \
Controllers/NVIDIAIlluminationController/nvapi_accessor.h \