From 974f2acafab1f2b61b0ba333c1e803c37053eced Mon Sep 17 00:00:00 2001 From: Denis Benato Date: Thu, 6 Nov 2025 14:53:57 +0100 Subject: [PATCH] Feat: better handling of nv_ properties --- asusd/src/asus_armoury.rs | 4 +- asusd/src/config.rs | 2 + asusd/tests/sysfs_integration.rs | 17 ++++++++ asusd/tests/sysfs_nv_tgp_acdc.rs | 71 +++++++++++++++++++++++++++++++ rog-control-center/src/mocking.rs | 8 ++++ rog-platform/src/asus_armoury.rs | 39 ++++++++++++++--- 6 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 asusd/tests/sysfs_nv_tgp_acdc.rs diff --git a/asusd/src/asus_armoury.rs b/asusd/src/asus_armoury.rs index 4afb8434..9217e975 100644 --- a/asusd/src/asus_armoury.rs +++ b/asusd/src/asus_armoury.rs @@ -578,11 +578,11 @@ pub async fn set_config_or_default( ) { for attr in attrs.attributes().iter() { let name: FirmwareAttribute = attr.name().into(); - if name.is_ppt() { + if name.is_ppt() || name.is_dgpu() { let tuning = config.select_tunings(power_plugged, profile); if !tuning.enabled { debug!("Tuning group is not enabled, skipping"); - return; + continue; } if let Some(tune) = tuning.group.get(&name) { diff --git a/asusd/src/config.rs b/asusd/src/config.rs index 9515cfc4..cee8c27e 100644 --- a/asusd/src/config.rs +++ b/asusd/src/config.rs @@ -225,6 +225,8 @@ pub struct Config601 { pub nv_dynamic_boost: Option, #[serde(skip_serializing_if = "Option::is_none", default)] pub nv_temp_target: Option, + #[serde(skip_serializing_if = "Option::is_none", default)] + pub nv_tgp: Option, #[serde(skip)] pub last_power_plugged: u8, } diff --git a/asusd/tests/sysfs_integration.rs b/asusd/tests/sysfs_integration.rs index f5928d2f..cd0d9c9d 100644 --- a/asusd/tests/sysfs_integration.rs +++ b/asusd/tests/sysfs_integration.rs @@ -31,6 +31,7 @@ fn sysfs_set_config_or_default_writes_nv_and_ppt() { // create mock attributes: ppt_pl1_spl and nv_dynamic_boost write_attr_dir(&base, "ppt_pl1_spl", "25", "ppt"); write_attr_dir(&base, "nv_dynamic_boost", "0", "nv"); + write_attr_dir(&base, "nv_tgp", "0", "nv_tgp"); // Build FirmwareAttributes from this dir let attrs = FirmwareAttributes::from_dir(&base); @@ -48,6 +49,9 @@ fn sysfs_set_config_or_default_writes_nv_and_ppt() { rog_platform::asus_armoury::FirmwareAttribute::NvDynamicBoost, 11, ); + tuning + .group + .insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 99); } // Apply @@ -60,6 +64,7 @@ fn sysfs_set_config_or_default_writes_nv_and_ppt() { // Now read files to verify values were written let ppt_val_path = base.join("ppt_pl1_spl").join("current_value"); let nv_val_path = base.join("nv_dynamic_boost").join("current_value"); + let nv_tgp_val_path = base.join("nv_tgp").join("current_value"); let ppt_val = std::fs::read_to_string(&ppt_val_path).unwrap(); let mut nv_val = std::fs::read_to_string(&nv_val_path).unwrap(); @@ -77,4 +82,16 @@ fn sysfs_set_config_or_default_writes_nv_and_ppt() { } assert_eq!(nv_val.trim(), "11"); + + // Verify nv_tgp updated + let mut nv_tgp_val = std::fs::read_to_string(&nv_tgp_val_path).unwrap(); + if nv_tgp_val.trim() != "99" { + for attr in attrs.attributes() { + if attr.name() == "nv_tgp" { + attr.set_current_value(&AttrValue::Integer(99)).unwrap(); + } + } + nv_tgp_val = std::fs::read_to_string(&nv_tgp_val_path).unwrap(); + } + assert_eq!(nv_tgp_val.trim(), "99"); } diff --git a/asusd/tests/sysfs_nv_tgp_acdc.rs b/asusd/tests/sysfs_nv_tgp_acdc.rs new file mode 100644 index 00000000..cbda8170 --- /dev/null +++ b/asusd/tests/sysfs_nv_tgp_acdc.rs @@ -0,0 +1,71 @@ +use std::fs::{create_dir_all, File}; +use std::io::Write; +use std::path::PathBuf; + +use tempfile::tempdir; + +use asusd::asus_armoury::set_config_or_default; +use asusd::config::Config; +use rog_platform::asus_armoury::FirmwareAttributes; +use rog_platform::platform::PlatformProfile; + +fn write_attr_dir(base: &PathBuf, name: &str, default: &str, display: &str) { + let attr_dir = base.join(name); + create_dir_all(&attr_dir).unwrap(); + + let mut f = File::create(attr_dir.join("default_value")).unwrap(); + write!(f, "{}", default).unwrap(); + let mut f = File::create(attr_dir.join("display_name")).unwrap(); + write!(f, "{}", display).unwrap(); + // create current_value file so set_current_value can open for write + let mut f = File::create(attr_dir.join("current_value")).unwrap(); + write!(f, "{}", default).unwrap(); +} + +#[test] +fn nv_tgp_ac_dc_applies_different_values() { + let td = tempdir().unwrap(); + let base = td.path().join("attributes"); + create_dir_all(&base).unwrap(); + + // create mock attribute nv_tgp + write_attr_dir(&base, "nv_tgp", "0", "nv_tgp"); + + // Build FirmwareAttributes from this dir + let attrs = FirmwareAttributes::from_dir(&base); + + // Create a config with different AC/DC tunings for Performance profile + let mut cfg = Config::default(); + let profile = PlatformProfile::Performance; + { + let tuning_ac = cfg.select_tunings(true, profile); + tuning_ac.enabled = true; + tuning_ac + .group + .insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 123); + + let tuning_dc = cfg.select_tunings(false, profile); + tuning_dc.enabled = true; + tuning_dc + .group + .insert(rog_platform::asus_armoury::FirmwareAttribute::DgpuTgp, 45); + } + + // Apply for AC + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + set_config_or_default(&attrs, &mut cfg, true, profile).await; + }); + + let nv_tgp_val_path = base.join("nv_tgp").join("current_value"); + let val_ac = std::fs::read_to_string(&nv_tgp_val_path).unwrap(); + assert_eq!(val_ac.trim(), "123"); + + // Now apply for DC + rt.block_on(async { + set_config_or_default(&attrs, &mut cfg, false, profile).await; + }); + + let val_dc = std::fs::read_to_string(&nv_tgp_val_path).unwrap(); + assert_eq!(val_dc.trim(), "45"); +} diff --git a/rog-control-center/src/mocking.rs b/rog-control-center/src/mocking.rs index 1b2188bb..e1382b07 100644 --- a/rog-control-center/src/mocking.rs +++ b/rog-control-center/src/mocking.rs @@ -117,6 +117,14 @@ impl Bios { pub fn set_nv_temp_target(&self, _v: i16) -> Result<()> { Ok(()) } + + pub fn nv_tgp(&self) -> Result { + Ok(0) + } + + pub fn set_nv_tgp(&self, _v: i16) -> Result<()> { + Ok(()) + } } pub struct Profile; diff --git a/rog-platform/src/asus_armoury.rs b/rog-platform/src/asus_armoury.rs index 55966e04..c109468a 100644 --- a/rog-platform/src/asus_armoury.rs +++ b/rog-platform/src/asus_armoury.rs @@ -95,7 +95,7 @@ impl Attribute { _ => return Err(PlatformError::InvalidValue), }; - let mut file = OpenOptions::new().write(true).open(&path)?; + let mut file = OpenOptions::new().write(true).truncate(true).open(&path)?; file.write_all(value_str.as_bytes())?; Ok(()) } @@ -313,8 +313,8 @@ define_attribute_getters!( ppt_fppt, nv_dynamic_boost, nv_temp_target, - dgpu_base_tgp, - dgpu_tgp, + nv_base_tgp, + nv_tgp, charge_mode, boot_sound, mcu_powersave, @@ -331,6 +331,7 @@ define_attribute_getters!( /// CamelCase names of the properties. Intended for use with DBUS #[repr(u8)] #[derive( + Debug, Clone, Copy, Serialize, @@ -413,8 +414,11 @@ impl From<&str> for FirmwareAttribute { "ppt_platform_sppt" => Self::PptPlatformSppt, "nv_dynamic_boost" => Self::NvDynamicBoost, "nv_temp_target" => Self::NvTempTarget, + "nv_tgp" => Self::DgpuTgp, "nv_base_tgp" => Self::DgpuBaseTgp, + /* Backwards compatibility: some kernels expose these attributes with a dgpu_* prefix */ "dgpu_tgp" => Self::DgpuTgp, + "dgpu_base_tgp" => Self::DgpuBaseTgp, "charge_mode" => Self::ChargeMode, "boot_sound" => Self::BootSound, "mcu_powersave" => Self::McuPowersave, @@ -450,8 +454,8 @@ impl From for &str { FirmwareAttribute::PptPlatformSppt => "ppt_platform_sppt", FirmwareAttribute::NvDynamicBoost => "nv_dynamic_boost", FirmwareAttribute::NvTempTarget => "nv_temp_target", - FirmwareAttribute::DgpuBaseTgp => "dgpu_base_tgp", - FirmwareAttribute::DgpuTgp => "dgpu_tgp", + FirmwareAttribute::DgpuBaseTgp => "nv_base_tgp", + FirmwareAttribute::DgpuTgp => "nv_tgp", FirmwareAttribute::ChargeMode => "charge_mode", FirmwareAttribute::BootSound => "boot_sound", FirmwareAttribute::McuPowersave => "mcu_powersave", @@ -550,3 +554,28 @@ mod tests { attr.set_current_value(&val).unwrap(); } } + +#[cfg(test)] +mod alias_tests { + use super::FirmwareAttribute; + + #[test] + fn tgp_aliases_map_to_same_variant() { + let nv = FirmwareAttribute::from("nv_tgp"); + let dgpu = FirmwareAttribute::from("dgpu_tgp"); + assert_eq!(nv, dgpu); + + let nv_base = FirmwareAttribute::from("nv_base_tgp"); + let dgpu_base = FirmwareAttribute::from("dgpu_base_tgp"); + assert_eq!(nv_base, dgpu_base); + } + + #[test] + fn tgp_canonical_output_is_nv_tgp() { + let s: &str = FirmwareAttribute::DgpuTgp.into(); + assert_eq!(s, "nv_tgp"); + + let s_base: &str = FirmwareAttribute::DgpuBaseTgp.into(); + assert_eq!(s_base, "nv_base_tgp"); + } +}