From c88a6021f27a23b7d1b84010a6fe19be2671fdb3 Mon Sep 17 00:00:00 2001 From: Misaka 19465 <19465@misakanet.team> Date: Thu, 22 Dec 2022 14:57:58 +0000 Subject: [PATCH] Adding support for ASUS TUF Laptop keyboard LED for Linux --- .../AsusTUFLaptopLinuxController.cpp | 51 ++++++ .../AsusTUFLaptopLinuxController.h | 37 +++++ .../AsusTUFLaptopLinuxDetect.cpp | 28 ++++ .../RGBController_AsusTUFLaptopLinux.cpp | 150 ++++++++++++++++++ .../RGBController_AsusTUFLaptopLinux.h | 27 ++++ OpenRGB.pro | 5 + scripts/build-udev-rules.sh | 5 + 7 files changed, 303 insertions(+) create mode 100644 Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.cpp create mode 100644 Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.h create mode 100644 Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxDetect.cpp create mode 100644 Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.cpp create mode 100644 Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.h diff --git a/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.cpp b/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.cpp new file mode 100644 index 00000000..f112dbea --- /dev/null +++ b/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.cpp @@ -0,0 +1,51 @@ +#include "AsusTUFLaptopLinuxController.h" + +#include + +void AsusTUFLaptopLinuxController::SendUpdate +( + unsigned char mode, + unsigned char speed, + unsigned char save, + unsigned char red, + unsigned char green, + unsigned char blue +) +{ + std::string s = ""; + s.append(ASUS_KBD_BACKLIGHT_BASE_PATH); + s.append(ASUS_KBD_BACKLIGHT_MODE_PATH); + FILE *controller = fopen(s.c_str(), "w"); + + s = ""; + s.append(std::to_string(save)); + s.append(" "); + s.append(std::to_string(mode)); + s.append(" "); + s.append(std::to_string(red)); + s.append(" "); + s.append(std::to_string(green)); + s.append(" "); + s.append(std::to_string(blue)); + s.append(" "); + s.append(std::to_string(speed)); + + fputs(s.c_str(), controller); + + fclose(controller); +} + +void AsusTUFLaptopLinuxController::SendBrightness +( + unsigned char brightness +) +{ + std::string s = ""; + s.append(ASUS_KBD_BACKLIGHT_BASE_PATH); + s.append(ASUS_KBD_BACKLIGHT_BRIGHTNESS_PATH); + FILE *controller = fopen(s.c_str(), "w"); + + fputs(std::to_string(brightness).c_str(), controller); + + fclose(controller); +} diff --git a/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.h b/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.h new file mode 100644 index 00000000..70f0054b --- /dev/null +++ b/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.h @@ -0,0 +1,37 @@ +#ifndef ASUSTUFLAPTOPLINUXCONTROLLER_H +#define ASUSTUFLAPTOPLINUXCONTROLLER_H + +#include "RGBController.h" + +#define ASUS_KBD_BACKLIGHT_BRIGHTNESS_MIN 0 +#define ASUS_KBD_BACKLIGHT_BRIGHTNESS_MAX 3 +#define ASUS_KBD_BACKLIGHT_BRIGHTNESS 3 + +#define ASUS_KBD_BACKLIGHT_SPEED_MIN 0 +#define ASUS_KBD_BACKLIGHT_SPEED_MAX 2 +#define ASUS_KBD_BACKLIGHT_SPEED 1 + +#define ASUS_KBD_BACKLIGHT_BASE_PATH "/sys/devices/platform/asus-nb-wmi/leds/asus::kbd_backlight" +#define ASUS_KBD_BACKLIGHT_MODE_PATH "/kbd_rgb_mode" +#define ASUS_KBD_BACKLIGHT_BRIGHTNESS_PATH "/brightness" + +class AsusTUFLaptopLinuxController +{ +public: + void SendBrightness + ( + unsigned char brightness + ); + + void SendUpdate + ( + unsigned char mode, + unsigned char speed, + unsigned char save, + unsigned char red, + unsigned char green, + unsigned char blue + ); +}; + +#endif // ASUSTUFLAPTOPLINUXCONTROLLER_H diff --git a/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxDetect.cpp b/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxDetect.cpp new file mode 100644 index 00000000..4e73df45 --- /dev/null +++ b/Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxDetect.cpp @@ -0,0 +1,28 @@ +#include "RGBController_AsusTUFLaptopLinux.h" +#include "AsusTUFLaptopLinuxController.h" + +#include +#include "Detector.h" +#include + +static void DetectAsusTUFLaptopLinuxControllers(std::vector&) +{ + /*-------------------------------------------------------------------------------------*\ + | If /sys/devices/platform/asus-nb-wmi/leds/asus::kbd_backlight/kbd_rgb_mode exists, | + | the kernel support TUF Laptop keyboard LED controlling. | + \*-------------------------------------------------------------------------------------*/ + + std::string s = ""; + s.append(ASUS_KBD_BACKLIGHT_BASE_PATH); + s.append(ASUS_KBD_BACKLIGHT_MODE_PATH); + + if(!access(s.c_str(), F_OK)) + { + AsusTUFLaptopLinuxController* controller = new AsusTUFLaptopLinuxController(); + RGBController_AsusTUFLaptopLinux* rgb_controller = new RGBController_AsusTUFLaptopLinux(controller); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + return; +} + +REGISTER_DETECTOR("ASUS TUF Laptop Linux WMI", DetectAsusTUFLaptopLinuxControllers); diff --git a/Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.cpp b/Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.cpp new file mode 100644 index 00000000..da9a01b1 --- /dev/null +++ b/Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.cpp @@ -0,0 +1,150 @@ +#include "RGBController_AsusTUFLaptopLinux.h" + +/**------------------------------------------------------------------*\ + @name Asus TUF Laptop Linux WMI + @category Keyboard + @type File Stream + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectAsusTUFLaptopLinuxControllers + @comment Tested on ASUS TUF Gaming A15 2022 + PLEASE UPDATE YOUR KERNEL TO A VERSION NEWER THAN 6.1.0 + + Every devices supported by asus-wmi would work technically. +\*-------------------------------------------------------------------*/ + +RGBController_AsusTUFLaptopLinux::RGBController_AsusTUFLaptopLinux(AsusTUFLaptopLinuxController* controller_ptr) +{ + controller = controller_ptr; + + name = "ASUS TUF Keyboard"; + vendor = "ASUS"; + type = DEVICE_TYPE_KEYBOARD; + description = "Asus TUF Device"; + location = ASUS_KBD_BACKLIGHT_BASE_PATH; + + mode Direct; + Direct.name = "Direct"; + Direct.value = 4; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Direct.brightness_min = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MIN; + Direct.brightness_max = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MAX; + Direct.brightness = ASUS_KBD_BACKLIGHT_BRIGHTNESS; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Static; + Static.name = "Static"; + Static.value = 0; + Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Static.brightness_min = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MIN; + Static.brightness_max = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MAX; + Static.brightness = ASUS_KBD_BACKLIGHT_BRIGHTNESS; + Static.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Static); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = 1; + Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Breathing.speed_min = ASUS_KBD_BACKLIGHT_SPEED_MIN; + Breathing.speed_max = ASUS_KBD_BACKLIGHT_SPEED_MAX; + Breathing.brightness_min = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MIN; + Breathing.brightness_max = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MAX; + Breathing.brightness = ASUS_KBD_BACKLIGHT_BRIGHTNESS; + Breathing.color_mode = MODE_COLORS_PER_LED; + Breathing.speed = ASUS_KBD_BACKLIGHT_SPEED; + modes.push_back(Breathing); + + mode Cycle; + Cycle.name = "Spectrum Cycle"; + Cycle.value = 2; + Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Cycle.speed_min = ASUS_KBD_BACKLIGHT_SPEED_MIN; + Cycle.speed_max = ASUS_KBD_BACKLIGHT_SPEED_MAX; + Cycle.brightness_min = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MIN; + Cycle.brightness_max = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MAX; + Cycle.brightness = ASUS_KBD_BACKLIGHT_BRIGHTNESS; + Cycle.color_mode = MODE_COLORS_NONE; + Cycle.speed = ASUS_KBD_BACKLIGHT_SPEED; + modes.push_back(Cycle); + + mode Flashing; + Flashing.name = "Flashing"; + Flashing.value = 0x0A; + Flashing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Flashing.brightness_min = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MIN; + Flashing.brightness_max = ASUS_KBD_BACKLIGHT_BRIGHTNESS_MAX; + Flashing.brightness = ASUS_KBD_BACKLIGHT_BRIGHTNESS; + Flashing.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Flashing); + + SetupZones(); +} + +void RGBController_AsusTUFLaptopLinux::SetupZones() +{ + /*---------------------------------------------------------*\ + | Set up zone | + \*---------------------------------------------------------*/ + 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; + + /*---------------------------------------------------------*\ + | Set up LED | + \*---------------------------------------------------------*/ + leds.resize(1); + leds[0].name = "Keyboard Backlight LED"; + + SetupColors(); +} + +void RGBController_AsusTUFLaptopLinux::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_AsusTUFLaptopLinux::DeviceUpdateLEDs() +{ + uint8_t red = RGBGetRValue(colors[0]); + uint8_t green = RGBGetGValue(colors[0]); + uint8_t blue = RGBGetBValue(colors[0]); + uint8_t speed = 0; + uint8_t mode = modes[active_mode].value; + uint8_t save = 1; + if(mode == 4) + { + mode = 0; + save = 0; + } + if(mode == 1 || mode == 2) + { + speed = modes[active_mode].speed; + } + + controller->SendUpdate(mode, speed, save, red, green, blue); + controller->SendBrightness(modes[active_mode].brightness); +} + +void RGBController_AsusTUFLaptopLinux::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AsusTUFLaptopLinux::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_AsusTUFLaptopLinux::DeviceUpdateMode() +{ + DeviceUpdateLEDs(); +} diff --git a/Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.h b/Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.h new file mode 100644 index 00000000..a7e76bca --- /dev/null +++ b/Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.h @@ -0,0 +1,27 @@ +#ifndef RGBCONTROLLER_ASUSTUFLAPTOPLINUX_H +#define RGBCONTROLLER_ASUSTUFLAPTOPLINUX_H + +#include "RGBController.h" +#include "AsusTUFLaptopLinuxController.h" + + +class RGBController_AsusTUFLaptopLinux : public RGBController +{ +public: + RGBController_AsusTUFLaptopLinux(AsusTUFLaptopLinuxController* controller_ptr); + + void SetupZones() override; + + void ResizeZone(int zone, int new_size) override; + + void DeviceUpdateLEDs() override; + void UpdateZoneLEDs(int zone) override; + void UpdateSingleLED(int led) override; + + void DeviceUpdateMode() override; + +private: + AsusTUFLaptopLinuxController* controller; +}; + +#endif // RGBCONTROLLER_ASUSTUFLAPTOPLINUX_H diff --git a/OpenRGB.pro b/OpenRGB.pro index aabbd161..e691160d 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -1551,6 +1551,8 @@ contains(QMAKE_PLATFORM, linux) { HEADERS += \ i2c_smbus/i2c_smbus_linux.h \ AutoStart/AutoStart-Linux.h \ + Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.h \ + Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.h \ Controllers/ENESMBusController/ENESMBusInterface/ENESMBusInterface_SpectrixS40G.h \ Controllers/FaustusController/RGBController_Faustus.h \ Controllers/LinuxLEDController/LinuxLEDController.h \ @@ -1598,6 +1600,9 @@ contains(QMAKE_PLATFORM, linux) { i2c_smbus/i2c_smbus_linux.cpp \ serial_port/find_usb_serial_port_linux.cpp \ AutoStart/AutoStart-Linux.cpp \ + Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxController.cpp \ + Controllers/AsusTUFLaptopLinuxController/AsusTUFLaptopLinuxDetect.cpp \ + Controllers/AsusTUFLaptopLinuxController/RGBController_AsusTUFLaptopLinux.cpp \ Controllers/ENESMBusController/XPGSpectrixS40GDetect.cpp \ Controllers/ENESMBusController/ENESMBusInterface/ENESMBusInterface_SpectrixS40G.cpp \ Controllers/FaustusController/RGBController_Faustus.cpp \ diff --git a/scripts/build-udev-rules.sh b/scripts/build-udev-rules.sh index 1a9945ac..e21cfb41 100755 --- a/scripts/build-udev-rules.sh +++ b/scripts/build-udev-rules.sh @@ -33,6 +33,11 @@ for DEV in ${ASUS_TUF_DEVICES[@]}; do UDEV_HEADER+='ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_'${DEV}'"\n' done +# asus-wmi rules +UDEV_HEADER+=${UDEV_LINE}'# ASUS TUF Laptops (asus-wmi) #\n'${UDEV_LINE} +UDEV_HEADER+='ACTION=="add", SUBSYSTEM=="platform", KERNEL=="asus-nb-wmi", RUN+="/bin/chmod a+w /sys/bus/platform/devices/asus-nb-wmi/leds/asus::kbd_backlight/kbd_rgb_mode"' +UDEV_HEADER+='ACTION=="add", SUBSYSTEM=="platform", KERNEL=="asus-nb-wmi", RUN+="/bin/chmod a+w /sys/bus/platform/devices/asus-nb-wmi/leds/asus::kbd_backlight/brightness"' + echo -e "$UDEV_HEADER" > "$UDEV_FILE" #-----------------------------------------------------------------------------#