rog-platform: refactor all related parts

This commit is contained in:
Luke D. Jones
2023-11-18 20:13:01 +13:00
parent fa043adc99
commit 1f696508e7
9 changed files with 343 additions and 263 deletions

View File

@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- SetOffWhenSuspended, also add asusctl CLI option - SetOffWhenSuspended, also add asusctl CLI option
- SetOffWhenLidClosed, also add asusctl CLI option - SetOffWhenLidClosed, also add asusctl CLI option
- Anime: add brightness_on_battery config option - Anime: add brightness_on_battery config option
- Platform: add `post_animation_sound`, kernel 6.7+ requires patch
### Changed ### Changed
- asusd: remove set_image_brightness for anime - 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 display is off when on battery and option is set
- Ensure builtin animations run instead of custom animations if 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] ## [v4.7.2]
### Added ### Added
- Support for G733PZ LED modes - Support for G733PZ LED modes

View File

@@ -8,7 +8,7 @@ version = "4.7.2"
[workspace.dependencies] [workspace.dependencies]
async-trait = "^0.1" 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" concat-idents = "^1.1"
dirs = "^4.0" dirs = "^4.0"
smol = "^1.3" smol = "^1.3"
@@ -44,11 +44,11 @@ notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-f
[profile.release] [profile.release]
# thin = 57s, asusd = 9.0M # thin = 57s, asusd = 9.0M
# fat = 72s, asusd = 6.4M # fat = 72s, asusd = 6.4M
#lto = "fat" lto = "fat"
debug = false debug = false
opt-level = 3 opt-level = 3
panic = "abort" panic = "abort"
#codegen-units = 1 codegen-units = 1
[profile.dev] [profile.dev]
debug = true debug = true

View File

@@ -763,7 +763,7 @@ fn handle_bios_option(
let usage: Vec<String> = BiosCommand::usage().lines().map(|s| s.to_owned()).collect(); let usage: Vec<String> = BiosCommand::usage().lines().map(|s| s.to_owned()).collect();
for line in usage.iter().filter(|line| { 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("GPU") && supported.gpu_mux
|| line.contains("panel") && supported.panel_overdrive || line.contains("panel") && supported.panel_overdrive
}) { }) {

View File

@@ -12,17 +12,24 @@ pub struct Config {
pub disable_nvidia_powerd_on_battery: bool, pub disable_nvidia_powerd_on_battery: bool,
pub ac_command: String, pub ac_command: String,
pub bat_command: String, pub bat_command: String,
pub post_animation_sound: bool,
pub ppt_pl1_spl: Option<u8>,
pub ppt_pl2_sppt: Option<u8>,
pub ppt_fppt: Option<u8>,
pub ppt_apu_sppt: Option<u8>,
pub ppt_platform_sppt: Option<u8>,
pub nv_dynamic_boost: Option<u8>,
pub nv_temp_target: Option<u8>,
} }
impl StdConfig for Config { impl StdConfig for Config {
fn new() -> Self { fn new() -> Self {
Config { Config {
bat_charge_limit: 100, bat_charge_limit: 100,
panel_od: false,
mini_led_mode: false,
disable_nvidia_powerd_on_battery: true, disable_nvidia_powerd_on_battery: true,
ac_command: String::new(), ac_command: String::new(),
bat_command: String::new(), bat_command: String::new(),
..Default::default()
} }
} }
@@ -35,7 +42,32 @@ impl StdConfig for Config {
} }
} }
impl StdConfigLoad2<Config458, Config462> for Config {} impl StdConfigLoad2<Config462, Config472> 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<Config472> 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)] #[derive(Deserialize, Serialize)]
pub struct Config462 { pub struct Config462 {
@@ -52,32 +84,10 @@ impl From<Config462> for Config {
Self { Self {
bat_charge_limit: c.bat_charge_limit, bat_charge_limit: c.bat_charge_limit,
panel_od: c.panel_od, panel_od: c.panel_od,
mini_led_mode: false,
disable_nvidia_powerd_on_battery: true, disable_nvidia_powerd_on_battery: true,
ac_command: String::new(), ac_command: String::new(),
bat_command: String::new(), bat_command: String::new(),
} ..Default::default()
}
}
#[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<Config458> 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,
} }
} }
} }

View File

@@ -382,6 +382,23 @@ impl crate::Reloadable for CtrlAnimeZbus {
lock.config.display_brightness, 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() { if !lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
lock.node lock.node
.write_bytes(&pkt_set_enable_powersave_anim(false)) .write_bytes(&pkt_set_enable_powersave_anim(false))

View File

@@ -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 std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use config_traits::StdConfig; use config_traits::StdConfig;
use log::{info, warn}; use log::{error, info, warn};
use rog_platform::platform::{AsusPlatform, GpuMode}; use rog_platform::platform::{AsusPlatform, GpuMode};
use rog_platform::supported::PlatformSupportedFunctions; use rog_platform::supported::PlatformSupportedFunctions;
use zbus::export::futures_util::lock::Mutex; use zbus::export::futures_util::lock::Mutex;
use zbus::fdo::Error as FdoErr;
use zbus::{dbus_interface, Connection, SignalContext}; use zbus::{dbus_interface, Connection, SignalContext};
use crate::config::Config; use crate::config::Config;
@@ -17,8 +14,92 @@ use crate::error::RogError;
use crate::{task_watch_item, CtrlTask, GetSupported}; use crate::{task_watch_item, CtrlTask, GetSupported};
const ZBUS_PATH: &str = "/org/asuslinux/Platform"; 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)] #[derive(Clone)]
pub struct CtrlPlatform { pub struct CtrlPlatform {
@@ -44,25 +125,9 @@ impl CtrlPlatform {
info!("Standard graphics switching will still work."); 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 }) 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> { fn set_gfx_mode(&self, mode: GpuMode) -> Result<(), RogError> {
self.platform.set_gpu_mux_mode(mode.to_mux_attr())?; self.platform.set_gpu_mux_mode(mode.to_mux_attr())?;
// self.update_initramfs(enable)?; // self.update_initramfs(enable)?;
@@ -73,226 +138,177 @@ impl CtrlPlatform {
} }
Ok(()) Ok(())
} }
pub fn get_boot_sound() -> Result<i8, RogError> {
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")] #[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlPlatform { impl CtrlPlatform {
async fn set_gpu_mux_mode( /// Returns a list of property names that this system supports
&mut self, fn supported_properties(&self) -> Vec<String> {
#[zbus(signal_context)] ctxt: SignalContext<'_>, let mut supported = Vec::new();
mode: GpuMode,
) { macro_rules! push_name {
self.set_gfx_mode(mode) ($property:tt, $prop_name:literal) => {
.map_err(|err| { concat_idents::concat_idents!(has = has_, $property {
warn!("CtrlRogBios: set_gpu_mux_mode {}", err); if self.platform.has() {
err supported.push($prop_name.to_owned());
}) }
.ok(); })
Self::notify_gpu_mux_mode(&ctxt, mode).await.ok(); }
}
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 { #[dbus_interface(property)]
match self.platform.get_gpu_mux_mode() { fn gpu_mux_mode(&self) -> Result<u8, FdoErr> {
Ok(m) => GpuMode::from_mux(m as u8), self.platform.get_gpu_mux_mode().map_err(|err| {
Err(e) => { warn!("CtrlRogBios: set_gpu_mux_mode {err}");
warn!("CtrlRogBios: get_gfx_mode {}", e); FdoErr::NotSupported("CtrlRogBios: set_gpu_mux_mode not supported".to_owned())
GpuMode::Error })
} }
#[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)] #[dbus_interface(property)]
async fn notify_gpu_mux_mode( fn post_animation_sound(&self) -> Result<bool, FdoErr> {
signal_ctxt: &SignalContext<'_>, platform_get_value!(self, post_animation_sound, "post_animation_sound")
mode: GpuMode,
) -> zbus::Result<()> {
} }
async fn set_post_boot_sound( #[dbus_interface(property)]
&mut self, async fn set_post_animation_sound(&mut self, on: bool) -> Result<(), FdoErr> {
#[zbus(signal_context)] ctxt: SignalContext<'_>, platform_set_bool!(self, post_animation_sound, "post_animation_sound", on)
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),
};
} }
/// Get the `panel_od` value from platform. Updates the stored value in /// Get the `panel_od` value from platform. Updates the stored value in
/// internal config also. /// internal config also.
fn panel_od(&self) -> bool { #[dbus_interface(property)]
self.platform fn panel_od(&self) -> Result<bool, FdoErr> {
.get_panel_od() platform_get_value!(self, panel_od, "panel_od")
.map_err(|err| {
warn!("CtrlRogBios: get_panel_od {}", err);
err
})
.unwrap_or(false)
} }
#[dbus_interface(signal)] #[dbus_interface(property)]
async fn notify_panel_od(signal_ctxt: &SignalContext<'_>, overdrive: bool) -> zbus::Result<()> { async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
} platform_set_bool!(self, panel_od, "panel_od", overdrive)
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),
};
} }
/// Get the `panel_od` value from platform. Updates the stored value in /// Get the `panel_od` value from platform. Updates the stored value in
/// internal config also. /// internal config also.
fn mini_led_mode(&self) -> bool { #[dbus_interface(property)]
self.platform fn mini_led_mode(&self) -> Result<bool, FdoErr> {
.get_mini_led_mode() platform_get_value!(self, mini_led_mode, "mini_led_mode")
.map_err(|err| {
warn!("CtrlRogBios: get_mini_led_mode {}", err);
err
})
.unwrap_or(false)
} }
#[dbus_interface(signal)] #[dbus_interface(property)]
async fn notify_mini_led_mode(signal_ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {} async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
platform_set_bool!(self, mini_led_mode, "mini_led_mode", on)
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),
};
} }
fn dgpu_disable(&self) -> bool { #[dbus_interface(property)]
self.platform fn dgpu_disable(&self) -> Result<bool, FdoErr> {
.get_dgpu_disable() platform_get_value!(self, dgpu_disable, "dgpu_disable")
.map_err(|err| {
warn!("CtrlRogBios: get_dgpu_disable {}", err);
err
})
.unwrap_or(false)
} }
#[dbus_interface(signal)] #[dbus_interface(property)]
async fn notify_dgpu_disable( fn egpu_enable(&self) -> Result<bool, FdoErr> {
signal_ctxt: &SignalContext<'_>, platform_get_value!(self, egpu_enable, "egpu_enable")
disable: bool,
) -> zbus::Result<()> {
} }
async fn set_egpu_enable( /// ***************************************************************************
&mut self, #[dbus_interface(property)]
#[zbus(signal_context)] ctxt: SignalContext<'_>, async fn ppt_pl1_spl(&self) -> Result<u8, FdoErr> {
enable: bool, platform_get_value_if_some!(self, ppt_pl1_spl, "ppt_pl1_spl", 5)
) {
match self.platform.set_egpu_enable(enable) {
Ok(_) => {
Self::notify_egpu_enable(&ctxt, enable).await.ok();
}
Err(err) => warn!("CtrlRogBios: set_egpu_enable {}", err),
};
} }
fn egpu_enable(&self) -> bool { #[dbus_interface(property)]
self.platform async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
.get_egpu_enable() platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250)
.map_err(|err| {
warn!("CtrlRogBios: get_egpu_enable {}", err);
err
})
.unwrap_or(false)
} }
#[dbus_interface(signal)] #[dbus_interface(property)]
async fn notify_egpu_enable(signal_ctxt: &SignalContext<'_>, enable: bool) -> zbus::Result<()> { async fn ppt_pl2_sppt(&self) -> Result<u8, FdoErr> {
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<u8, FdoErr> {
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<u8, FdoErr> {
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<u8, FdoErr> {
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<u8, FdoErr> {
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<u8, FdoErr> {
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 { } else {
false false
}; };
self.set_panel_overdrive(p)?; self.platform.set_panel_od(p)?;
} }
Ok(()) Ok(())
} }
@@ -320,12 +336,9 @@ impl crate::Reloadable for CtrlPlatform {
impl CtrlPlatform { impl CtrlPlatform {
task_watch_item!(panel_od platform); task_watch_item!(panel_od platform);
// task_watch_item!(dgpu_disable platform);
task_watch_item!(dgpu_disable platform); // task_watch_item!(egpu_enable platform);
// task_watch_item!(mini_led_mode platform);
task_watch_item!(egpu_enable platform);
task_watch_item!(mini_led_mode platform);
// NOTE: see note further below // NOTE: see note further below
// task_watch_item!(gpu_mux_mode platform); // task_watch_item!(gpu_mux_mode platform);
} }
@@ -347,7 +360,8 @@ impl CtrlTask for CtrlPlatform {
let lock = platform1.config.lock().await; let lock = platform1.config.lock().await;
if !sleeping && platform1.platform.has_panel_od() { if !sleeping && platform1.platform.has_panel_od() {
platform1 platform1
.set_panel_overdrive(lock.panel_od) .platform
.set_panel_od(lock.panel_od)
.map_err(|err| { .map_err(|err| {
warn!("CtrlCharge: panel_od {}", err); warn!("CtrlCharge: panel_od {}", err);
err err
@@ -363,7 +377,8 @@ impl CtrlTask for CtrlPlatform {
let lock = platform2.config.lock().await; let lock = platform2.config.lock().await;
if !shutting_down && platform2.platform.has_panel_od() { if !shutting_down && platform2.platform.has_panel_od() {
platform2 platform2
.set_panel_overdrive(lock.panel_od) .platform
.set_panel_od(lock.panel_od)
.map_err(|err| { .map_err(|err| {
warn!("CtrlCharge: panel_od {}", err); warn!("CtrlCharge: panel_od {}", err);
err err
@@ -384,9 +399,9 @@ impl CtrlTask for CtrlPlatform {
.await; .await;
self.watch_panel_od(signal_ctxt.clone()).await?; self.watch_panel_od(signal_ctxt.clone()).await?;
self.watch_dgpu_disable(signal_ctxt.clone()).await?; // self.watch_dgpu_disable(signal_ctxt.clone()).await?;
self.watch_egpu_enable(signal_ctxt.clone()).await?; // self.watch_egpu_enable(signal_ctxt.clone()).await?;
self.watch_mini_led_mode(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 // 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. // booted-with value as it does not actually change until reboot.
// self.watch_gpu_mux_mode(signal_ctxt.clone()).await?; // self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;

View File

@@ -72,10 +72,15 @@ macro_rules! task_watch_item {
tokio::spawn(async move { tokio::spawn(async move {
let mut buffer = [0; 32]; let mut buffer = [0; 32];
watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async { watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async {
let value = ctrl.$name(); if let Ok(value) = ctrl.$name(){
concat_idents::concat_idents!(notif_fn = notify_, $name { concat_idents::concat_idents!(notif_fn = $name, _changed {
Self::notif_fn(&signal_ctxt, value).await.ok(); Self::notif_fn(&ctrl, &signal_ctxt).await.ok();
}); });
if let Some(mut lock) = ctrl.config.try_lock() {
lock.$name = value;
lock.write();
}
}
}).await; }).await;
}); });
} }

View File

@@ -34,7 +34,7 @@ impl AsusPlatform {
attr_bool!("mini_led_mode", path); attr_bool!("mini_led_mode", path);
attr_bool!("gpu_mux_mode", path); attr_u8!("gpu_mux_mode", path);
attr_u8!( attr_u8!(
/// This is technically the same as `platform_profile` since both are /// This is technically the same as `platform_profile` since both are
@@ -100,6 +100,12 @@ impl AsusPlatform {
path path
); );
attr_bool!(
/// Control the POST animation "FWOOoosh" sound
"post_animation_sound",
path
);
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
let mut enumerator = udev::Enumerator::new().map_err(|err| { let mut enumerator = udev::Enumerator::new().map_err(|err| {
warn!("{}", err); warn!("{}", err);
@@ -146,7 +152,7 @@ impl Default for AsusPlatform {
impl From<AsusPlatform> for PlatformSupportedFunctions { impl From<AsusPlatform> for PlatformSupportedFunctions {
fn from(a: AsusPlatform) -> Self { fn from(a: AsusPlatform) -> Self {
PlatformSupportedFunctions { PlatformSupportedFunctions {
post_sound: false, post_animation_sound: a.has_post_animation_sound(),
gpu_mux: a.has_gpu_mux_mode(), gpu_mux: a.has_gpu_mux_mode(),
panel_overdrive: a.has_panel_od(), panel_overdrive: a.has_panel_od(),
dgpu_disable: a.has_dgpu_disable(), dgpu_disable: a.has_dgpu_disable(),
@@ -164,6 +170,7 @@ impl From<AsusPlatform> for PlatformSupportedFunctions {
} }
#[typeshare] #[typeshare]
#[repr(u8)]
#[derive(Serialize, Deserialize, Default, Type, Debug, PartialEq, Eq, Clone, Copy)] #[derive(Serialize, Deserialize, Default, Type, Debug, PartialEq, Eq, Clone, Copy)]
pub enum GpuMode { pub enum GpuMode {
Discrete, Discrete,
@@ -177,13 +184,34 @@ pub enum GpuMode {
NotSupported, NotSupported,
} }
impl From<u8> 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<GpuMode> for u8 {
fn from(v: GpuMode) -> Self {
v as u8
}
}
impl GpuMode { impl GpuMode {
/// For writing to `gpu_mux_mode` attribute /// 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 { if *self == Self::Discrete {
return false; return 0;
} }
true 1
} }
pub fn to_dgpu_attr(&self) -> u8 { pub fn to_dgpu_attr(&self) -> u8 {

View File

@@ -69,7 +69,7 @@ pub struct LedSupportedFunctions {
#[typeshare] #[typeshare]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)] #[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct PlatformSupportedFunctions { pub struct PlatformSupportedFunctions {
pub post_sound: bool, pub post_animation_sound: bool,
pub gpu_mux: bool, pub gpu_mux: bool,
pub panel_overdrive: bool, pub panel_overdrive: bool,
pub dgpu_disable: bool, pub dgpu_disable: bool,
@@ -132,7 +132,7 @@ impl fmt::Display for LedSupportedFunctions {
impl fmt::Display for PlatformSupportedFunctions { impl fmt::Display for PlatformSupportedFunctions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "ROG BIOS:")?; 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, "\tPanel Overdrive: {}", self.panel_overdrive)?;
writeln!(f, "\tMiniLED backlight: {}", self.mini_led_mode)?; writeln!(f, "\tMiniLED backlight: {}", self.mini_led_mode)?;
writeln!(f, "\tdGPU disable switch: {}", self.dgpu_disable)?; writeln!(f, "\tdGPU disable switch: {}", self.dgpu_disable)?;