Try to mitigate the lack of kbd_brightness on some laptops

This commit is contained in:
Luke D. Jones
2024-05-10 12:21:15 +12:00
parent e62e7e8eca
commit 1da68ea69d
6 changed files with 105 additions and 41 deletions

View File

@@ -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]

View File

@@ -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.

View File

@@ -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,

View File

@@ -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(())
} }

View File

@@ -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",

View File

@@ -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(),
)) ))
} }
} }