Fetch and store fan curve correctly

This commit is contained in:
Luke D. Jones
2021-09-09 23:45:18 +12:00
parent 0a565a7a5c
commit b939a9d331
12 changed files with 114 additions and 73 deletions

View File

@@ -4,7 +4,7 @@ use udev::Device;
#[cfg(feature = "dbus")]
use zvariant_derive::Type;
use crate::{FanCurvePU, error::ProfileError, write_to_fan};
use crate::{error::ProfileError, write_to_fan, FanCurvePU};
pub fn pwm_str(fan: char, index: char) -> String {
let mut buf = "pwm1_auto_point1_pwm".to_string();
@@ -34,13 +34,31 @@ pub struct CurveData {
pub temp: [u8; 8],
}
/// A `FanCurveSet` contains both CPU and GPU fan curve data
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Default, Debug, Clone)]
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct FanCurveSet {
pub cpu: CurveData,
pub gpu: CurveData,
}
impl Default for FanCurveSet {
fn default() -> Self {
Self {
cpu: CurveData {
fan: FanCurvePU::CPU,
pwm: [0u8; 8],
temp: [0u8; 8],
},
gpu: CurveData {
fan: FanCurvePU::GPU,
pwm: [0u8; 8],
temp: [0u8; 8],
},
}
}
}
impl FanCurveSet {
pub fn get_device() -> Result<Device, ProfileError> {
let mut enumerator = udev::Enumerator::new()?;
@@ -58,6 +76,14 @@ impl FanCurveSet {
Err(ProfileError::NotSupported)
}
pub fn is_supported() -> Result<bool, ProfileError> {
if Self::get_device().is_ok() {
return Ok(true);
}
Ok(false)
}
pub fn new() -> Result<(Self, Device), ProfileError> {
if let Ok(device) = Self::get_device() {
let mut fans = Self {
@@ -68,7 +94,7 @@ impl FanCurveSet {
fans.cpu.fan = FanCurvePU::CPU;
fans.cpu.fan = FanCurvePU::GPU;
fans.init_from_device(&device);
fans.read_from_device(&device);
return Ok((fans, device));
}
@@ -76,18 +102,6 @@ impl FanCurveSet {
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;
@@ -97,7 +111,7 @@ impl FanCurveSet {
}
}
pub fn init_from_device(&mut self, device: &Device) {
pub fn read_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") {
@@ -122,4 +136,4 @@ impl FanCurveSet {
pub fn write_gpu_fan(&self, device: &mut Device) {
write_to_fan(&self.gpu, '2', device);
}
}
}

View File

@@ -1,14 +1,14 @@
pub mod error;
pub mod fan_curves;
pub mod fan_curve_set;
use std::{
fs::OpenOptions,
io::{Read, Write},
path::{Path},
path::Path,
};
use error::ProfileError;
use fan_curves::{CurveData, FanCurveSet};
use fan_curve_set::{CurveData, FanCurveSet};
use serde_derive::{Deserialize, Serialize};
use udev::Device;
@@ -135,19 +135,18 @@ impl Default for FanCurvePU {
/// Main purpose of `FanCurves` is to enable retoring state on system boot
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct FanCurves {
pub struct FanCurveProfiles {
enabled: Vec<Profile>,
balanced: FanCurveSet,
performance: FanCurveSet,
quiet: FanCurveSet,
}
impl FanCurves {
impl FanCurveProfiles {
///
pub fn init_from_platform(&mut self, profile: Profile, device: &Device) {
pub fn read_from_dev_profile(&mut self, profile: Profile, device: &Device) {
let mut tmp = FanCurveSet::default();
tmp.init_from_device(device);
tmp.read_from_device(device);
match profile {
Profile::Balanced => self.balanced = tmp,
Profile::Performance => self.performance = tmp,
@@ -214,7 +213,12 @@ impl FanCurves {
}
}
pub fn write_and_set_fan_curve(&mut self, curve: CurveData, profile: Profile, device: &mut Device) {
pub fn write_and_set_fan_curve(
&mut self,
curve: CurveData,
profile: Profile,
device: &mut Device,
) {
match curve.fan {
FanCurvePU::CPU => write_to_fan(&curve, '1', device),
FanCurvePU::GPU => write_to_fan(&curve, '2', device),
@@ -236,31 +240,33 @@ impl FanCurves {
}
}
pub 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() {
dbg!(&device);
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;
buf[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
}
let out = out.to_string();
dbg!(&pwm);
dbg!(&out);
device.set_attribute_value(&pwm, &out).unwrap();
}
let mut pwm = "pwmN_auto_pointN_temp".to_string();
for (index,out) in curve.temp.iter().enumerate() {
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;
buf[15] = char::from_digit(index as u32 + 1, 10).unwrap() as u8;
}
let out = out.to_string();
device.set_attribute_value(&pwm, &out).unwrap();
}
}
}