From 1f696508e71e1c78212fe99e7e07dfa0f29c7b3c Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Sat, 18 Nov 2023 20:13:01 +1300 Subject: [PATCH] rog-platform: refactor all related parts --- CHANGELOG.md | 5 + Cargo.toml | 6 +- asusctl/src/main.rs | 2 +- asusd/src/config.rs | 62 ++-- asusd/src/ctrl_anime/trait_impls.rs | 17 ++ asusd/src/ctrl_platform.rs | 459 ++++++++++++++-------------- asusd/src/lib.rs | 13 +- rog-platform/src/platform.rs | 38 ++- rog-platform/src/supported.rs | 4 +- 9 files changed, 343 insertions(+), 263 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16886e94..3d44ea38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SetOffWhenSuspended, also add asusctl CLI option - SetOffWhenLidClosed, also add asusctl CLI option - Anime: add brightness_on_battery config option +- Platform: add `post_animation_sound`, kernel 6.7+ requires patch ### Changed - asusd: remove set_image_brightness for anime @@ -29,6 +30,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure display is off when on battery and option is set - Ensure builtin animations run instead of custom animations if option is set +### Breaking +- DBUS stuff. Again. + - Platform dbus refactored to Properties as it makes more sense than a pile of functions + ## [v4.7.2] ### Added - Support for G733PZ LED modes diff --git a/Cargo.toml b/Cargo.toml index 2692846c..c07a451d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ version = "4.7.2" [workspace.dependencies] async-trait = "^0.1" -tokio = { version = "^1.23.0", features = ["macros", "rt-multi-thread", "time", "sync"]} +tokio = { version = "^1.23.0", features = ["macros", "rt-multi-thread"]} concat-idents = "^1.1" dirs = "^4.0" smol = "^1.3" @@ -44,11 +44,11 @@ notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-f [profile.release] # thin = 57s, asusd = 9.0M # fat = 72s, asusd = 6.4M -#lto = "fat" +lto = "fat" debug = false opt-level = 3 panic = "abort" -#codegen-units = 1 +codegen-units = 1 [profile.dev] debug = true diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index 68ab2cfa..958bf98d 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -763,7 +763,7 @@ fn handle_bios_option( let usage: Vec = BiosCommand::usage().lines().map(|s| s.to_owned()).collect(); for line in usage.iter().filter(|line| { - line.contains("sound") && supported.post_sound + line.contains("sound") && supported.post_animation_sound || line.contains("GPU") && supported.gpu_mux || line.contains("panel") && supported.panel_overdrive }) { diff --git a/asusd/src/config.rs b/asusd/src/config.rs index 0635bf49..8665adf0 100644 --- a/asusd/src/config.rs +++ b/asusd/src/config.rs @@ -12,17 +12,24 @@ pub struct Config { pub disable_nvidia_powerd_on_battery: bool, pub ac_command: String, pub bat_command: String, + pub post_animation_sound: bool, + pub ppt_pl1_spl: Option, + pub ppt_pl2_sppt: Option, + pub ppt_fppt: Option, + pub ppt_apu_sppt: Option, + pub ppt_platform_sppt: Option, + pub nv_dynamic_boost: Option, + pub nv_temp_target: Option, } impl StdConfig for Config { fn new() -> Self { Config { bat_charge_limit: 100, - panel_od: false, - mini_led_mode: false, disable_nvidia_powerd_on_battery: true, ac_command: String::new(), bat_command: String::new(), + ..Default::default() } } @@ -35,7 +42,32 @@ impl StdConfig for Config { } } -impl StdConfigLoad2 for Config {} +impl StdConfigLoad2 for Config {} + +#[derive(Deserialize, Serialize, Default, Debug)] +pub struct Config472 { + /// Save charge limit for restoring on boot + pub bat_charge_limit: u8, + pub panel_od: bool, + pub mini_led_mode: bool, + pub disable_nvidia_powerd_on_battery: bool, + pub ac_command: String, + pub bat_command: String, + pub post_animation_sound: bool, +} + +impl From for Config { + fn from(c: Config472) -> Self { + Self { + bat_charge_limit: c.bat_charge_limit, + panel_od: c.panel_od, + disable_nvidia_powerd_on_battery: true, + ac_command: c.ac_command, + bat_command: c.bat_command, + ..Default::default() + } + } +} #[derive(Deserialize, Serialize)] pub struct Config462 { @@ -52,32 +84,10 @@ impl From for Config { Self { bat_charge_limit: c.bat_charge_limit, panel_od: c.panel_od, - mini_led_mode: false, disable_nvidia_powerd_on_battery: true, ac_command: String::new(), bat_command: String::new(), - } - } -} - -#[derive(Deserialize, Serialize)] -pub struct Config458 { - /// Save charge limit for restoring on boot - pub bat_charge_limit: u8, - pub panel_od: bool, - pub ac_command: String, - pub bat_command: String, -} - -impl From for Config { - fn from(c: Config458) -> Self { - Self { - bat_charge_limit: c.bat_charge_limit, - panel_od: c.panel_od, - mini_led_mode: false, - disable_nvidia_powerd_on_battery: true, - ac_command: c.ac_command, - bat_command: c.bat_command, + ..Default::default() } } } diff --git a/asusd/src/ctrl_anime/trait_impls.rs b/asusd/src/ctrl_anime/trait_impls.rs index eea7c5e9..0351c08f 100644 --- a/asusd/src/ctrl_anime/trait_impls.rs +++ b/asusd/src/ctrl_anime/trait_impls.rs @@ -382,6 +382,23 @@ impl crate::Reloadable for CtrlAnimeZbus { lock.config.display_brightness, )?; + let manager = get_logind_manager().await; + let lid_closed = manager.lid_closed().await.unwrap_or_default(); + let power_plugged = manager.on_external_power().await.unwrap_or_default(); + + let on = (lid_closed && lock.config.off_when_lid_closed) + || (power_plugged && lock.config.off_when_unplugged); + lock.node + .write_bytes(&pkt_set_enable_display(on)) + .map_err(|err| { + warn!("create_sys_event_tasks::reload {}", err); + }) + .ok(); + if !on { + // early return so we don't run animation thread + return Ok(()); + } + if !lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() { lock.node .write_bytes(&pkt_set_enable_powersave_anim(false)) diff --git a/asusd/src/ctrl_platform.rs b/asusd/src/ctrl_platform.rs index 513ed16c..a0a9fb52 100644 --- a/asusd/src/ctrl_platform.rs +++ b/asusd/src/ctrl_platform.rs @@ -1,15 +1,12 @@ -use std::fs::OpenOptions; -use std::io::{Read, Write}; -use std::path::Path; -use std::process::Command; use std::sync::Arc; use async_trait::async_trait; use config_traits::StdConfig; -use log::{info, warn}; +use log::{error, info, warn}; use rog_platform::platform::{AsusPlatform, GpuMode}; use rog_platform::supported::PlatformSupportedFunctions; use zbus::export::futures_util::lock::Mutex; +use zbus::fdo::Error as FdoErr; use zbus::{dbus_interface, Connection, SignalContext}; use crate::config::Config; @@ -17,8 +14,92 @@ use crate::error::RogError; use crate::{task_watch_item, CtrlTask, GetSupported}; const ZBUS_PATH: &str = "/org/asuslinux/Platform"; -const ASUS_POST_LOGO_SOUND: &str = - "/sys/firmware/efi/efivars/AsusPostLogoSound-607005d5-3f75-4b2e-98f0-85ba66797a3e"; + +macro_rules! platform_get_value { + ($self:ident, $property:tt, $prop_name:literal) => { + concat_idents::concat_idents!(has = has_, $property { + if $self.platform.has() { + concat_idents::concat_idents!(get = get_, $property { + $self.platform + .get() + .map_err(|err| { + warn!("CtrlRogBios: {}: {}", $prop_name, err); + FdoErr::Failed(format!("CtrlRogBios: {}: {}", $prop_name, err)) + }) + }) + } else { + error!("CtrlRogBios: {} not supported", $prop_name); + return Err(FdoErr::NotSupported(format!("CtrlRogBios: {} not supported", $prop_name))); + } + }) + } +} + +macro_rules! platform_get_value_if_some { + ($self:ident, $property:tt, $prop_name:literal, $default:expr) => { + concat_idents::concat_idents!(has = has_, $property { + if $self.platform.has() { + let lock = $self.config.lock().await; + Ok(lock.ppt_pl1_spl.unwrap_or($default)) + } else { + error!("CtrlRogBios: {} not supported", $prop_name); + return Err(FdoErr::NotSupported(format!("CtrlRogBios: {} not supported", $prop_name))); + } + }) + } +} + +macro_rules! platform_set_bool { + ($self:ident, $property:tt, $prop_name:literal, $new_value:expr) => { + concat_idents::concat_idents!(has = has_, $property { + if $self.platform.has() { + concat_idents::concat_idents!(set = set_, $property { + $self.platform.set($new_value).map_err(|err| { + error!("CtrlRogBios: {} {err}", $prop_name); + FdoErr::NotSupported(format!("CtrlRogBios: {} {err}", $prop_name)) + })?; + }); + let mut lock = $self.config.lock().await; + lock.$property = $new_value; + lock.write(); + Ok(()) + } else { + error!("CtrlRogBios: {} not supported", $prop_name); + Err(FdoErr::NotSupported(format!("CtrlRogBios: {} not supported", $prop_name))) + } + }) + } +} + +/// Intended only for setting platform object values where the value isn't +/// retained across boots +macro_rules! platform_set_with_min_max { + ($self:ident, $property:tt, $prop_name:literal, $new_value:expr, $min_value:expr, $max_value:expr) => { + if !($min_value..=$max_value).contains(&$new_value) { + Err(FdoErr::Failed( + format!("CtrlRogBios: {} value not in range {}=..={}", $prop_name, $min_value, $max_value) + )) + } else { + concat_idents::concat_idents!(has = has_, $property { + if $self.platform.has() { + concat_idents::concat_idents!(set = set_, $property { + $self.platform.set($new_value).map_err(|err| { + error!("CtrlRogBios: {} {err}", $prop_name); + FdoErr::NotSupported(format!("CtrlRogBios: {} {err}", $prop_name)) + })?; + }); + let mut lock = $self.config.lock().await; + lock.$property = Some($new_value); + lock.write(); + } else { + error!("CtrlRogBios: {} not supported", $prop_name); + return Err(FdoErr::NotSupported(format!("CtrlRogBios: {} not supported", $prop_name))); + } + }); + Ok(()) + } + } +} #[derive(Clone)] pub struct CtrlPlatform { @@ -44,25 +125,9 @@ impl CtrlPlatform { info!("Standard graphics switching will still work."); } - if Path::new(ASUS_POST_LOGO_SOUND).exists() { - CtrlPlatform::set_path_mutable(ASUS_POST_LOGO_SOUND)?; - } else { - info!("Switch for POST boot sound not detected"); - } - Ok(CtrlPlatform { platform, config }) } - fn set_path_mutable(path: &str) -> Result<(), RogError> { - let output = Command::new("/usr/bin/chattr") - .arg("-i") - .arg(path) - .output() - .map_err(|err| RogError::Path(path.into(), err))?; - info!("Set {} writeable: status: {}", path, output.status); - Ok(()) - } - fn set_gfx_mode(&self, mode: GpuMode) -> Result<(), RogError> { self.platform.set_gpu_mux_mode(mode.to_mux_attr())?; // self.update_initramfs(enable)?; @@ -73,226 +138,177 @@ impl CtrlPlatform { } Ok(()) } - - pub fn get_boot_sound() -> Result { - let data = std::fs::read(ASUS_POST_LOGO_SOUND) - .map_err(|err| RogError::Read(ASUS_POST_LOGO_SOUND.into(), err))?; - - let idx = data.len() - 1; - Ok(data[idx] as i8) - } - - pub(super) fn set_boot_sound(on: bool) -> Result<(), RogError> { - let path = ASUS_POST_LOGO_SOUND; - let mut file = OpenOptions::new() - .read(true) - .write(true) - .open(path) - .map_err(|err| RogError::Path(path.into(), err))?; - - let mut data = Vec::new(); - #[allow(clippy::verbose_file_reads)] - file.read_to_end(&mut data) - .map_err(|err| RogError::Read(path.into(), err))?; - - let idx = data.len() - 1; - if on { - data[idx] = 1; - info!("Set boot POST sound on"); - } else { - data[idx] = 0; - info!("Set boot POST sound off"); - } - file.write_all(&data) - .map_err(|err| RogError::Path(path.into(), err))?; - - Ok(()) - } - - fn set_panel_overdrive(&self, enable: bool) -> Result<(), RogError> { - self.platform.set_panel_od(enable).map_err(|err| { - warn!("CtrlRogBios: set_panel_overdrive {}", err); - err - })?; - Ok(()) - } } #[dbus_interface(name = "org.asuslinux.Daemon")] impl CtrlPlatform { - async fn set_gpu_mux_mode( - &mut self, - #[zbus(signal_context)] ctxt: SignalContext<'_>, - mode: GpuMode, - ) { - self.set_gfx_mode(mode) - .map_err(|err| { - warn!("CtrlRogBios: set_gpu_mux_mode {}", err); - err - }) - .ok(); - Self::notify_gpu_mux_mode(&ctxt, mode).await.ok(); + /// Returns a list of property names that this system supports + fn supported_properties(&self) -> Vec { + let mut supported = Vec::new(); + + macro_rules! push_name { + ($property:tt, $prop_name:literal) => { + concat_idents::concat_idents!(has = has_, $property { + if self.platform.has() { + supported.push($prop_name.to_owned()); + } + }) + } + } + + push_name!(dgpu_disable, "dgpu_disable"); + push_name!(gpu_mux_mode, "gpu_mux_mode"); + push_name!(post_animation_sound, "post_animation_sound"); + push_name!(panel_od, "panel_od"); + push_name!(mini_led_mode, "mini_led_mode"); + push_name!(egpu_enable, "egpu_enable"); + + push_name!(ppt_pl1_spl, "ppt_pl1_spl"); + push_name!(ppt_pl2_sppt, "ppt_pl2_sppt"); + push_name!(ppt_fppt, "ppt_fppt"); + push_name!(ppt_apu_sppt, "ppt_apu_sppt"); + push_name!(ppt_platform_sppt, "ppt_platform_sppt"); + push_name!(nv_dynamic_boost, "nv_dynamic_boost"); + push_name!(nv_temp_target, "nv_temp_target"); + + supported } - fn gpu_mux_mode(&self) -> GpuMode { - match self.platform.get_gpu_mux_mode() { - Ok(m) => GpuMode::from_mux(m as u8), - Err(e) => { - warn!("CtrlRogBios: get_gfx_mode {}", e); - GpuMode::Error - } + #[dbus_interface(property)] + fn gpu_mux_mode(&self) -> Result { + self.platform.get_gpu_mux_mode().map_err(|err| { + warn!("CtrlRogBios: set_gpu_mux_mode {err}"); + FdoErr::NotSupported("CtrlRogBios: set_gpu_mux_mode not supported".to_owned()) + }) + } + + #[dbus_interface(property)] + async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> { + if self.platform.has_gpu_mux_mode() { + self.set_gfx_mode(mode.into()).map_err(|err| { + warn!("CtrlRogBios: set_gpu_mux_mode {}", err); + FdoErr::Failed(format!("CtrlRogBios: set_gpu_mux_mode: {err}")) + }) + } else { + Err(FdoErr::NotSupported( + "CtrlRogBios: set_gpu_mux_mode not supported".to_owned(), + )) } } - #[dbus_interface(signal)] - async fn notify_gpu_mux_mode( - signal_ctxt: &SignalContext<'_>, - mode: GpuMode, - ) -> zbus::Result<()> { + #[dbus_interface(property)] + fn post_animation_sound(&self) -> Result { + platform_get_value!(self, post_animation_sound, "post_animation_sound") } - async fn set_post_boot_sound( - &mut self, - #[zbus(signal_context)] ctxt: SignalContext<'_>, - on: bool, - ) { - Self::set_boot_sound(on) - .map_err(|err| { - warn!("CtrlRogBios: set_post_boot_sound {}", err); - err - }) - .ok(); - Self::notify_post_boot_sound(&ctxt, on) - .await - .map_err(|err| { - warn!("CtrlRogBios: set_post_boot_sound {}", err); - err - }) - .ok(); - } - - fn post_boot_sound(&self) -> i8 { - Self::get_boot_sound() - .map_err(|err| { - warn!("CtrlRogBios: get_boot_sound {}", err); - err - }) - .unwrap_or(-1) - } - - #[dbus_interface(signal)] - async fn notify_post_boot_sound(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {} - - async fn set_panel_od(&mut self, overdrive: bool) { - match self.platform.set_panel_od(overdrive) { - Ok(_) => { - if let Some(mut lock) = self.config.try_lock() { - lock.panel_od = overdrive; - lock.write(); - } - } - Err(err) => warn!("CtrlRogBios: set_panel_overdrive {}", err), - }; + #[dbus_interface(property)] + async fn set_post_animation_sound(&mut self, on: bool) -> Result<(), FdoErr> { + platform_set_bool!(self, post_animation_sound, "post_animation_sound", on) } /// Get the `panel_od` value from platform. Updates the stored value in /// internal config also. - fn panel_od(&self) -> bool { - self.platform - .get_panel_od() - .map_err(|err| { - warn!("CtrlRogBios: get_panel_od {}", err); - err - }) - .unwrap_or(false) + #[dbus_interface(property)] + fn panel_od(&self) -> Result { + platform_get_value!(self, panel_od, "panel_od") } - #[dbus_interface(signal)] - async fn notify_panel_od(signal_ctxt: &SignalContext<'_>, overdrive: bool) -> zbus::Result<()> { - } - - async fn set_mini_led_mode(&mut self, on: bool) { - match self.platform.set_mini_led_mode(on) { - Ok(_) => { - if let Some(mut lock) = self.config.try_lock() { - lock.mini_led_mode = on; - lock.write(); - } - } - Err(err) => warn!("CtrlRogBios: set_mini_led_mode {}", err), - }; + #[dbus_interface(property)] + async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> { + platform_set_bool!(self, panel_od, "panel_od", overdrive) } /// Get the `panel_od` value from platform. Updates the stored value in /// internal config also. - fn mini_led_mode(&self) -> bool { - self.platform - .get_mini_led_mode() - .map_err(|err| { - warn!("CtrlRogBios: get_mini_led_mode {}", err); - err - }) - .unwrap_or(false) + #[dbus_interface(property)] + fn mini_led_mode(&self) -> Result { + platform_get_value!(self, mini_led_mode, "mini_led_mode") } - #[dbus_interface(signal)] - async fn notify_mini_led_mode(signal_ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {} - - async fn set_dgpu_disable( - &mut self, - #[zbus(signal_context)] ctxt: SignalContext<'_>, - disable: bool, - ) { - match self.platform.set_dgpu_disable(disable) { - Ok(_) => { - Self::notify_dgpu_disable(&ctxt, disable).await.ok(); - } - Err(err) => warn!("CtrlRogBios: set_dgpu_disable {}", err), - }; + #[dbus_interface(property)] + async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> { + platform_set_bool!(self, mini_led_mode, "mini_led_mode", on) } - fn dgpu_disable(&self) -> bool { - self.platform - .get_dgpu_disable() - .map_err(|err| { - warn!("CtrlRogBios: get_dgpu_disable {}", err); - err - }) - .unwrap_or(false) + #[dbus_interface(property)] + fn dgpu_disable(&self) -> Result { + platform_get_value!(self, dgpu_disable, "dgpu_disable") } - #[dbus_interface(signal)] - async fn notify_dgpu_disable( - signal_ctxt: &SignalContext<'_>, - disable: bool, - ) -> zbus::Result<()> { + #[dbus_interface(property)] + fn egpu_enable(&self) -> Result { + platform_get_value!(self, egpu_enable, "egpu_enable") } - async fn set_egpu_enable( - &mut self, - #[zbus(signal_context)] ctxt: SignalContext<'_>, - enable: bool, - ) { - match self.platform.set_egpu_enable(enable) { - Ok(_) => { - Self::notify_egpu_enable(&ctxt, enable).await.ok(); - } - Err(err) => warn!("CtrlRogBios: set_egpu_enable {}", err), - }; + /// *************************************************************************** + #[dbus_interface(property)] + async fn ppt_pl1_spl(&self) -> Result { + platform_get_value_if_some!(self, ppt_pl1_spl, "ppt_pl1_spl", 5) } - fn egpu_enable(&self) -> bool { - self.platform - .get_egpu_enable() - .map_err(|err| { - warn!("CtrlRogBios: get_egpu_enable {}", err); - err - }) - .unwrap_or(false) + #[dbus_interface(property)] + async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250) } - #[dbus_interface(signal)] - async fn notify_egpu_enable(signal_ctxt: &SignalContext<'_>, enable: bool) -> zbus::Result<()> { + #[dbus_interface(property)] + async fn ppt_pl2_sppt(&self) -> Result { + platform_get_value_if_some!(self, ppt_pl2_sppt, "ppt_pl2_sppt", 5) + } + + #[dbus_interface(property)] + async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250) + } + + #[dbus_interface(property)] + async fn ppt_fppt(&self) -> Result { + platform_get_value_if_some!(self, ppt_fppt, "ppt_fppt", 5) + } + + #[dbus_interface(property)] + async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250) + } + + #[dbus_interface(property)] + async fn ppt_apu_sppt(&self) -> Result { + platform_get_value_if_some!(self, ppt_apu_sppt, "ppt_apu_sppt", 5) + } + + #[dbus_interface(property)] + async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130) + } + + #[dbus_interface(property)] + async fn ppt_platform_sppt(&self) -> Result { + platform_get_value_if_some!(self, ppt_platform_sppt, "ppt_platform_sppt", 5) + } + + #[dbus_interface(property)] + async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130) + } + + #[dbus_interface(property)] + async fn nv_dynamic_boost(&self) -> Result { + platform_get_value_if_some!(self, nv_dynamic_boost, "nv_dynamic_boost", 5) + } + + #[dbus_interface(property)] + async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25) + } + + #[dbus_interface(property)] + async fn nv_temp_target(&self) -> Result { + platform_get_value_if_some!(self, nv_temp_target, "nv_temp_target", 5) + } + + #[dbus_interface(property)] + async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> { + platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87) } } @@ -312,7 +328,7 @@ impl crate::Reloadable for CtrlPlatform { } else { false }; - self.set_panel_overdrive(p)?; + self.platform.set_panel_od(p)?; } Ok(()) } @@ -320,12 +336,9 @@ impl crate::Reloadable for CtrlPlatform { impl CtrlPlatform { task_watch_item!(panel_od platform); - - task_watch_item!(dgpu_disable platform); - - task_watch_item!(egpu_enable platform); - - task_watch_item!(mini_led_mode platform); + // task_watch_item!(dgpu_disable platform); + // task_watch_item!(egpu_enable platform); + // task_watch_item!(mini_led_mode platform); // NOTE: see note further below // task_watch_item!(gpu_mux_mode platform); } @@ -347,7 +360,8 @@ impl CtrlTask for CtrlPlatform { let lock = platform1.config.lock().await; if !sleeping && platform1.platform.has_panel_od() { platform1 - .set_panel_overdrive(lock.panel_od) + .platform + .set_panel_od(lock.panel_od) .map_err(|err| { warn!("CtrlCharge: panel_od {}", err); err @@ -363,7 +377,8 @@ impl CtrlTask for CtrlPlatform { let lock = platform2.config.lock().await; if !shutting_down && platform2.platform.has_panel_od() { platform2 - .set_panel_overdrive(lock.panel_od) + .platform + .set_panel_od(lock.panel_od) .map_err(|err| { warn!("CtrlCharge: panel_od {}", err); err @@ -384,9 +399,9 @@ impl CtrlTask for CtrlPlatform { .await; self.watch_panel_od(signal_ctxt.clone()).await?; - self.watch_dgpu_disable(signal_ctxt.clone()).await?; - self.watch_egpu_enable(signal_ctxt.clone()).await?; - self.watch_mini_led_mode(signal_ctxt.clone()).await?; + // self.watch_dgpu_disable(signal_ctxt.clone()).await?; + // self.watch_egpu_enable(signal_ctxt.clone()).await?; + // self.watch_mini_led_mode(signal_ctxt.clone()).await?; // NOTE: Can't have this as a watch because on a write to it, it reverts back to // booted-with value as it does not actually change until reboot. // self.watch_gpu_mux_mode(signal_ctxt.clone()).await?; diff --git a/asusd/src/lib.rs b/asusd/src/lib.rs index 88a69344..f1387a96 100644 --- a/asusd/src/lib.rs +++ b/asusd/src/lib.rs @@ -72,10 +72,15 @@ macro_rules! task_watch_item { tokio::spawn(async move { let mut buffer = [0; 32]; watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async { - let value = ctrl.$name(); - concat_idents::concat_idents!(notif_fn = notify_, $name { - Self::notif_fn(&signal_ctxt, value).await.ok(); - }); + if let Ok(value) = ctrl.$name(){ + concat_idents::concat_idents!(notif_fn = $name, _changed { + Self::notif_fn(&ctrl, &signal_ctxt).await.ok(); + }); + if let Some(mut lock) = ctrl.config.try_lock() { + lock.$name = value; + lock.write(); + } + } }).await; }); } diff --git a/rog-platform/src/platform.rs b/rog-platform/src/platform.rs index cf525433..1ca9550b 100644 --- a/rog-platform/src/platform.rs +++ b/rog-platform/src/platform.rs @@ -34,7 +34,7 @@ impl AsusPlatform { attr_bool!("mini_led_mode", path); - attr_bool!("gpu_mux_mode", path); + attr_u8!("gpu_mux_mode", path); attr_u8!( /// This is technically the same as `platform_profile` since both are @@ -100,6 +100,12 @@ impl AsusPlatform { path ); + attr_bool!( + /// Control the POST animation "FWOOoosh" sound + "post_animation_sound", + path + ); + pub fn new() -> Result { let mut enumerator = udev::Enumerator::new().map_err(|err| { warn!("{}", err); @@ -146,7 +152,7 @@ impl Default for AsusPlatform { impl From for PlatformSupportedFunctions { fn from(a: AsusPlatform) -> Self { PlatformSupportedFunctions { - post_sound: false, + post_animation_sound: a.has_post_animation_sound(), gpu_mux: a.has_gpu_mux_mode(), panel_overdrive: a.has_panel_od(), dgpu_disable: a.has_dgpu_disable(), @@ -164,6 +170,7 @@ impl From for PlatformSupportedFunctions { } #[typeshare] +#[repr(u8)] #[derive(Serialize, Deserialize, Default, Type, Debug, PartialEq, Eq, Clone, Copy)] pub enum GpuMode { Discrete, @@ -177,13 +184,34 @@ pub enum GpuMode { NotSupported, } +impl From for GpuMode { + fn from(v: u8) -> Self { + match v { + 0 => GpuMode::Discrete, + 1 => GpuMode::Optimus, + 2 => GpuMode::Integrated, + 3 => GpuMode::Egpu, + 4 => GpuMode::Vfio, + 5 => GpuMode::Ultimate, + 6 => GpuMode::Error, + _ => GpuMode::NotSupported, + } + } +} + +impl From for u8 { + fn from(v: GpuMode) -> Self { + v as u8 + } +} + impl GpuMode { /// For writing to `gpu_mux_mode` attribute - pub fn to_mux_attr(&self) -> bool { + pub fn to_mux_attr(&self) -> u8 { if *self == Self::Discrete { - return false; + return 0; } - true + 1 } pub fn to_dgpu_attr(&self) -> u8 { diff --git a/rog-platform/src/supported.rs b/rog-platform/src/supported.rs index 0e205de4..49015b18 100644 --- a/rog-platform/src/supported.rs +++ b/rog-platform/src/supported.rs @@ -69,7 +69,7 @@ pub struct LedSupportedFunctions { #[typeshare] #[derive(Serialize, Deserialize, Type, Debug, Default, Clone)] pub struct PlatformSupportedFunctions { - pub post_sound: bool, + pub post_animation_sound: bool, pub gpu_mux: bool, pub panel_overdrive: bool, pub dgpu_disable: bool, @@ -132,7 +132,7 @@ impl fmt::Display for LedSupportedFunctions { impl fmt::Display for PlatformSupportedFunctions { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "ROG BIOS:")?; - writeln!(f, "\tPOST sound switch: {}", self.post_sound)?; + writeln!(f, "\tPOST sound switch: {}", self.post_animation_sound)?; writeln!(f, "\tPanel Overdrive: {}", self.panel_overdrive)?; writeln!(f, "\tMiniLED backlight: {}", self.mini_led_mode)?; writeln!(f, "\tdGPU disable switch: {}", self.dgpu_disable)?;