mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 09:23:19 +01:00
Per-AC/DC per-profile tunings enabled
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- Per-AC/DC, per-profile tunings enabled (Battery vs AC power + platform profile)
|
||||
|
||||
## [v6.1.0-rc4]
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -7,6 +6,7 @@ use config_traits::StdConfig;
|
||||
use log::{debug, error, info};
|
||||
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
|
||||
use rog_platform::platform::{RogPlatform, ThrottlePolicy};
|
||||
use rog_platform::power::AsusPower;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zbus::object_server::SignalEmitter;
|
||||
use zbus::zvariant::{ObjectPath, OwnedObjectPath, OwnedValue, Type, Value};
|
||||
@@ -33,15 +33,22 @@ pub struct AsusArmouryAttribute {
|
||||
attr: Attribute,
|
||||
config: Arc<Mutex<Config>>,
|
||||
/// platform control required here for access to PPD or Throttle profile
|
||||
platform: RogPlatform
|
||||
platform: RogPlatform,
|
||||
power: AsusPower
|
||||
}
|
||||
|
||||
impl AsusArmouryAttribute {
|
||||
pub fn new(attr: Attribute, platform: RogPlatform, config: Arc<Mutex<Config>>) -> Self {
|
||||
pub fn new(
|
||||
attr: Attribute,
|
||||
platform: RogPlatform,
|
||||
power: AsusPower,
|
||||
config: Arc<Mutex<Config>>
|
||||
) -> Self {
|
||||
Self {
|
||||
attr,
|
||||
config,
|
||||
platform
|
||||
platform,
|
||||
power
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +102,20 @@ impl crate::Reloadable for AsusArmouryAttribute {
|
||||
info!("Reloading {}", self.attr.name());
|
||||
let profile: ThrottlePolicy =
|
||||
ThrottlePolicy::from_str(self.platform.get_platform_profile()?.as_str())?;
|
||||
if let Some(tunings) = self.config.lock().await.profile_tunings.get(&profile) {
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let config = if power_plugged == 1 {
|
||||
&self.config.lock().await.ac_profile_tunings
|
||||
} else {
|
||||
&self.config.lock().await.dc_profile_tunings
|
||||
};
|
||||
if let Some(tunings) = config.get(&profile) {
|
||||
if let Some(tune) = tunings.get(&self.name()) {
|
||||
self.attr
|
||||
.set_current_value(AttrValue::Integer(*tune))
|
||||
@@ -214,31 +234,23 @@ impl AsusArmouryAttribute {
|
||||
let profile: ThrottlePolicy =
|
||||
ThrottlePolicy::from_str(self.platform.get_platform_profile()?.as_str())?;
|
||||
|
||||
// var here to prevent async deadlock on else clause
|
||||
let has_profile = self
|
||||
.config
|
||||
.lock()
|
||||
.await
|
||||
.profile_tunings
|
||||
.contains_key(&profile);
|
||||
if has_profile {
|
||||
if let Some(tunings) = self.config.lock().await.profile_tunings.get_mut(&profile) {
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let mut config = self.config.lock().await;
|
||||
let tunings = config.select_tunings(power_plugged == 1, profile);
|
||||
|
||||
if let Some(tune) = tunings.get_mut(&self.name()) {
|
||||
*tune = value;
|
||||
} else {
|
||||
tunings.insert(self.name(), value);
|
||||
debug!("Set tuning config for {} = {:?}", self.attr.name(), value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug!("Adding tuning config for {}", profile);
|
||||
self.config
|
||||
.lock()
|
||||
.await
|
||||
.profile_tunings
|
||||
.insert(profile, HashMap::from([(self.name(), value)]));
|
||||
debug!("Set tuning config for {} = {:?}", self.attr.name(), value);
|
||||
}
|
||||
} else {
|
||||
let has_attr = self
|
||||
.config
|
||||
@@ -274,10 +286,16 @@ impl AsusArmouryAttribute {
|
||||
pub async fn start_attributes_zbus(
|
||||
conn: &Connection,
|
||||
platform: RogPlatform,
|
||||
power: AsusPower,
|
||||
config: Arc<Mutex<Config>>
|
||||
) -> Result<(), RogError> {
|
||||
for attr in FirmwareAttributes::new().attributes() {
|
||||
let mut attr = AsusArmouryAttribute::new(attr.clone(), platform.clone(), config.clone());
|
||||
let mut attr = AsusArmouryAttribute::new(
|
||||
attr.clone(),
|
||||
platform.clone(),
|
||||
power.clone(),
|
||||
config.clone()
|
||||
);
|
||||
attr.reload().await?;
|
||||
|
||||
let path = dbus_path_for_attr(attr.attr.name());
|
||||
@@ -288,3 +306,41 @@ pub async fn start_attributes_zbus(
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_config_or_default(
|
||||
attrs: &FirmwareAttributes,
|
||||
config: &mut Config,
|
||||
power_plugged: bool,
|
||||
profile: ThrottlePolicy
|
||||
) {
|
||||
for attr in attrs.attributes().iter() {
|
||||
let name: FirmwareAttribute = attr.name().into();
|
||||
if name.is_ppt() {
|
||||
let tunings = config.select_tunings(power_plugged, profile);
|
||||
|
||||
if let Some(tune) = tunings.get(&name) {
|
||||
attr.set_current_value(AttrValue::Integer(*tune))
|
||||
.map_err(|e| {
|
||||
error!("Failed to set {}: {e}", <&str>::from(name));
|
||||
})
|
||||
.ok();
|
||||
} else {
|
||||
let default = attr.default_value().clone();
|
||||
attr.set_current_value(default.clone())
|
||||
.map_err(|e| {
|
||||
error!("Failed to set {}: {e}", <&str>::from(name));
|
||||
})
|
||||
.ok();
|
||||
if let AttrValue::Integer(i) = default {
|
||||
tunings.insert(name, i);
|
||||
info!(
|
||||
"Set default tuning config for {} = {:?}",
|
||||
<&str>::from(name),
|
||||
i
|
||||
);
|
||||
config.write();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use rog_platform::platform::ThrottlePolicy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const CONFIG_FILE: &str = "asusd.ron";
|
||||
type Tunings = HashMap<ThrottlePolicy, HashMap<FirmwareAttribute, i32>>;
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq)]
|
||||
pub struct Config {
|
||||
@@ -37,13 +38,29 @@ pub struct Config {
|
||||
pub throttle_balanced_epp: CPUEPP,
|
||||
/// The energy_performance_preference for this throttle/platform profile
|
||||
pub throttle_performance_epp: CPUEPP,
|
||||
pub profile_tunings: HashMap<ThrottlePolicy, HashMap<FirmwareAttribute, i32>>,
|
||||
pub ac_profile_tunings: Tunings,
|
||||
pub dc_profile_tunings: Tunings,
|
||||
pub armoury_settings: HashMap<FirmwareAttribute, i32>,
|
||||
/// Temporary state for AC/Batt
|
||||
#[serde(skip)]
|
||||
pub last_power_plugged: u8
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn select_tunings(
|
||||
&mut self,
|
||||
power_plugged: bool,
|
||||
profile: ThrottlePolicy
|
||||
) -> &mut HashMap<FirmwareAttribute, i32> {
|
||||
let config = if power_plugged {
|
||||
&mut self.ac_profile_tunings
|
||||
} else {
|
||||
&mut self.dc_profile_tunings
|
||||
};
|
||||
config.entry(profile).or_insert_with(HashMap::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -60,7 +77,8 @@ impl Default for Config {
|
||||
throttle_quiet_epp: CPUEPP::Power,
|
||||
throttle_balanced_epp: CPUEPP::BalancePower,
|
||||
throttle_performance_epp: CPUEPP::Performance,
|
||||
profile_tunings: HashMap::default(),
|
||||
ac_profile_tunings: HashMap::default(),
|
||||
dc_profile_tunings: HashMap::default(),
|
||||
armoury_settings: HashMap::default(),
|
||||
last_power_plugged: Default::default()
|
||||
}
|
||||
@@ -148,7 +166,8 @@ impl From<Config601> for Config {
|
||||
throttle_balanced_epp: c.throttle_balanced_epp,
|
||||
throttle_performance_epp: c.throttle_performance_epp,
|
||||
last_power_plugged: c.last_power_plugged,
|
||||
profile_tunings: HashMap::default(),
|
||||
ac_profile_tunings: HashMap::default(),
|
||||
dc_profile_tunings: HashMap::default(),
|
||||
armoury_settings: HashMap::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::sync::Arc;
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
|
||||
use rog_platform::asus_armoury::FirmwareAttributes;
|
||||
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||
use rog_platform::platform::{Properties, RogPlatform, ThrottlePolicy};
|
||||
use rog_platform::power::AsusPower;
|
||||
@@ -14,6 +14,7 @@ use zbus::fdo::Error as FdoErr;
|
||||
use zbus::object_server::SignalEmitter;
|
||||
use zbus::{interface, Connection};
|
||||
|
||||
use crate::asus_armoury::set_config_or_default;
|
||||
use crate::config::Config;
|
||||
use crate::error::RogError;
|
||||
use crate::{task_watch_item, CtrlTask, ReloadAndNotify};
|
||||
@@ -661,6 +662,24 @@ impl CtrlTask for CtrlPlatform {
|
||||
if platform3.power.has_charge_control_end_threshold() && !power_plugged {
|
||||
platform3.restore_charge_limit().await;
|
||||
}
|
||||
|
||||
if let Ok(profile) = platform3
|
||||
.platform
|
||||
.get_throttle_thermal_policy()
|
||||
.map(ThrottlePolicy::from)
|
||||
.map_err(|e| {
|
||||
error!("Platform: get_throttle_thermal_policy error: {e}");
|
||||
})
|
||||
{
|
||||
let attrs = FirmwareAttributes::new();
|
||||
set_config_or_default(
|
||||
&attrs,
|
||||
&mut *platform3.config.lock().await,
|
||||
power_plugged,
|
||||
profile
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -698,35 +717,21 @@ impl CtrlTask for CtrlPlatform {
|
||||
ctrl.throttle_thermal_policy_changed(&signal_ctxt)
|
||||
.await
|
||||
.ok();
|
||||
for attr in attrs.attributes().iter() {
|
||||
let name: FirmwareAttribute = attr.name().into();
|
||||
if name.is_ppt() {
|
||||
let mut do_default = false;
|
||||
if let Some(tunings) =
|
||||
ctrl.config.lock().await.profile_tunings.get(&profile)
|
||||
{
|
||||
if let Some(tune) = tunings.get(&name) {
|
||||
attr.set_current_value(AttrValue::Integer(*tune))
|
||||
let power_plugged = ctrl
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Failed to set {}: {e}", <&str>::from(name));
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.ok();
|
||||
} else {
|
||||
do_default = true;
|
||||
}
|
||||
} else {
|
||||
do_default = true;
|
||||
}
|
||||
if do_default {
|
||||
let default = attr.default_value().clone();
|
||||
attr.set_current_value(default)
|
||||
.map_err(|e| {
|
||||
error!("Failed to set {}: {e}", <&str>::from(name));
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
.unwrap_or_default();
|
||||
set_config_or_default(
|
||||
&attrs,
|
||||
&mut *ctrl.config.lock().await,
|
||||
power_plugged == 1,
|
||||
profile
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use asusd::{print_board_info, start_tasks, CtrlTask, DBUS_NAME};
|
||||
use config_traits::{StdConfig, StdConfigLoad1};
|
||||
use log::{error, info};
|
||||
use rog_platform::platform::RogPlatform;
|
||||
use rog_platform::power::AsusPower;
|
||||
use zbus::fdo::ObjectManager;
|
||||
|
||||
#[tokio::main]
|
||||
@@ -67,7 +68,8 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
// supported.add_to_server(&mut connection).await;
|
||||
let platform = RogPlatform::new()?; // TODO: maybe needs async mutex?
|
||||
start_attributes_zbus(&server, platform, config.clone()).await?;
|
||||
let power = AsusPower::new()?; // TODO: maybe needs async mutex?
|
||||
start_attributes_zbus(&server, platform, power, config.clone()).await?;
|
||||
|
||||
match CtrlFanCurveZbus::new() {
|
||||
Ok(ctrl) => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2025-01-18 10:11+0000\n"
|
||||
"POT-Creation-Date: 2025-01-18 22:33+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
||||
@@ -178,6 +178,7 @@ impl Attribute {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FirmwareAttributes {
|
||||
attrs: Vec<Attribute>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user