rog-platform: add power (basics)

- Refactor the macros
- Add inotify creator for each attribute
This commit is contained in:
Luke D. Jones
2022-08-20 21:07:34 +12:00
parent 033f2141ef
commit f8cdde2adf
17 changed files with 345 additions and 187 deletions

View File

@@ -135,7 +135,7 @@ impl Default for AuraConfig {
}
if let Ok(p) = KeyboardLed::new() {
if p.has_keyboard_rgb_mode() {
if p.has_kbd_rgb_mode() {
prod_id = AuraDevice::Tuf;
}
}

View File

@@ -42,7 +42,7 @@ impl GetSupported for CtrlKbdLed {
}
if let Ok(p) = KeyboardLed::new() {
if p.has_keyboard_rgb_mode() {
if p.has_kbd_rgb_mode() {
prod_id = AuraDevice::Tuf;
}
}
@@ -199,7 +199,7 @@ impl CtrlKbdLed {
let bright_node = KeyboardLed::new();
let platform = KeyboardLed::new()?;
if led_node.is_none() && !platform.has_keyboard_rgb_mode() {
if led_node.is_none() && !platform.has_kbd_rgb_mode() {
let dmi = sysfs_class::DmiId::default();
if let Ok(prod_family) = dmi.product_family() {
if prod_family.contains("TUF") {
@@ -212,7 +212,7 @@ impl CtrlKbdLed {
let led_node = if let Some(rog) = led_node {
info!("Found ROG USB keyboard");
LEDNode::Rog(rog)
} else if platform.has_keyboard_rgb_mode() {
} else if platform.has_kbd_rgb_mode() {
info!("Found TUF keyboard");
LEDNode::KbdLed(platform)
} else {
@@ -269,7 +269,7 @@ impl CtrlKbdLed {
if let LEDNode::KbdLed(platform) = &mut self.led_node {
if let Some(pwr) = AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) {
let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8, pwr[4] as u8];
platform.set_keyboard_rgb_state(&buf)?;
platform.set_kbd_rgb_state(&buf)?;
}
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
let bytes = AuraPowerConfig::to_bytes(&self.config.enabled);
@@ -365,7 +365,7 @@ impl CtrlKbdLed {
mode.colour1.2,
mode.speed as u8,
];
platform.set_keyboard_rgb_mode(&buf)?;
platform.set_kbd_rgb_mode(&buf)?;
} else if let LEDNode::Rog(hid_raw) = &self.led_node {
let bytes: [u8; LED_MSG_LEN] = mode.into();
hid_raw.write_bytes(&bytes)?;

View File

@@ -156,6 +156,7 @@ impl crate::Reloadable for CtrlRogBios {
impl CtrlRogBios {
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
let platform = AsusPlatform::new()?;
if !platform.has_gpu_mux_mode() {
info!("G-Sync Switchable Graphics not detected");
info!("If your laptop is not a G-Sync enabled laptop then you can ignore this. Standard graphics switching will still work.");

View File

@@ -3,38 +3,38 @@ use crate::{config::Config, error::RogError, GetSupported};
use async_trait::async_trait;
use log::{info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_platform::power::AsusPower;
use rog_platform::supported::ChargeSupportedFunctions;
use smol::stream::StreamExt;
use smol::Executor;
use std::fs::OpenOptions;
use std::io::Write;
use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::dbus_interface;
use zbus::Connection;
use zbus::SignalContext;
static BAT_CHARGE_PATH0: &str = "/sys/class/power_supply/BAT0/charge_control_end_threshold";
static BAT_CHARGE_PATH1: &str = "/sys/class/power_supply/BAT1/charge_control_end_threshold";
static BAT_CHARGE_PATH2: &str = "/sys/class/power_supply/BAT2/charge_control_end_threshold";
impl GetSupported for CtrlCharge {
impl GetSupported for CtrlPower {
type A = ChargeSupportedFunctions;
fn get_supported() -> Self::A {
ChargeSupportedFunctions {
charge_level_set: CtrlCharge::get_battery_path().is_ok(),
charge_level_set: if let Ok(power) = AsusPower::new() {
power.has_charge_control_end_threshold()
} else {
false
},
}
}
}
pub struct CtrlCharge {
#[derive(Clone)]
pub struct CtrlPower {
power: AsusPower,
config: Arc<Mutex<Config>>,
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlCharge {
impl CtrlPower {
async fn set_limit(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
@@ -43,14 +43,12 @@ impl CtrlCharge {
if !(20..=100).contains(&limit) {
return Err(RogError::ChargeLimit(limit))?;
}
if let Ok(mut config) = self.config.try_lock() {
Self::set(limit, &mut config)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
self.set(limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
Self::notify_charge(&ctxt, limit).await?;
Ok(())
}
@@ -67,68 +65,51 @@ impl CtrlCharge {
}
#[async_trait]
impl crate::ZbusAdd for CtrlCharge {
impl crate::ZbusAdd for CtrlPower {
async fn add_to_server(self, server: &mut Connection) {
Self::add_to_server_helper(self, "/org/asuslinux/Charge", server).await;
}
}
impl crate::Reloadable for CtrlCharge {
impl crate::Reloadable for CtrlPower {
fn reload(&mut self) -> Result<(), RogError> {
if let Ok(mut config) = self.config.try_lock() {
config.read();
Self::set(config.bat_charge_limit, &mut config)?;
self.set(config.bat_charge_limit)?;
}
Ok(())
}
}
impl CtrlCharge {
impl CtrlPower {
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
CtrlCharge::get_battery_path()?;
Ok(CtrlCharge { config })
Ok(CtrlPower {
power: AsusPower::new()?,
config,
})
}
fn get_battery_path() -> Result<&'static str, RogError> {
if Path::new(BAT_CHARGE_PATH0).exists() {
Ok(BAT_CHARGE_PATH0)
} else if Path::new(BAT_CHARGE_PATH1).exists() {
Ok(BAT_CHARGE_PATH1)
} else if Path::new(BAT_CHARGE_PATH2).exists() {
Ok(BAT_CHARGE_PATH2)
} else {
Err(RogError::MissingFunction(
"Charge control not available, you may require a v5.8.10 series kernel or newer"
.into(),
))
}
}
pub(super) fn set(limit: u8, config: &mut Config) -> Result<(), RogError> {
pub(super) fn set(&self, limit: u8) -> Result<(), RogError> {
if !(20..=100).contains(&limit) {
return Err(RogError::ChargeLimit(limit));
}
let path = Self::get_battery_path()?;
self.power.set_charge_control_end_threshold(limit)?;
let mut file = OpenOptions::new()
.write(true)
.open(path)
.map_err(|err| RogError::Path(path.into(), err))?;
file.write_all(limit.to_string().as_bytes())
.map_err(|err| RogError::Write(path.into(), err))?;
info!("Battery charge limit: {}", limit);
config.read();
config.bat_charge_limit = limit;
config.write();
if let Ok(mut config) = self.config.try_lock() {
config.read();
config.bat_charge_limit = limit;
config.write();
}
Ok(())
}
}
#[async_trait]
impl CtrlTask for CtrlCharge {
impl CtrlTask for CtrlPower {
async fn create_tasks(&self, executor: &mut Executor) -> Result<(), RogError> {
let connection = Connection::system()
.await
@@ -138,7 +119,7 @@ impl CtrlTask for CtrlCharge {
.await
.expect("CtrlCharge could not create ManagerProxy");
let config1 = self.config.clone();
let power = self.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_sleep().await {
@@ -148,8 +129,9 @@ impl CtrlTask for CtrlCharge {
// If waking up
if !args.start {
info!("CtrlCharge reloading charge limit");
if let Ok(mut lock) = config1.try_lock() {
Self::set(lock.bat_charge_limit, &mut lock)
if let Ok(lock) = power.config.try_lock() {
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
@@ -168,7 +150,7 @@ impl CtrlTask for CtrlCharge {
.await
.expect("CtrlCharge could not create ManagerProxy");
let config = self.config.clone();
let power = self.clone();
executor
.spawn(async move {
if let Ok(notif) = manager.receive_prepare_for_shutdown().await {
@@ -178,16 +160,14 @@ impl CtrlTask for CtrlCharge {
// If waking up - intention is to catch hibernation event
if !args.start {
info!("CtrlCharge reloading charge limit");
loop {
if let Ok(mut lock) = config.clone().try_lock() {
Self::set(lock.bat_charge_limit, &mut lock)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
break;
}
if let Ok(lock) = power.config.try_lock() {
power
.set(lock.bat_charge_limit)
.map_err(|err| {
warn!("CtrlCharge: set_limit {}", err);
err
})
.ok();
}
}
}

View File

@@ -5,8 +5,8 @@ use zbus::Connection;
use zvariant::Type;
use crate::{
ctrl_anime::CtrlAnime, ctrl_aura::controller::CtrlKbdLed, ctrl_charge::CtrlCharge,
ctrl_platform::CtrlRogBios, ctrl_profiles::controller::CtrlPlatformProfile, GetSupported,
ctrl_anime::CtrlAnime, ctrl_aura::controller::CtrlKbdLed, ctrl_platform::CtrlRogBios,
ctrl_power::CtrlPower, ctrl_profiles::controller::CtrlPlatformProfile, GetSupported,
};
use rog_platform::supported::*;
@@ -41,7 +41,7 @@ impl GetSupported for SupportedFunctions {
SupportedFunctions {
anime_ctrl: CtrlAnime::get_supported(),
keyboard_led: CtrlKbdLed::get_supported(),
charge_ctrl: CtrlCharge::get_supported(),
charge_ctrl: CtrlPower::get_supported(),
platform_profile: CtrlPlatformProfile::get_supported(),
rog_bios_ctrl: CtrlRogBios::get_supported(),
}

View File

@@ -16,8 +16,8 @@ use daemon::ctrl_aura::config::AuraConfig;
use daemon::ctrl_aura::controller::{
CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus,
};
use daemon::ctrl_charge::CtrlCharge;
use daemon::ctrl_platform::CtrlRogBios;
use daemon::ctrl_power::CtrlPower;
use daemon::ctrl_profiles::config::ProfileConfig;
use daemon::{
config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported,
@@ -94,7 +94,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
}
}
match CtrlCharge::new(config.clone()) {
match CtrlPower::new(config.clone()) {
Ok(mut ctrl) => {
// Do a reload of any settings
ctrl.reload()
@@ -102,7 +102,7 @@ async fn start_daemon(executor: &mut Executor<'_>) -> Result<(), Box<dyn Error>>
// Then register to dbus server
ctrl.add_to_server(&mut connection).await;
let task = CtrlCharge::new(config)?;
let task = CtrlPower::new(config)?;
task.create_tasks(executor).await.ok();
}
Err(err) => {

View File

@@ -5,10 +5,10 @@ pub mod config;
pub mod ctrl_anime;
/// Keyboard LED brightness control, RGB, and LED display modes
pub mod ctrl_aura;
/// Control of battery charge level
pub mod ctrl_charge;
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
pub mod ctrl_platform;
/// Control of battery charge level
pub mod ctrl_power;
/// Control CPU min/max freq and turbo, fan mode, fan curves
///
/// Intel machines can control: