Begin syncing changes with patch series

This commit is contained in:
Luke D. Jones
2021-09-07 20:20:37 +12:00
parent 5f677bc3b9
commit bfaa478a4a
9 changed files with 298 additions and 233 deletions

1
Cargo.lock generated
View File

@@ -938,6 +938,7 @@ version = "1.0.0"
dependencies = [
"serde",
"serde_derive",
"udev",
"zvariant",
"zvariant_derive",
]

View File

@@ -1,4 +1,5 @@
use log::{error, warn};
use rog_profiles::fan_curves::FanCurveSet;
use rog_profiles::{FanCurves, Profile};
use serde_derive::{Deserialize, Serialize};
use std::fs::{File, OpenOptions};
@@ -22,10 +23,11 @@ impl ProfileConfig {
fan_curves: None,
};
if FanCurves::is_fan_curves_supported() {
let mut curves = FanCurves::default();
curves.update_from_platform();
platform.fan_curves = Some(curves);
if let Ok(res) = FanCurveSet::is_supported() {
if res {
let mut curves = FanCurves::default();
platform.fan_curves = Some(curves);
}
}
platform

View File

@@ -2,37 +2,16 @@ use crate::error::RogError;
use crate::GetSupported;
use log::{info, warn};
use rog_profiles::error::ProfileError;
use rog_profiles::{FanCurves, Profile};
use rog_profiles::fan_curves::FanCurveSet;
use rog_profiles::{Profile};
use rog_supported::PlatformProfileFunctions;
use std::sync::Arc;
use std::sync::Mutex;
use udev::Device;
use super::config::ProfileConfig;
pub struct CtrlPlatformTask {
config: Arc<Mutex<ProfileConfig>>,
}
impl CtrlPlatformTask {
pub fn new(config: Arc<Mutex<ProfileConfig>>) -> Self {
Self { config }
}
}
impl crate::CtrlTask for CtrlPlatformTask {
fn do_task(&self) -> Result<(), RogError> {
if let Ok(mut lock) = self.config.try_lock() {
// Refresh the config in-case the user has edited it
if let Some(curves) = &mut lock.fan_curves {
curves.update_from_platform();
}
}
Ok(())
}
}
pub struct CtrlPlatformProfile {
pub config: Arc<Mutex<ProfileConfig>>,
pub config: ProfileConfig,
pub fan_device: Option<Device>,
}
impl GetSupported for CtrlPlatformProfile {
@@ -48,7 +27,14 @@ https://lkml.org/lkml/2021/8/18/1022
"#
);
}
if !FanCurves::is_fan_curves_supported() {
let res = FanCurveSet::is_supported();
let mut fan_curve_supported = res.is_err();
if let Ok(r) = res {
fan_curve_supported = r;
};
if fan_curve_supported {
info!(
r#"
fan curves kernel interface not found, your laptop does not support this, or the interface is missing.
@@ -58,9 +44,10 @@ Please note that as of 24/08/2021 this is not final.
"#
);
}
PlatformProfileFunctions {
platform_profile: Profile::is_platform_profile_supported(),
fan_curves: FanCurves::is_fan_curves_supported(),
fan_curves: fan_curve_supported,
}
}
}
@@ -68,53 +55,54 @@ Please note that as of 24/08/2021 this is not final.
impl crate::Reloadable for CtrlPlatformProfile {
/// Fetch the active profile and use that to set all related components up
fn reload(&mut self) -> Result<(), RogError> {
if let Ok(cfg) = self.config.clone().try_lock() {
if let Some(curves) = &cfg.fan_curves {
curves.update_platform();
if let Some(curves) = &self.config.fan_curves {
if let Ok(mut device) = FanCurveSet::get_device() {
curves.write_to_platform(self.config.active, &mut device);
}
}
}
Ok(())
}
}
impl CtrlPlatformProfile {
pub fn new(config: Arc<Mutex<ProfileConfig>>) -> Result<Self, RogError> {
pub fn new(config: ProfileConfig, fan_device: Option<Device>) -> Result<Self, RogError> {
if Profile::is_platform_profile_supported() {
info!("Device has profile control available");
return Ok(CtrlPlatformProfile { config });
return Ok(CtrlPlatformProfile { config, fan_device });
}
Err(ProfileError::NotSupported.into())
}
pub fn get_device(&self) -> Option<Device> {
self.fan_device.clone()
}
pub fn save_config(&self) {
if let Ok(lock) = self.config.lock() {
lock.write();
}
self.config.write();
}
/// Toggle to next profile in list. This will first read the config, switch, then write out
pub(super) fn set_next_profile(&mut self) -> Result<(), RogError> {
if let Ok(mut config) = self.config.clone().try_lock() {
// Read first just incase the user has modified the config before calling this
config.read();
// Read first just incase the user has modified the config before calling this
self.config.read();
match config.active {
Profile::Balanced => {
Profile::set_profile(Profile::Performance)?;
config.active = Profile::Performance;
}
Profile::Performance => {
Profile::set_profile(Profile::Quiet)?;
config.active = Profile::Quiet;
}
Profile::Quiet => {
Profile::set_profile(Profile::Balanced)?;
config.active = Profile::Balanced;
}
match self.config.active {
Profile::Balanced => {
Profile::set_profile(Profile::Performance)?;
self.config.active = Profile::Performance;
}
Profile::Performance => {
Profile::set_profile(Profile::Quiet)?;
self.config.active = Profile::Quiet;
}
Profile::Quiet => {
Profile::set_profile(Profile::Balanced)?;
self.config.active = Profile::Balanced;
}
config.write();
}
self.config.write();
Ok(())
}
}

View File

@@ -1,5 +1,5 @@
use log::warn;
use rog_profiles::FanCurve;
use rog_profiles::fan_curves::FanCurveSet;
use rog_profiles::Profile;
use std::sync::Arc;
@@ -45,11 +45,9 @@ impl ProfileZbus {
/// Fetch the active profile name
fn active_profile(&mut self) -> zbus::fdo::Result<Profile> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
return Ok(cfg.active);
}
if let Ok(mut ctrl) = self.inner.try_lock() {
ctrl.config.read();
return Ok(ctrl.config.active);
}
Err(Error::Failed(
"Failed to get active profile name".to_string(),
@@ -58,15 +56,14 @@ impl ProfileZbus {
/// Set this platform_profile name as active
fn set_active_profile(&self, profile: Profile) {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
// Read first just incase the user has modified the config before calling this
cfg.read();
Profile::set_profile(profile)
.map_err(|e| warn!("Profile::set_profile, {}", e))
.ok();
cfg.active = profile;
}
if let Ok(mut ctrl) = self.inner.try_lock() {
// Read first just incase the user has modified the config before calling this
ctrl.config.read();
Profile::set_profile(profile)
.map_err(|e| warn!("Profile::set_profile, {}", e))
.ok();
ctrl.config.active = profile;
ctrl.save_config();
}
self.do_notification();
@@ -74,14 +71,12 @@ impl ProfileZbus {
/// Get a list of profiles that have fan-curves enabled.
fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Some(curves) = &cfg.fan_curves {
return Ok(curves.get_enabled_curve_names().to_vec());
}
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
if let Ok(mut ctrl) = self.inner.try_lock() {
ctrl.config.read();
if let Some(curves) = &ctrl.config.fan_curves {
return Ok(curves.get_enabled_curve_names().to_vec());
}
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
}
Err(Error::Failed(
"Failed to get enabled fan curve names".to_string(),
@@ -89,43 +84,41 @@ impl ProfileZbus {
}
/// Get the fan-curve data for the currently active Profile
fn active_fan_curve_data(&mut self) -> zbus::fdo::Result<FanCurve> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Some(curves) = &cfg.fan_curves {
return Ok((*curves.get_active_fan_curves()).clone());
}
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
fn active_fan_curve_data(&mut self) -> zbus::fdo::Result<FanCurveSet> {
if let Ok(mut ctrl) = self.inner.try_lock() {
ctrl.config.read();
if let Some(curves) = &ctrl.config.fan_curves {
return Ok((*curves.get_active_fan_curves()).clone());
}
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
}
Err(Error::Failed("Failed to get fan curve data".to_string()))
}
/// Get fan-curve data for each Profile as an array of objects
fn fan_curves(&self) -> zbus::fdo::Result<Vec<FanCurve>> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Some(curves) = &cfg.fan_curves {
return Ok(curves.get_all_fan_curves());
}
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
fn fan_curves(&self) -> zbus::fdo::Result<Vec<FanCurveSet>> {
if let Ok(mut ctrl) = self.inner.try_lock() {
ctrl.config.read();
if let Some(curves) = &ctrl.config.fan_curves {
return Ok(curves.get_all_fan_curves());
}
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
}
Err(Error::Failed("Failed to get all fan curves".to_string()))
}
/// Set this fan-curve data
fn set_fan_curve(&self, curve: FanCurve) -> zbus::fdo::Result<()> {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(mut cfg) = ctrl.config.try_lock() {
cfg.read();
if let Some(curves) = &mut cfg.fan_curves {
curves.set_fan_curve(curve);
fn set_fan_curve(&self, curve: FanCurveSet) -> zbus::fdo::Result<()> {
if let Ok(mut ctrl) = self.inner.try_lock() {
ctrl.config.read();
if let Some(mut device) = ctrl.get_device() {
if let Some(curves) = &mut ctrl.config.fan_curves {
curves.set_fan_curve(curve, &mut device);
}
} else {
return Err(Error::Failed(UNSUPPORTED_MSG.to_string()));
}
ctrl.save_config();
}
@@ -139,10 +132,8 @@ impl ProfileZbus {
impl ProfileZbus {
fn do_notification(&self) {
if let Ok(ctrl) = self.inner.try_lock() {
if let Ok(cfg) = ctrl.config.clone().try_lock() {
self.notify_profile(&cfg.active)
.unwrap_or_else(|err| warn!("{}", err));
}
self.notify_profile(&ctrl.config.active)
.unwrap_or_else(|err| warn!("{}", err));
}
}
}

View File

@@ -7,7 +7,6 @@ use daemon::ctrl_aura::controller::{
};
use daemon::ctrl_charge::CtrlCharge;
use daemon::ctrl_profiles::config::ProfileConfig;
use daemon::ctrl_profiles::controller::CtrlPlatformTask;
use daemon::{
config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported,
};
@@ -21,6 +20,7 @@ use daemon::{CtrlTask, Reloadable, ZbusAdd};
use log::LevelFilter;
use log::{error, info, warn};
use rog_dbus::DBUS_NAME;
use rog_profiles::fan_curves::FanCurveSet;
use std::env;
use std::error::Error;
use std::io::Write;
@@ -108,16 +108,19 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
}
}
let profile_config = Arc::new(Mutex::new(ProfileConfig::load(PROFILE_CONFIG_PATH.into())));
match CtrlPlatformProfile::new(profile_config.clone()) {
let fan_device = if let Ok(res) = FanCurveSet::get_device() {
Some(res)
} else {
None
};
let profile_config = ProfileConfig::load(PROFILE_CONFIG_PATH.into());
match CtrlPlatformProfile::new(profile_config, fan_device) {
Ok(mut ctrl) => {
ctrl.reload()
.unwrap_or_else(|err| warn!("Profile control: {}", err));
let tmp = Arc::new(Mutex::new(ctrl));
ProfileZbus::new(tmp).add_to_server(&mut object_server);
tasks.push(Box::new(CtrlPlatformTask::new(profile_config)));
}
Err(err) => {
error!("Profile control: {}", err);

View File

@@ -21,7 +21,7 @@
use std::sync::mpsc::Sender;
use rog_profiles::{FanCurve, Profile};
use rog_profiles::{Profile, fan_curves::FanCurveSet};
use zbus::{dbus_proxy, Connection, Result};
#[dbus_proxy(
@@ -45,13 +45,13 @@ trait Daemon {
fn enabled_fan_profiles(&self) -> zbus::Result<Vec<Profile>>;
/// Get the active `Profile` data
fn active_fan_data(&self) -> zbus::Result<FanCurve>;
fn active_fan_data(&self) -> zbus::Result<FanCurveSet>;
/// Get all fan curve data
fn fan_curves(&self) -> zbus::Result<Vec<FanCurve>>;
fn fan_curves(&self) -> zbus::Result<Vec<FanCurveSet>>;
/// Set a fan curve. If a field is empty then the exisiting saved curve is used
fn set_fan_curve(&self, curve: FanCurve) -> zbus::Result<()>;
fn set_fan_curve(&self, curve: FanCurveSet) -> zbus::Result<()>;
/// NotifyProfile signal
#[dbus_proxy(signal)]

View File

@@ -9,6 +9,7 @@ default = ["dbus"]
dbus = ["zvariant", "zvariant_derive"]
[dependencies]
udev = "^0.6"
serde = "^1.0"
serde_derive = "^1.0"

View File

@@ -0,0 +1,147 @@
use serde_derive::{Deserialize, Serialize};
use udev::Device;
#[cfg(feature = "dbus")]
use zvariant_derive::Type;
use crate::error::ProfileError;
pub fn pwm_str(fan: char, index: char) -> String {
let mut buf = "pwm1_auto_point1_pwm".to_string();
unsafe {
let tmp = buf.as_bytes_mut();
tmp[3] = fan as u8;
tmp[15] = index as u8;
}
buf
}
pub fn temp_str(fan: char, index: char) -> String {
let mut buf = "pwm1_auto_point1_temp".to_string();
unsafe {
let tmp = buf.as_bytes_mut();
tmp[3] = fan as u8;
tmp[15] = index as u8;
}
buf
}
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
pub struct CurveData {
pub pwm: [u8; 8],
pub temp: [u8; 8],
}
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
pub struct FanCurveSet {
pub cpu: CurveData,
pub gpu: CurveData,
}
impl FanCurveSet {
pub fn get_device() -> Result<Device, ProfileError> {
let mut enumerator = udev::Enumerator::new()?;
enumerator.match_subsystem("hwmon")?;
for device in enumerator.scan_devices().unwrap() {
if device.parent_with_subsystem("platform").unwrap().is_some() {
if let Some(name) = device.attribute_value("name") {
if name == "asus_custom_fan_curve" {
return Ok(device);
}
}
}
}
Err(ProfileError::NotSupported)
}
pub fn new() -> Result<(Self, Device), ProfileError> {
if let Ok(device) = Self::get_device() {
let mut fans = Self {
cpu: CurveData::default(),
gpu: CurveData::default(),
};
fans.init_from_device(&device);
return Ok((fans, device));
}
Err(ProfileError::NotSupported)
}
pub fn is_supported() -> Result<bool, ProfileError> {
if Self::get_device().is_ok() {
return Ok(true);
}
Ok(false)
}
pub fn update_from_device(&mut self, device: &Device) {
self.init_from_device(device);
}
fn set_val_from_attr(tmp: &str, device: &Device, buf: &mut [u8; 8]) {
if let Some(n) = tmp.chars().nth(15) {
let i = n.to_digit(10).unwrap() as usize;
let d = device.attribute_value(tmp).unwrap();
let d: u8 = d.to_string_lossy().parse().unwrap();
buf[i - 1] = d;
}
}
pub fn init_from_device(&mut self, device: &Device) {
for attr in device.attributes() {
let tmp = attr.name().to_string_lossy();
if tmp.starts_with("pwm1") && tmp.ends_with("_temp") {
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.cpu.temp)
}
if tmp.starts_with("pwm1") && tmp.ends_with("_pwm") {
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.cpu.pwm)
}
if tmp.starts_with("pwm2") && tmp.ends_with("_temp") {
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.gpu.temp)
}
if tmp.starts_with("pwm2") && tmp.ends_with("_pwm") {
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.gpu.pwm)
}
}
}
fn write_to_fan(curve: &CurveData, pwm_num: char, device: &mut Device) {
let mut pwm = "pwmN_auto_pointN_pwm".to_string();
for (index,out) in curve.pwm.iter().enumerate() {
unsafe {
let buf = pwm.as_bytes_mut();
buf[3] = pwm_num as u8;
// Should be quite safe to unwrap as we're not going over 8
buf[15] = char::from_digit(index as u32, 10).unwrap() as u8;
}
let out = out.to_string();
device.set_attribute_value(&pwm, &out).unwrap();
}
let mut pwm = "pwmN_auto_pointN_temp".to_string();
for (index,out) in curve.temp.iter().enumerate() {
unsafe {
let buf = pwm.as_bytes_mut();
buf[3] = pwm_num as u8;
// Should be quite safe to unwrap as we're not going over 8
buf[15] = char::from_digit(index as u32, 10).unwrap() as u8;
}
let out = out.to_string();
device.set_attribute_value(&pwm, &out).unwrap();
}
}
pub fn write_cpu_fan(&self, device: &mut Device) {
Self::write_to_fan(&self.cpu, '1', device);
}
pub fn write_gpu_fan(&self, device: &mut Device) {
Self::write_to_fan(&self.gpu, '2', device);
}
}

View File

@@ -1,26 +1,42 @@
pub mod error;
pub mod fan_curves;
use std::{
fs::OpenOptions,
io::{Read, Write},
path::{Path, PathBuf},
path::{Path},
};
use error::ProfileError;
use fan_curves::{CurveData, FanCurveSet};
use serde_derive::{Deserialize, Serialize};
use udev::Device;
#[cfg(feature = "dbus")]
use zvariant_derive::Type;
pub static PLATFORM_PROFILE: &str = "/sys/firmware/acpi/platform_profile";
pub static PLATFORM_PROFILES: &str = "/sys/firmware/acpi/platform_profile_choices";
pub static FAN_CURVE_BASE_PATH: &str = "/sys/devices/platform/asus-nb-wmi/";
pub static FAN_CURVE_ACTIVE_FILE: &str = "enabled_fan_curve_profiles";
pub static FAN_CURVE_FILENAME_PART: &str = "_fan_curve_";
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn find_fan_curve_node() -> Result<Option<Device>, ProfileError> {
let mut enumerator = udev::Enumerator::new()?;
enumerator.match_subsystem("hwmon")?;
for device in enumerator.scan_devices()? {
if device.parent_with_subsystem("platform")?.is_some() {
if let Some(name) = device.attribute_value("name") {
if name == "asus_custom_fan_curve" {
return Ok(Some(device));
}
}
}
}
Err(ProfileError::NotSupported)
}
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
pub enum Profile {
@@ -116,82 +132,44 @@ impl Default for FanCurvePU {
}
}
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
pub struct FanCurve {
pub profile: Profile,
pub cpu: String,
pub gpu: String,
}
/// Main purpose of `FanCurves` is to enable retoring state on system boot
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Debug)]
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct FanCurves {
enabled: Vec<Profile>,
balanced: FanCurve,
performance: FanCurve,
quiet: FanCurve,
balanced: FanCurveSet,
performance: FanCurveSet,
quiet: FanCurveSet,
}
impl Default for FanCurves {
fn default() -> Self {
let mut curves = Self {
enabled: Default::default(),
balanced: Default::default(),
performance: Default::default(),
quiet: Default::default(),
};
curves.balanced.profile = Profile::Balanced;
curves.performance.profile = Profile::Performance;
curves.quiet.profile = Profile::Quiet;
curves
}
}
impl FanCurves {
pub fn is_fan_curves_supported() -> bool {
let mut path = PathBuf::new();
path.push(FAN_CURVE_BASE_PATH);
path.push(FAN_CURVE_ACTIVE_FILE);
path.exists()
///
pub fn init_from_platform(&mut self, profile: Profile, device: &Device) {
let mut tmp = FanCurveSet::default();
tmp.init_from_device(device);
match profile {
Profile::Balanced => self.balanced = tmp,
Profile::Performance => self.performance = tmp,
Profile::Quiet => self.quiet = tmp,
}
}
pub fn update_from_platform(&mut self) {
self.balanced.cpu = Self::get_fan_curve_from_file(Profile::Balanced, FanCurvePU::CPU);
self.balanced.gpu = Self::get_fan_curve_from_file(Profile::Balanced, FanCurvePU::GPU);
self.performance.cpu = Self::get_fan_curve_from_file(Profile::Performance, FanCurvePU::CPU);
self.performance.gpu = Self::get_fan_curve_from_file(Profile::Performance, FanCurvePU::GPU);
self.quiet.cpu = Self::get_fan_curve_from_file(Profile::Quiet, FanCurvePU::CPU);
self.quiet.gpu = Self::get_fan_curve_from_file(Profile::Quiet, FanCurvePU::GPU);
}
pub fn update_platform(&self) {
Self::set_fan_curve_for_platform(Profile::Balanced, FanCurvePU::CPU, &self.balanced.cpu);
Self::set_fan_curve_for_platform(Profile::Balanced, FanCurvePU::GPU, &self.balanced.gpu);
Self::set_fan_curve_for_platform(
Profile::Performance,
FanCurvePU::CPU,
&self.performance.cpu,
);
Self::set_fan_curve_for_platform(
Profile::Performance,
FanCurvePU::GPU,
&self.performance.gpu,
);
Self::set_fan_curve_for_platform(Profile::Quiet, FanCurvePU::CPU, &self.quiet.cpu);
Self::set_fan_curve_for_platform(Profile::Quiet, FanCurvePU::GPU, &self.quiet.gpu);
pub fn write_to_platform(&self, profile: Profile, device: &mut Device) {
let fans = match profile {
Profile::Balanced => &self.balanced,
Profile::Performance => &self.performance,
Profile::Quiet => &self.quiet,
};
fans.write_cpu_fan(device);
fans.write_gpu_fan(device);
}
pub fn get_enabled_curve_names(&self) -> &[Profile] {
&self.enabled
}
pub fn get_all_fan_curves(&self) -> Vec<FanCurve> {
pub fn get_all_fan_curves(&self) -> Vec<FanCurveSet> {
vec![
self.balanced.clone(),
self.performance.clone(),
@@ -199,7 +177,7 @@ impl FanCurves {
]
}
pub fn get_active_fan_curves(&self) -> &FanCurve {
pub fn get_active_fan_curves(&self) -> &FanCurveSet {
match Profile::get_active_profile().unwrap() {
Profile::Balanced => &self.balanced,
Profile::Performance => &self.performance,
@@ -207,7 +185,7 @@ impl FanCurves {
}
}
pub fn get_fan_curves_for(&self, name: Profile) -> &FanCurve {
pub fn get_fan_curves_for(&self, name: Profile) -> &FanCurveSet {
match name {
Profile::Balanced => &self.balanced,
Profile::Performance => &self.performance,
@@ -215,23 +193,7 @@ impl FanCurves {
}
}
fn get_fan_curve_from_file(name: Profile, pu: FanCurvePU) -> String {
let mut file: String = FAN_CURVE_BASE_PATH.into();
file.push_str(pu.into());
file.push_str(FAN_CURVE_FILENAME_PART);
file.push_str(name.into());
let mut file = OpenOptions::new()
.read(true)
.open(&file)
.unwrap_or_else(|_| panic!("{} not found", &file));
let mut buf = String::new();
file.read_to_string(&mut buf).unwrap();
buf.trim().to_string()
}
pub fn get_fan_curve_for(&self, name: &Profile, pu: &FanCurvePU) -> &str {
pub fn get_fan_curve_for(&self, name: &Profile, pu: &FanCurvePU) -> &CurveData {
match name {
Profile::Balanced => match pu {
FanCurvePU::CPU => &self.balanced.cpu,
@@ -248,38 +210,8 @@ impl FanCurves {
}
}
fn set_fan_curve_for_platform(name: Profile, pu: FanCurvePU, curve: &str) {
let mut file: String = FAN_CURVE_BASE_PATH.into();
file.push_str(pu.into());
file.push_str(FAN_CURVE_FILENAME_PART);
file.push_str(name.into());
let mut file = OpenOptions::new()
.write(true)
.open(&file)
.unwrap_or_else(|_| panic!("{} not found", &file));
file.write_all(curve.as_bytes()).unwrap();
}
pub fn set_fan_curve(&mut self, curve: FanCurve) {
// First, set the profiles.
Self::set_fan_curve_for_platform(curve.profile, FanCurvePU::CPU, &curve.cpu);
match curve.profile {
Profile::Balanced => self.balanced.cpu = curve.cpu,
Profile::Performance => self.performance.cpu = curve.cpu,
Profile::Quiet => self.quiet.cpu = curve.cpu,
};
Self::set_fan_curve_for_platform(curve.profile, FanCurvePU::GPU, &curve.gpu);
match curve.profile {
Profile::Balanced => self.balanced.gpu = curve.gpu,
Profile::Performance => self.performance.gpu = curve.gpu,
Profile::Quiet => self.quiet.cpu = curve.gpu,
};
// Any curve that was blank will have been reset, so repopulate the settings
// Note: successfully set curves will just be re-read in.
self.update_from_platform();
pub fn set_fan_curve(&self, curve: FanCurveSet, device: &mut Device) {
curve.write_cpu_fan(device);
curve.write_gpu_fan(device);
}
}