mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Try to mitigate the lack of kbd_brightness on some laptops
This commit is contained in:
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Better more robust error handling in ROGCC
|
- Better more robust error handling in ROGCC
|
||||||
- Try to better handle pre-2021 laptops with lightbar
|
- Try to better handle pre-2021 laptops with lightbar
|
||||||
- Add more logging to try and trace the charge_control_end_threshold issue
|
- Add more logging to try and trace the charge_control_end_threshold issue
|
||||||
|
- Make `kbd_brightness` optional to work around issues on some laptops that seem to lack it. Likely this will all need a refactor *again* if work proceeds in kernel for better RGB support.
|
||||||
|
|
||||||
## [v6.0.4]
|
## [v6.0.4]
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ The list is a bit outdated as many features have been enabled in the Linux kerne
|
|||||||
|
|
||||||
A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already.
|
A gui is now in the repo - ROG Control Center. At this time it is still a WIP, but it has almost all features in place already.
|
||||||
|
|
||||||
|
**NOTE**: Xorg is not supported.
|
||||||
|
|
||||||
# BUILDING
|
# BUILDING
|
||||||
|
|
||||||
Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/) or from the distro repos if newer than 1.75.
|
Rust and cargo are required, they can be installed from [rustup.rs](https://rustup.rs/) or from the distro repos if newer than 1.75.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use rog_aura::{
|
|||||||
AuraDeviceType, AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN,
|
AuraDeviceType, AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN,
|
||||||
};
|
};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||||
use zbus::zvariant::OwnedObjectPath;
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
|
|
||||||
use super::config::AuraConfig;
|
use super::config::AuraConfig;
|
||||||
@@ -21,9 +21,9 @@ use crate::error::RogError;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LEDNode {
|
pub enum LEDNode {
|
||||||
/// Brightness and/or TUF RGB controls
|
/// Brightness and/or TUF RGB controls
|
||||||
KbdLed(KeyboardLed),
|
KbdLed(KeyboardBacklight),
|
||||||
/// Raw HID handle
|
/// Raw HID handle
|
||||||
Rog(KeyboardLed, HidRaw),
|
Rog(Option<KeyboardBacklight>, HidRaw),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LEDNode {
|
impl LEDNode {
|
||||||
@@ -31,7 +31,13 @@ impl LEDNode {
|
|||||||
pub fn set_brightness(&self, value: u8) -> Result<(), RogError> {
|
pub fn set_brightness(&self, value: u8) -> Result<(), RogError> {
|
||||||
match self {
|
match self {
|
||||||
LEDNode::KbdLed(k) => k.set_brightness(value)?,
|
LEDNode::KbdLed(k) => k.set_brightness(value)?,
|
||||||
LEDNode::Rog(k, _) => k.set_brightness(value)?,
|
LEDNode::Rog(k, _) => {
|
||||||
|
if let Some(k) = k {
|
||||||
|
k.set_brightness(value)?
|
||||||
|
} else {
|
||||||
|
debug!("No brightness control found");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -39,16 +45,47 @@ impl LEDNode {
|
|||||||
pub fn get_brightness(&self) -> Result<u8, RogError> {
|
pub fn get_brightness(&self) -> Result<u8, RogError> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
LEDNode::KbdLed(k) => k.get_brightness()?,
|
LEDNode::KbdLed(k) => k.get_brightness()?,
|
||||||
LEDNode::Rog(k, _) => k.get_brightness()?,
|
LEDNode::Rog(k, _) => {
|
||||||
|
if let Some(k) = k {
|
||||||
|
k.get_brightness()?
|
||||||
|
} else {
|
||||||
|
debug!("No brightness control found");
|
||||||
|
return Err(RogError::MissingFunction(
|
||||||
|
"No keyboard brightness control found".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monitor_brightness(&self) -> Result<Inotify, RogError> {
|
pub fn monitor_brightness(&self) -> Result<Inotify, RogError> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
LEDNode::KbdLed(k) => k.monitor_brightness()?,
|
LEDNode::KbdLed(k) => k.monitor_brightness()?,
|
||||||
LEDNode::Rog(k, _) => k.monitor_brightness()?,
|
LEDNode::Rog(k, _) => {
|
||||||
|
if let Some(k) = k {
|
||||||
|
k.monitor_brightness()?
|
||||||
|
} else {
|
||||||
|
debug!("No brightness control found");
|
||||||
|
return Err(RogError::MissingFunction(
|
||||||
|
"No keyboard brightness control found".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_brightness_control(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
LEDNode::KbdLed(k) => k.has_brightness(),
|
||||||
|
LEDNode::Rog(k, _) => {
|
||||||
|
if let Some(k) = k {
|
||||||
|
k.has_brightness()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Individual controller for one Aura device
|
/// Individual controller for one Aura device
|
||||||
@@ -122,7 +159,7 @@ impl CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for a TUF laptop LED. Assume there is only ever one.
|
// Check for a TUF laptop LED. Assume there is only ever one.
|
||||||
if let Ok(kbd_backlight) = KeyboardLed::new() {
|
if let Ok(kbd_backlight) = KeyboardBacklight::new() {
|
||||||
if kbd_backlight.has_kbd_rgb_mode() {
|
if kbd_backlight.has_kbd_rgb_mode() {
|
||||||
// Extra sure double-check that this isn't a laptop with crap
|
// Extra sure double-check that this isn't a laptop with crap
|
||||||
// ACPI with borked return on the TUF rgb methods
|
// ACPI with borked return on the TUF rgb methods
|
||||||
@@ -157,7 +194,14 @@ impl CtrlKbdLed {
|
|||||||
/// should be overwritten. The reason for the default config is because
|
/// should be overwritten. The reason for the default config is because
|
||||||
/// of async issues between this and udev/hidraw
|
/// of async issues between this and udev/hidraw
|
||||||
pub fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result<Self, RogError> {
|
pub fn from_hidraw(device: HidRaw, dbus_path: OwnedObjectPath) -> Result<Self, RogError> {
|
||||||
let rgb_led = KeyboardLed::new()?;
|
let rgb_led = KeyboardBacklight::new()
|
||||||
|
.map_err(|e| {
|
||||||
|
log::error!(
|
||||||
|
"{} is missing a keyboard backlight brightness control: {e:?}",
|
||||||
|
device.prod_id()
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
let prod_id = AuraDeviceType::from(device.prod_id());
|
let prod_id = AuraDeviceType::from(device.prod_id());
|
||||||
if prod_id == AuraDeviceType::Unknown {
|
if prod_id == AuraDeviceType::Unknown {
|
||||||
log::error!("{} is AuraDevice::Unknown", device.prod_id());
|
log::error!("{} is AuraDevice::Unknown", device.prod_id());
|
||||||
@@ -376,7 +420,7 @@ mod tests {
|
|||||||
use rog_aura::aura_detection::LedSupportData;
|
use rog_aura::aura_detection::LedSupportData;
|
||||||
use rog_aura::{AuraDeviceType, AuraModeNum, AuraZone, PowerZones};
|
use rog_aura::{AuraDeviceType, AuraModeNum, AuraZone, PowerZones};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||||
use zbus::zvariant::OwnedObjectPath;
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
|
|
||||||
use super::CtrlKbdLed;
|
use super::CtrlKbdLed;
|
||||||
@@ -399,7 +443,10 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_type: AuraDeviceType::LaptopPost2021,
|
led_type: AuraDeviceType::LaptopPost2021,
|
||||||
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("19b6").unwrap()),
|
led_node: LEDNode::Rog(
|
||||||
|
Some(KeyboardBacklight::default()),
|
||||||
|
HidRaw::new("19b6").unwrap(),
|
||||||
|
),
|
||||||
supported_data: supported_basic_modes,
|
supported_data: supported_basic_modes,
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config,
|
||||||
@@ -440,7 +487,10 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_type: AuraDeviceType::LaptopPost2021,
|
led_type: AuraDeviceType::LaptopPost2021,
|
||||||
led_node: LEDNode::Rog(KeyboardLed::default(), HidRaw::new("19b6").unwrap()),
|
led_node: LEDNode::Rog(
|
||||||
|
Some(KeyboardBacklight::default()),
|
||||||
|
HidRaw::new("19b6").unwrap(),
|
||||||
|
),
|
||||||
supported_data: supported_basic_modes,
|
supported_data: supported_basic_modes,
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ impl CtrlAuraZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
||||||
let bright = lock.led_node.get_brightness()?;
|
let bright = lock.led_node.get_brightness().unwrap_or_default();
|
||||||
lock.config.read();
|
lock.config.read();
|
||||||
lock.config.brightness = bright.into();
|
lock.config.brightness = bright.into();
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
@@ -109,8 +109,10 @@ impl CtrlAuraZbus {
|
|||||||
if ctrl.config.brightness == LedBrightness::Off {
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
ctrl.config.brightness = LedBrightness::Med;
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
}
|
}
|
||||||
ctrl.led_node
|
if ctrl.led_node.has_brightness_control() {
|
||||||
.set_brightness(ctrl.config.brightness.into())?;
|
ctrl.led_node
|
||||||
|
.set_brightness(ctrl.config.brightness.into())?;
|
||||||
|
}
|
||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
|
||||||
self.led_mode_data_invalidate(&self.1).await.ok();
|
self.led_mode_data_invalidate(&self.1).await.ok();
|
||||||
@@ -148,8 +150,10 @@ impl CtrlAuraZbus {
|
|||||||
if ctrl.config.brightness == LedBrightness::Off {
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
ctrl.config.brightness = LedBrightness::Med;
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
}
|
}
|
||||||
ctrl.led_node
|
if ctrl.led_node.has_brightness_control() {
|
||||||
.set_brightness(ctrl.config.brightness.into())?;
|
ctrl.led_node
|
||||||
|
.set_brightness(ctrl.config.brightness.into())?;
|
||||||
|
}
|
||||||
ctrl.config.set_builtin(effect);
|
ctrl.config.set_builtin(effect);
|
||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
|
||||||
@@ -213,12 +217,14 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
// If waking up
|
// If waking up
|
||||||
if !start {
|
if !start {
|
||||||
info!("CtrlKbdLedTask reloading brightness and modes");
|
info!("CtrlKbdLedTask reloading brightness and modes");
|
||||||
lock.led_node
|
if lock.led_node.has_brightness_control() {
|
||||||
.set_brightness(lock.config.brightness.into())
|
lock.led_node
|
||||||
.map_err(|e| {
|
.set_brightness(lock.config.brightness.into())
|
||||||
error!("CtrlKbdLedTask: {e}");
|
.map_err(|e| {
|
||||||
e
|
error!("CtrlKbdLedTask: {e}");
|
||||||
})?;
|
e
|
||||||
|
})?;
|
||||||
|
}
|
||||||
lock.write_current_config_mode().map_err(|e| {
|
lock.write_current_config_mode().map_err(|e| {
|
||||||
error!("CtrlKbdLedTask: {e}");
|
error!("CtrlKbdLedTask: {e}");
|
||||||
e
|
e
|
||||||
@@ -264,20 +270,22 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
|
|
||||||
let ctrl2 = self.0.clone();
|
let ctrl2 = self.0.clone();
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
let watch = ctrl.led_node.monitor_brightness()?;
|
if ctrl.led_node.has_brightness_control() {
|
||||||
tokio::spawn(async move {
|
let watch = ctrl.led_node.monitor_brightness()?;
|
||||||
let mut buffer = [0; 32];
|
tokio::spawn(async move {
|
||||||
watch
|
let mut buffer = [0; 32];
|
||||||
.into_event_stream(&mut buffer)
|
watch
|
||||||
.unwrap()
|
.into_event_stream(&mut buffer)
|
||||||
.for_each(|_| async {
|
.unwrap()
|
||||||
if let Some(lock) = ctrl2.try_lock() {
|
.for_each(|_| async {
|
||||||
load_save(true, lock).unwrap(); // unwrap as we want to
|
if let Some(lock) = ctrl2.try_lock() {
|
||||||
// bomb out of the task
|
load_save(true, lock).unwrap(); // unwrap as we want to
|
||||||
}
|
// bomb out of the task
|
||||||
})
|
}
|
||||||
.await;
|
})
|
||||||
});
|
.await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -328,9 +328,9 @@
|
|||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
basic_zones: [Key1, Key2, Key3, Key4],
|
basic_zones: [Key1, Key2, Key3, Key4, BarLeft, BarRight],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard, Lightbar],
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
device_name: "G731",
|
device_name: "G731",
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ use log::{info, warn};
|
|||||||
use crate::error::{PlatformError, Result};
|
use crate::error::{PlatformError, Result};
|
||||||
use crate::{attr_u8, has_attr, set_attr_u8_array, to_device};
|
use crate::{attr_u8, has_attr, set_attr_u8_array, to_device};
|
||||||
|
|
||||||
|
/// The sysfs control for backlight levels. This is only for the 3-step
|
||||||
|
/// backlight setting, and for TUF laptops. It is not a hard requirement
|
||||||
|
/// for Aura keyboards
|
||||||
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Clone)]
|
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Clone)]
|
||||||
pub struct KeyboardLed {
|
pub struct KeyboardBacklight {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyboardLed {
|
impl KeyboardBacklight {
|
||||||
attr_u8!("brightness", path);
|
attr_u8!("brightness", path);
|
||||||
|
|
||||||
has_attr!("kbd_rgb_mode" path);
|
has_attr!("kbd_rgb_mode" path);
|
||||||
@@ -59,7 +62,7 @@ impl KeyboardLed {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(PlatformError::MissingFunction(
|
Err(PlatformError::MissingFunction(
|
||||||
"asus::kbd_backlight not found".into(),
|
"KeyboardLed:new(), asus::kbd_backlight not found".into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user