diff --git a/CHANGELOG.md b/CHANGELOG.md index c2319347..df3d0882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + `BREAKING:` plain `Image` with time period is changed and old anime configs break as a result (sorry) - LED: + By popular request LED prev/next cycle is added + + Add led modes for GX551Q ### BREAKING CHANGES - Graphics control: + graphics control is pulled out of asusd and moved to new package; https://gitlab.com/asus-linux/supergfxctl @@ -19,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + profiles now depend on power-profile-daemon plus kernel patches for support of platform_profile - if your system supports fan-curves you will also require upcoming kernel patches for this + profiles are now moved to a new file + + fan-curves are only partially completed due to this release needing to be done sooner # [3.7.2] - 2021-08-02 ### Added diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index c8dc6b68..820fe039 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -375,7 +375,9 @@ fn handle_profile( supported: &PlatformProfileFunctions, cmd: &ProfileCommand, ) -> Result<(), Box> { - if !cmd.next && !cmd.list && !cmd.active_name && !cmd.active_data && !cmd.profiles_data { + println!("Warning: Profiles should work fine but now depend on power-profiles-daemon v0.9+"); + println!("Warning: Fan-curve support is coming in a 4.1.x release"); + if !cmd.next && !cmd.list { if !cmd.help { println!("Missing arg or command\n"); } @@ -394,14 +396,18 @@ fn handle_profile( println!("\n{}", lst); } - println!("Note: turbo, frequency, fan preset and fan curve options will apply to"); - println!(" to the currently active profile unless a profile name is specified"); + // println!("Note: turbo, frequency, fan preset and fan curve options will apply to"); + // println!(" to the currently active profile unless a profile name is specified"); std::process::exit(1); } if cmd.next { dbus.proxies().profile().next_profile()?; } + if cmd.list { + let res = dbus.proxies().profile().profiles()?; + res.iter().for_each(|p| println!("{:?}", p)); + } Ok(()) } diff --git a/asusctl/src/profiles_cli.rs b/asusctl/src/profiles_cli.rs index 921ba7a2..09550a42 100644 --- a/asusctl/src/profiles_cli.rs +++ b/asusctl/src/profiles_cli.rs @@ -8,10 +8,4 @@ pub struct ProfileCommand { pub next: bool, #[options(help = "list available profiles")] pub list: bool, - #[options(help = "get active profile name")] - pub active_name: bool, - #[options(help = "get active profile data")] - pub active_data: bool, - #[options(help = "get all profile data")] - pub profiles_data: bool, } diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index cb54d5d8..8f3a1e35 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -39,7 +39,7 @@ logind-zbus = "^0.7.1" serde = "^1.0" serde_derive = "^1.0" serde_json = "^1.0" -toml = "^0.5" +toml = "^0.5.8" # Device control sysfs-class = "^0.1.2" # used for backlight control and baord ID diff --git a/daemon/src/ctrl_profiles/config.rs b/daemon/src/ctrl_profiles/config.rs index 552e7a71..176d9158 100644 --- a/daemon/src/ctrl_profiles/config.rs +++ b/daemon/src/ctrl_profiles/config.rs @@ -1,6 +1,6 @@ use log::{error, warn}; -use rog_profiles::fan_curves::FanCurveSet; -use rog_profiles::{FanCurves, Profile}; +use rog_profiles::fan_curve_set::FanCurveSet; +use rog_profiles::{FanCurveProfiles, Profile}; use serde_derive::{Deserialize, Serialize}; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; @@ -12,20 +12,20 @@ pub struct ProfileConfig { /// For restore on boot pub active_profile: Profile, /// States to restore - pub fan_curves: Option, + pub fan_curves: Option, } impl ProfileConfig { fn new(config_path: String) -> Self { let mut platform = ProfileConfig { config_path, - active_profile: Profile::Balanced, + active_profile: Profile::get_active_profile().unwrap_or(Profile::Balanced), fan_curves: None, }; if let Ok(res) = FanCurveSet::is_supported() { if res { - let curves = FanCurves::default(); + let curves = FanCurveProfiles::default(); platform.fan_curves = Some(curves); } } @@ -45,7 +45,7 @@ impl ProfileConfig { if let Ok(read_len) = file.read_to_string(&mut buf) { if read_len == 0 { config = Self::new(config_path); - } else if let Ok(data) = serde_json::from_str(&buf) { + } else if let Ok(data) = toml::from_str(&buf) { config = data; config.config_path = config_path; } else { @@ -70,7 +70,7 @@ impl ProfileConfig { if l == 0 { warn!("File is empty {}", self.config_path); } else { - let mut data: ProfileConfig = serde_json::from_str(&buf) + let mut data: ProfileConfig = toml::from_str(&buf) .unwrap_or_else(|_| panic!("Could not deserialise {}", self.config_path)); // copy over serde skipped values data.config_path = self.config_path.clone(); @@ -81,8 +81,8 @@ impl ProfileConfig { pub fn write(&self) { let mut file = File::create(&self.config_path).expect("Couldn't overwrite config"); - let json = serde_json::to_string_pretty(self).expect("Parse config to JSON failed"); - file.write_all(json.as_bytes()) + let data = toml::to_string(self).expect("Parse config to toml failed"); + file.write_all(data.as_bytes()) .unwrap_or_else(|err| error!("Could not write config: {}", err)); } } diff --git a/daemon/src/ctrl_profiles/controller.rs b/daemon/src/ctrl_profiles/controller.rs index 98434323..4f55d52a 100644 --- a/daemon/src/ctrl_profiles/controller.rs +++ b/daemon/src/ctrl_profiles/controller.rs @@ -2,8 +2,8 @@ use crate::error::RogError; use crate::GetSupported; use log::{info, warn}; use rog_profiles::error::ProfileError; -use rog_profiles::fan_curves::FanCurveSet; -use rog_profiles::{Profile}; +use rog_profiles::fan_curve_set::FanCurveSet; +use rog_profiles::Profile; use rog_supported::PlatformProfileFunctions; use udev::Device; @@ -55,21 +55,33 @@ 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 Some(curves) = &self.config.fan_curves { - if let Ok(mut device) = FanCurveSet::get_device() { - curves.write_to_platform(self.config.active_profile, &mut device); - } + if let Some(curves) = &self.config.fan_curves { + if let Ok(mut device) = FanCurveSet::get_device() { + curves.write_to_platform(self.config.active_profile, &mut device); } + } Ok(()) } } impl CtrlPlatformProfile { - pub fn new(config: ProfileConfig, fan_device: Option) -> Result { + pub fn new(mut config: ProfileConfig, fan_device: Option) -> Result { if Profile::is_platform_profile_supported() { info!("Device has profile control available"); + + if let Some(ref device) = fan_device { + let profile = config.active_profile; + config + .fan_curves + .as_mut() + .unwrap() + .read_from_dev_profile(profile, device); + } + config.write(); + return Ok(CtrlPlatformProfile { config, fan_device }); } + Err(ProfileError::NotSupported.into()) } diff --git a/daemon/src/ctrl_profiles/zbus.rs b/daemon/src/ctrl_profiles/zbus.rs index 478a7192..c0f1e61c 100644 --- a/daemon/src/ctrl_profiles/zbus.rs +++ b/daemon/src/ctrl_profiles/zbus.rs @@ -1,6 +1,6 @@ use log::warn; -use rog_profiles::fan_curves::CurveData; -use rog_profiles::fan_curves::FanCurveSet; +use rog_profiles::fan_curve_set::CurveData; +use rog_profiles::fan_curve_set::FanCurveSet; use rog_profiles::Profile; use std::sync::Arc; diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index bc4ce3d1..46df535b 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -20,7 +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 rog_profiles::fan_curve_set::FanCurveSet; use std::env; use std::error::Error; use std::io::Write; diff --git a/data/asusd-ledmodes.toml b/data/asusd-ledmodes.toml index b5f4ae39..660ae22d 100644 --- a/data/asusd-ledmodes.toml +++ b/data/asusd-ledmodes.toml @@ -109,3 +109,10 @@ board_names = ["GX550L"] standard = ["Static", "Breathe", "Strobe", "Rainbow", "Star", "Rain", "Highlight", "Laser", "Ripple", "Pulse", "Comet", "Flash"] multizone = false per_key = true + +[[led_data]] +prod_family = "ROG Zephyrus Duo 15 SE" +board_name = ["GX551Q"] +standard ["Static", "Breathe", "Pulse", "Rainbow", "Strobe"] +multizone = false +per_key = true \ No newline at end of file diff --git a/rog-dbus/src/zbus_profile.rs b/rog-dbus/src/zbus_profile.rs index 229881a0..954d63ea 100644 --- a/rog-dbus/src/zbus_profile.rs +++ b/rog-dbus/src/zbus_profile.rs @@ -21,7 +21,7 @@ use std::sync::mpsc::Sender; -use rog_profiles::{Profile, fan_curves::FanCurveSet}; +use rog_profiles::{fan_curve_set::FanCurveSet, Profile}; use zbus::{dbus_proxy, Connection, Result}; #[dbus_proxy( @@ -29,27 +29,27 @@ use zbus::{dbus_proxy, Connection, Result}; default_path = "/org/asuslinux/Profile" )] trait Daemon { - /// Profiles method - fn profiles(&self) -> zbus::Result>; - - /// NextProfile method - fn next_profile(&self) -> zbus::Result<()>; + /// Get the active `Profile` data + fn active_fan_curve_data(&self) -> zbus::Result; /// Profile, get the active profile fn active_profile(&self) -> zbus::Result; - /// Set the specific profile as active - fn set_active_profile(&self, profile: Profile) -> zbus::Result<()>; - /// Get enabled fan curves fn enabled_fan_profiles(&self) -> zbus::Result>; - /// Get the active `Profile` data - fn active_fan_data(&self) -> zbus::Result; - /// Get all fan curve data fn fan_curves(&self) -> zbus::Result>; + /// NextProfile method + fn next_profile(&self) -> zbus::Result<()>; + + /// Profiles method + fn profiles(&self) -> zbus::Result>; + + /// Set the specific profile as active + fn set_active_profile(&self, profile: Profile) -> zbus::Result<()>; + /// Set a fan curve. If a field is empty then the exisiting saved curve is used fn set_fan_curve(&self, curve: FanCurveSet) -> zbus::Result<()>; diff --git a/rog-profiles/src/fan_curves.rs b/rog-profiles/src/fan_curve_set.rs similarity index 84% rename from rog-profiles/src/fan_curves.rs rename to rog-profiles/src/fan_curve_set.rs index dd8d0854..1ebd93e8 100644 --- a/rog-profiles/src/fan_curves.rs +++ b/rog-profiles/src/fan_curve_set.rs @@ -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 { let mut enumerator = udev::Enumerator::new()?; @@ -58,6 +76,14 @@ impl FanCurveSet { Err(ProfileError::NotSupported) } + pub fn is_supported() -> Result { + 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 { - 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); } -} \ No newline at end of file +} diff --git a/rog-profiles/src/lib.rs b/rog-profiles/src/lib.rs index 3bee4ae7..35a4b96a 100644 --- a/rog-profiles/src/lib.rs +++ b/rog-profiles/src/lib.rs @@ -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, 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(); } -} \ No newline at end of file +}