diff --git a/asusd/src/ctrl_platform.rs b/asusd/src/ctrl_platform.rs index de737f5e..e507ab58 100644 --- a/asusd/src/ctrl_platform.rs +++ b/asusd/src/ctrl_platform.rs @@ -264,25 +264,32 @@ impl CtrlPlatform { self.config.lock().await.platform_profile_on_battery }; - // Older configs may still contain Quiet on devices that only support LowPower. + // Configs may contain a profile name (Quiet or LowPower) that this + // platform does not expose via the kernel ACPI sysfs — different ASUS + // platforms expose one or the other for the same semantic profile. // Normalize at apply-time so AC/BAT transitions still work correctly. - if configured == PlatformProfile::Quiet { + let alias = match configured { + PlatformProfile::Quiet => Some(PlatformProfile::LowPower), + PlatformProfile::LowPower => Some(PlatformProfile::Quiet), + _ => None, + }; + if let Some(target) = alias { if let Ok(choices) = self.platform.get_platform_profile_choices() { - if !choices.contains(&PlatformProfile::Quiet) - && choices.contains(&PlatformProfile::LowPower) - { + if !choices.contains(&configured) && choices.contains(&target) { let mut cfg = self.config.lock().await; if power_plugged { - cfg.platform_profile_on_ac = PlatformProfile::LowPower; + cfg.platform_profile_on_ac = target; } else { - cfg.platform_profile_on_battery = PlatformProfile::LowPower; + cfg.platform_profile_on_battery = target; } cfg.write(); warn!( - "Configured profile Quiet is unavailable, falling back to LowPower for {}", + "Configured profile {:?} is unavailable, falling back to {:?} for {}", + configured, + target, if power_plugged { "AC" } else { "battery" } ); - return PlatformProfile::LowPower; + return target; } } } @@ -480,12 +487,36 @@ impl CtrlPlatform { self.config.lock().await.write(); let choices = self.platform.get_platform_profile_choices()?; - if !choices.contains(&policy) { - return Err(FdoErr::NotSupported(format!( - "RogPlatform: platform_profile: {} not supported", - policy - ))); - } + // Different ASUS platforms expose only one of Quiet / LowPower + // via the kernel ACPI platform_profile sysfs for the same + // semantic profile. Map the requested variant to the available + // one so user-facing setters succeed regardless of which name + // the kernel reports on this machine. Same bidirectional + // fallback is applied in set_platform_profile_on_battery / + // set_platform_profile_on_ac and at apply-time in + // select_power_profile_for_source. + let policy = if !choices.contains(&policy) { + match policy { + PlatformProfile::Quiet + if choices.contains(&PlatformProfile::LowPower) => + { + PlatformProfile::LowPower + } + PlatformProfile::LowPower + if choices.contains(&PlatformProfile::Quiet) => + { + PlatformProfile::Quiet + } + _ => { + return Err(FdoErr::NotSupported(format!( + "RogPlatform: platform_profile: {} not supported", + policy + ))); + } + } + } else { + policy + }; self.platform .set_platform_profile(policy.into()) @@ -525,13 +556,22 @@ impl CtrlPlatform { #[zbus(signal_context)] ctxt: SignalEmitter<'_>, policy: PlatformProfile, ) -> Result<(), FdoErr> { - // If the requested profile isn't available on this platform, and it's - // `Quiet`, fall back to `LowPower` so we don't write an unavailable - // profile into the config file. + // If the requested profile isn't available on this platform, fall + // back to the semantic equivalent (Quiet <-> LowPower) so we don't + // write an unavailable profile into the config file. Different ASUS + // platforms expose one or the other for the same semantic profile. let mut chosen = policy; if let Ok(choices) = self.platform.get_platform_profile_choices() { - if chosen == PlatformProfile::Quiet && !choices.contains(&PlatformProfile::Quiet) { - chosen = PlatformProfile::LowPower; + if !choices.contains(&chosen) { + if chosen == PlatformProfile::Quiet + && choices.contains(&PlatformProfile::LowPower) + { + chosen = PlatformProfile::LowPower; + } else if chosen == PlatformProfile::LowPower + && choices.contains(&PlatformProfile::Quiet) + { + chosen = PlatformProfile::Quiet; + } } } @@ -564,11 +604,19 @@ impl CtrlPlatform { #[zbus(signal_context)] ctxt: SignalEmitter<'_>, policy: PlatformProfile, ) -> Result<(), FdoErr> { - // Mirror the same fallback behavior for AC profile changes. + // Mirror the same bidirectional Quiet <-> LowPower fallback for AC. let mut chosen = policy; if let Ok(choices) = self.platform.get_platform_profile_choices() { - if chosen == PlatformProfile::Quiet && !choices.contains(&PlatformProfile::Quiet) { - chosen = PlatformProfile::LowPower; + if !choices.contains(&chosen) { + if chosen == PlatformProfile::Quiet + && choices.contains(&PlatformProfile::LowPower) + { + chosen = PlatformProfile::LowPower; + } else if chosen == PlatformProfile::LowPower + && choices.contains(&PlatformProfile::Quiet) + { + chosen = PlatformProfile::Quiet; + } } }