diff --git a/CHANGELOG.md b/CHANGELOG.md index 7826d1e7..ea943c42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Enable basic multiple user anime configs (asusd-user must still be restarted) + Profiles: - Enable dbus methods for freq min/max, fan curve, fan preset, CPU turbo enable. - These options will apply to the active profile if no profile name is specified. + These options will apply to the active profile if no profile name is specified. # [3.4.1] - 2021-04-11 ### Changed diff --git a/daemon/src/ctrl_gfx/gfx.rs b/daemon/src/ctrl_gfx/controller.rs similarity index 91% rename from daemon/src/ctrl_gfx/gfx.rs rename to daemon/src/ctrl_gfx/controller.rs index bf365e40..57fe324f 100644 --- a/daemon/src/ctrl_gfx/gfx.rs +++ b/daemon/src/ctrl_gfx/controller.rs @@ -14,8 +14,7 @@ use std::{str::FromStr, sync::mpsc}; use std::{sync::Arc, sync::Mutex}; use sysfs_class::{PciDevice, SysClass}; use system::{GraphicsDevice, PciBus}; -use zbus::{dbus_interface, Connection}; -use zvariant::ObjectPath; +use ::zbus::{Connection}; use crate::*; @@ -32,62 +31,6 @@ pub struct CtrlGraphics { thread_kill: Arc>>>, } -trait Dbus { - fn vendor(&self) -> zbus::fdo::Result; - fn power(&self) -> zbus::fdo::Result; - fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result; - fn notify_gfx(&self, vendor: &GfxVendors) -> zbus::Result<()>; - fn notify_action(&self, action: &GfxRequiredUserAction) -> zbus::Result<()>; -} - -#[dbus_interface(name = "org.asuslinux.Daemon")] -impl Dbus for CtrlGraphics { - fn vendor(&self) -> zbus::fdo::Result { - self.get_gfx_mode().map_err(|err| { - error!("GFX: {}", err); - zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) - }) - } - - fn power(&self) -> zbus::fdo::Result { - Self::get_runtime_status().map_err(|err| { - error!("GFX: {}", err); - zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) - }) - } - - fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result { - info!("GFX: Switching gfx mode to {}", <&str>::from(vendor)); - let msg = self.set_gfx_config(vendor).map_err(|err| { - error!("GFX: {}", err); - zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) - })?; - self.notify_gfx(&vendor) - .unwrap_or_else(|err| warn!("GFX: {}", err)); - self.notify_action(&msg) - .unwrap_or_else(|err| warn!("GFX: {}", err)); - Ok(msg) - } - - #[dbus_interface(signal)] - fn notify_gfx(&self, vendor: &GfxVendors) -> zbus::Result<()> {} - - #[dbus_interface(signal)] - fn notify_action(&self, action: &GfxRequiredUserAction) -> zbus::Result<()> {} -} - -impl ZbusAdd for CtrlGraphics { - fn add_to_server(self, server: &mut zbus::ObjectServer) { - server - .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Gfx"), self) - .map_err(|err| { - warn!("GFX: CtrlGraphics: add_to_server {}", err); - err - }) - .ok(); - } -} - impl Reloadable for CtrlGraphics { fn reload(&mut self) -> Result<(), RogError> { self.auto_power()?; @@ -183,7 +126,7 @@ impl CtrlGraphics { Ok(GfxVendors::Hybrid) } - fn get_runtime_status() -> Result { + pub(super) fn get_runtime_status() -> Result { let path = Path::new("/sys/bus/pci/devices/0000:01:00.0/power/runtime_status"); if path.exists() { let buf = std::fs::read_to_string(path).map_err(|err| { diff --git a/daemon/src/ctrl_gfx/mod.rs b/daemon/src/ctrl_gfx/mod.rs index 12bf963e..2a2e997b 100644 --- a/daemon/src/ctrl_gfx/mod.rs +++ b/daemon/src/ctrl_gfx/mod.rs @@ -1,9 +1,11 @@ pub mod error; -pub mod gfx; +pub mod controller; pub mod system; +pub mod zbus_gfx; + const NVIDIA_DRIVERS: [&str; 4] = ["nvidia_drm", "nvidia_modeset", "nvidia_uvm", "nvidia"]; const VFIO_DRIVERS: [&str; 5] = [ diff --git a/daemon/src/ctrl_gfx/zbus_gfx.rs b/daemon/src/ctrl_gfx/zbus_gfx.rs new file mode 100644 index 00000000..94391cbd --- /dev/null +++ b/daemon/src/ctrl_gfx/zbus_gfx.rs @@ -0,0 +1,56 @@ +use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}; +use ::zbus::{dbus_interface}; +use zvariant::ObjectPath; +use log::{error, warn, info}; + +use crate::ZbusAdd; + +use super::controller::CtrlGraphics; + +#[dbus_interface(name = "org.asuslinux.Daemon")] +impl CtrlGraphics { + fn vendor(&self) -> zbus::fdo::Result { + self.get_gfx_mode().map_err(|err| { + error!("GFX: {}", err); + zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) + }) + } + + fn power(&self) -> zbus::fdo::Result { + Self::get_runtime_status().map_err(|err| { + error!("GFX: {}", err); + zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) + }) + } + + fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result { + info!("GFX: Switching gfx mode to {}", <&str>::from(vendor)); + let msg = self.set_gfx_config(vendor).map_err(|err| { + error!("GFX: {}", err); + zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) + })?; + self.notify_gfx(&vendor) + .unwrap_or_else(|err| warn!("GFX: {}", err)); + self.notify_action(&msg) + .unwrap_or_else(|err| warn!("GFX: {}", err)); + Ok(msg) + } + + #[dbus_interface(signal)] + fn notify_gfx(&self, vendor: &GfxVendors) -> zbus::Result<()> {} + + #[dbus_interface(signal)] + fn notify_action(&self, action: &GfxRequiredUserAction) -> zbus::Result<()> {} +} + +impl ZbusAdd for CtrlGraphics { + fn add_to_server(self, server: &mut zbus::ObjectServer) { + server + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Gfx"), self) + .map_err(|err| { + warn!("GFX: CtrlGraphics: add_to_server {}", err); + err + }) + .ok(); + } +} \ No newline at end of file diff --git a/daemon/src/ctrl_profiles/controller.rs b/daemon/src/ctrl_profiles/controller.rs new file mode 100644 index 00000000..640bb409 --- /dev/null +++ b/daemon/src/ctrl_profiles/controller.rs @@ -0,0 +1,240 @@ +use crate::error::RogError; +use crate::{config::Config, GetSupported}; +use log::{info, warn}; +use rog_types::{ + profile::{FanLevel, Profile, ProfileEvent}, + supported::FanCpuSupportedFunctions, +}; +use std::fs::OpenOptions; +use std::io::Write; +use std::path::Path; +use std::sync::Arc; +use std::sync::Mutex; + +use super::*; + + +pub struct CtrlFanAndCpu { + pub path: &'static str, + pub config: Arc>, +} + +impl GetSupported for CtrlFanAndCpu { + type A = FanCpuSupportedFunctions; + + fn get_supported() -> Self::A { + FanCpuSupportedFunctions { + stock_fan_modes: CtrlFanAndCpu::get_fan_path().is_ok(), + min_max_freq: intel_pstate::PState::new().is_ok(), + fan_curve_set: rog_fan_curve::Board::from_board_name().is_some(), + } + } +} + +impl crate::Reloadable for CtrlFanAndCpu { + fn reload(&mut self) -> Result<(), RogError> { + if let Ok(mut config) = self.config.clone().try_lock() { + let profile = config.active_profile.clone(); + self.set(&profile, &mut config)?; + // info!( + // "Reloaded fan mode: {:?}", + // FanLevel::from(config.power_profile) + // ); + } + Ok(()) + } +} + +impl CtrlFanAndCpu { + pub fn new(config: Arc>) -> Result { + let path = CtrlFanAndCpu::get_fan_path()?; + info!("Device has thermal throttle control"); + Ok(CtrlFanAndCpu { path, config }) + } + + fn get_fan_path() -> Result<&'static str, RogError> { + if Path::new(FAN_TYPE_1_PATH).exists() { + Ok(FAN_TYPE_1_PATH) + } else if Path::new(FAN_TYPE_2_PATH).exists() { + Ok(FAN_TYPE_2_PATH) + } else { + Err(RogError::MissingFunction( + "Fan mode not available, you may require a v5.8.10 series kernel or newer".into(), + )) + } + } + + /// Toggle to next profile in list + pub(super) fn do_next_profile(&mut self, config: &mut Config) -> Result<(), RogError> { + config.read(); + + let mut i = config + .toggle_profiles + .iter() + .position(|x| x == &config.active_profile) + .map(|i| i + 1) + .unwrap_or(0); + if i >= config.toggle_profiles.len() { + i = 0; + } + + let new_profile = config + .toggle_profiles + .get(i) + .unwrap_or(&config.active_profile) + .clone(); + + self.set(&new_profile, config)?; + + info!("Profile was changed: {}", &new_profile); + Ok(()) + } + + fn set_fan_mode(&mut self, preset: u8, config: &mut Config) -> Result<(), RogError> { + let mode = config.active_profile.clone(); + let mut fan_ctrl = OpenOptions::new() + .write(true) + .open(self.path) + .map_err(|err| RogError::Path(self.path.into(), err))?; + config.read(); + let mut mode_config = config + .power_profiles + .get_mut(&mode) + .ok_or_else(|| RogError::MissingProfile(mode.clone()))?; + config.curr_fan_mode = preset; + mode_config.fan_preset = preset; + config.write(); + fan_ctrl + .write_all(format!("{}\n", preset).as_bytes()) + .map_err(|err| RogError::Write(self.path.into(), err))?; + info!("Fan mode set to: {:?}", FanLevel::from(preset)); + Ok(()) + } + + pub(super) fn handle_profile_event( + &mut self, + event: &ProfileEvent, + config: &mut Config, + ) -> Result<(), RogError> { + match event { + ProfileEvent::Toggle => self.do_next_profile(config)?, + ProfileEvent::ChangeMode(mode) => { + self.set_fan_mode(*mode, config)?; + let mode = config.active_profile.clone(); + self.set_pstate_for_fan_mode(&mode, config)?; + self.set_fan_curve_for_fan_mode(&mode, config)?; + } + ProfileEvent::Cli(command) => { + let profile_key = match command.profile.as_ref() { + Some(k) => k.clone(), + None => config.active_profile.clone(), + }; + + let mut profile = if command.create { + config + .power_profiles + .entry(profile_key.clone()) + .or_insert_with(Profile::default) + } else { + config + .power_profiles + .get_mut(&profile_key) + .ok_or_else(|| RogError::MissingProfile(profile_key.clone()))? + }; + + if command.turbo.is_some() { + profile.turbo = command.turbo.unwrap(); + } + if let Some(min_perc) = command.min_percentage { + profile.min_percentage = min_perc; + } + if let Some(max_perc) = command.max_percentage { + profile.max_percentage = max_perc; + } + if let Some(ref preset) = command.fan_preset { + profile.fan_preset = preset.into(); + } + if let Some(ref curve) = command.curve { + profile.fan_curve = Some(curve.clone()); + } + + self.set(&profile_key, config)?; + } + } + Ok(()) + } + + pub(super) fn set(&mut self, profile: &str, config: &mut Config) -> Result<(), RogError> { + let mode_config = config + .power_profiles + .get(profile) + .ok_or_else(|| RogError::MissingProfile(profile.into()))?; + let mut fan_ctrl = OpenOptions::new() + .write(true) + .open(self.path) + .map_err(|err| RogError::Path(self.path.into(), err))?; + config.curr_fan_mode = mode_config.fan_preset; + fan_ctrl + .write_all(format!("{}\n", mode_config.fan_preset).as_bytes()) + .map_err(|err| RogError::Write(self.path.into(), err))?; + + self.set_pstate_for_fan_mode(profile, config)?; + self.set_fan_curve_for_fan_mode(profile, config)?; + + config.active_profile = profile.into(); + + config.write(); + Ok(()) + } + + fn set_pstate_for_fan_mode(&self, mode: &str, config: &mut Config) -> Result<(), RogError> { + info!("Setting pstate"); + let mode_config = config + .power_profiles + .get(mode) + .ok_or_else(|| RogError::MissingProfile(mode.into()))?; + + // Set CPU pstate + if let Ok(pstate) = intel_pstate::PState::new() { + pstate.set_min_perf_pct(mode_config.min_percentage)?; + pstate.set_max_perf_pct(mode_config.max_percentage)?; + pstate.set_no_turbo(!mode_config.turbo)?; + info!( + "Intel CPU Power: min: {}%, max: {}%, turbo: {}", + mode_config.min_percentage, mode_config.max_percentage, mode_config.turbo + ); + } else { + info!("Setting pstate for AMD CPU"); + // must be AMD CPU + let mut file = OpenOptions::new() + .write(true) + .open(AMD_BOOST_PATH) + .map_err(|err| RogError::Path(self.path.into(), err))?; + + let boost = if mode_config.turbo { "1" } else { "0" }; // opposite of Intel + file.write_all(boost.as_bytes()) + .map_err(|err| RogError::Write(AMD_BOOST_PATH.into(), err))?; + info!("AMD CPU Turbo: {}", boost); + } + Ok(()) + } + + fn set_fan_curve_for_fan_mode(&self, mode: &str, config: &Config) -> Result<(), RogError> { + let mode_config = &config + .power_profiles + .get(mode) + .ok_or_else(|| RogError::MissingProfile(mode.into()))?; + + if let Some(ref curve) = mode_config.fan_curve { + use rog_fan_curve::{Board, Fan}; + if let Some(board) = Board::from_board_name() { + curve.apply(board, Fan::Cpu)?; + curve.apply(board, Fan::Gpu)?; + } else { + warn!("Fan curve unsupported on this board.") + } + } + + Ok(()) + } +} diff --git a/daemon/src/ctrl_profiles/mod.rs b/daemon/src/ctrl_profiles/mod.rs index 80dd7907..ffd9ec54 100644 --- a/daemon/src/ctrl_profiles/mod.rs +++ b/daemon/src/ctrl_profiles/mod.rs @@ -1,243 +1,7 @@ pub mod zbus; -use crate::error::RogError; -use crate::{config::Config, GetSupported}; -use log::{info, warn}; -use rog_types::{ - profile::{FanLevel, Profile, ProfileEvent}, - supported::FanCpuSupportedFunctions, -}; -use std::fs::OpenOptions; -use std::io::Write; -use std::path::Path; -use std::sync::Arc; -use std::sync::Mutex; +pub mod controller; static FAN_TYPE_1_PATH: &str = "/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy"; static FAN_TYPE_2_PATH: &str = "/sys/devices/platform/asus-nb-wmi/fan_boost_mode"; static AMD_BOOST_PATH: &str = "/sys/devices/system/cpu/cpufreq/boost"; - -pub struct CtrlFanAndCpu { - pub path: &'static str, - config: Arc>, -} - -impl GetSupported for CtrlFanAndCpu { - type A = FanCpuSupportedFunctions; - - fn get_supported() -> Self::A { - FanCpuSupportedFunctions { - stock_fan_modes: CtrlFanAndCpu::get_fan_path().is_ok(), - min_max_freq: intel_pstate::PState::new().is_ok(), - fan_curve_set: rog_fan_curve::Board::from_board_name().is_some(), - } - } -} - -impl crate::Reloadable for CtrlFanAndCpu { - fn reload(&mut self) -> Result<(), RogError> { - if let Ok(mut config) = self.config.clone().try_lock() { - let profile = config.active_profile.clone(); - self.set(&profile, &mut config)?; - // info!( - // "Reloaded fan mode: {:?}", - // FanLevel::from(config.power_profile) - // ); - } - Ok(()) - } -} - -impl CtrlFanAndCpu { - pub fn new(config: Arc>) -> Result { - let path = CtrlFanAndCpu::get_fan_path()?; - info!("Device has thermal throttle control"); - Ok(CtrlFanAndCpu { path, config }) - } - - fn get_fan_path() -> Result<&'static str, RogError> { - if Path::new(FAN_TYPE_1_PATH).exists() { - Ok(FAN_TYPE_1_PATH) - } else if Path::new(FAN_TYPE_2_PATH).exists() { - Ok(FAN_TYPE_2_PATH) - } else { - Err(RogError::MissingFunction( - "Fan mode not available, you may require a v5.8.10 series kernel or newer".into(), - )) - } - } - - /// Toggle to next profile in list - pub(super) fn do_next_profile(&mut self, config: &mut Config) -> Result<(), RogError> { - config.read(); - - let mut i = config - .toggle_profiles - .iter() - .position(|x| x == &config.active_profile) - .map(|i| i + 1) - .unwrap_or(0); - if i >= config.toggle_profiles.len() { - i = 0; - } - - let new_profile = config - .toggle_profiles - .get(i) - .unwrap_or(&config.active_profile) - .clone(); - - self.set(&new_profile, config)?; - - info!("Profile was changed: {}", &new_profile); - Ok(()) - } - - fn set_fan_mode(&mut self, preset: u8, config: &mut Config) -> Result<(), RogError> { - let mode = config.active_profile.clone(); - let mut fan_ctrl = OpenOptions::new() - .write(true) - .open(self.path) - .map_err(|err| RogError::Path(self.path.into(), err))?; - config.read(); - let mut mode_config = config - .power_profiles - .get_mut(&mode) - .ok_or_else(|| RogError::MissingProfile(mode.clone()))?; - config.curr_fan_mode = preset; - mode_config.fan_preset = preset; - config.write(); - fan_ctrl - .write_all(format!("{}\n", preset).as_bytes()) - .map_err(|err| RogError::Write(self.path.into(), err))?; - info!("Fan mode set to: {:?}", FanLevel::from(preset)); - Ok(()) - } - - fn handle_profile_event( - &mut self, - event: &ProfileEvent, - config: &mut Config, - ) -> Result<(), RogError> { - match event { - ProfileEvent::Toggle => self.do_next_profile(config)?, - ProfileEvent::ChangeMode(mode) => { - self.set_fan_mode(*mode, config)?; - let mode = config.active_profile.clone(); - self.set_pstate_for_fan_mode(&mode, config)?; - self.set_fan_curve_for_fan_mode(&mode, config)?; - } - ProfileEvent::Cli(command) => { - let profile_key = match command.profile.as_ref() { - Some(k) => k.clone(), - None => config.active_profile.clone(), - }; - - let mut profile = if command.create { - config - .power_profiles - .entry(profile_key.clone()) - .or_insert_with(Profile::default) - } else { - config - .power_profiles - .get_mut(&profile_key) - .ok_or_else(|| RogError::MissingProfile(profile_key.clone()))? - }; - - if command.turbo.is_some() { - profile.turbo = command.turbo.unwrap(); - } - if let Some(min_perc) = command.min_percentage { - profile.min_percentage = min_perc; - } - if let Some(max_perc) = command.max_percentage { - profile.max_percentage = max_perc; - } - if let Some(ref preset) = command.fan_preset { - profile.fan_preset = preset.into(); - } - if let Some(ref curve) = command.curve { - profile.fan_curve = Some(curve.clone()); - } - - self.set(&profile_key, config)?; - } - } - Ok(()) - } - - fn set(&mut self, profile: &str, config: &mut Config) -> Result<(), RogError> { - let mode_config = config - .power_profiles - .get(profile) - .ok_or_else(|| RogError::MissingProfile(profile.into()))?; - let mut fan_ctrl = OpenOptions::new() - .write(true) - .open(self.path) - .map_err(|err| RogError::Path(self.path.into(), err))?; - config.curr_fan_mode = mode_config.fan_preset; - fan_ctrl - .write_all(format!("{}\n", mode_config.fan_preset).as_bytes()) - .map_err(|err| RogError::Write(self.path.into(), err))?; - - self.set_pstate_for_fan_mode(profile, config)?; - self.set_fan_curve_for_fan_mode(profile, config)?; - - config.active_profile = profile.into(); - - config.write(); - Ok(()) - } - - fn set_pstate_for_fan_mode(&self, mode: &str, config: &mut Config) -> Result<(), RogError> { - info!("Setting pstate"); - let mode_config = config - .power_profiles - .get(mode) - .ok_or_else(|| RogError::MissingProfile(mode.into()))?; - - // Set CPU pstate - if let Ok(pstate) = intel_pstate::PState::new() { - pstate.set_min_perf_pct(mode_config.min_percentage)?; - pstate.set_max_perf_pct(mode_config.max_percentage)?; - pstate.set_no_turbo(!mode_config.turbo)?; - info!( - "Intel CPU Power: min: {}%, max: {}%, turbo: {}", - mode_config.min_percentage, mode_config.max_percentage, mode_config.turbo - ); - } else { - info!("Setting pstate for AMD CPU"); - // must be AMD CPU - let mut file = OpenOptions::new() - .write(true) - .open(AMD_BOOST_PATH) - .map_err(|err| RogError::Path(self.path.into(), err))?; - - let boost = if mode_config.turbo { "1" } else { "0" }; // opposite of Intel - file.write_all(boost.as_bytes()) - .map_err(|err| RogError::Write(AMD_BOOST_PATH.into(), err))?; - info!("AMD CPU Turbo: {}", boost); - } - Ok(()) - } - - fn set_fan_curve_for_fan_mode(&self, mode: &str, config: &Config) -> Result<(), RogError> { - let mode_config = &config - .power_profiles - .get(mode) - .ok_or_else(|| RogError::MissingProfile(mode.into()))?; - - if let Some(ref curve) = mode_config.fan_curve { - use rog_fan_curve::{Board, Fan}; - if let Some(board) = Board::from_board_name() { - curve.apply(board, Fan::Cpu)?; - curve.apply(board, Fan::Gpu)?; - } else { - warn!("Fan curve unsupported on this board.") - } - } - - Ok(()) - } -} diff --git a/daemon/src/ctrl_profiles/zbus.rs b/daemon/src/ctrl_profiles/zbus.rs index aa07b63b..dcd688fd 100644 --- a/daemon/src/ctrl_profiles/zbus.rs +++ b/daemon/src/ctrl_profiles/zbus.rs @@ -6,7 +6,7 @@ use std::sync::Mutex; use zbus::{dbus_interface, fdo::Error}; use zvariant::ObjectPath; -use super::CtrlFanAndCpu; +use super::controller::CtrlFanAndCpu; pub struct FanAndCpuZbus { inner: Arc>, diff --git a/daemon/src/ctrl_supported.rs b/daemon/src/ctrl_supported.rs index f3c13a26..9b05e472 100644 --- a/daemon/src/ctrl_supported.rs +++ b/daemon/src/ctrl_supported.rs @@ -3,10 +3,7 @@ use serde_derive::{Deserialize, Serialize}; use zbus::dbus_interface; use zvariant::ObjectPath; -use crate::{ - ctrl_anime::CtrlAnime, ctrl_charge::CtrlCharge, ctrl_leds::CtrlKbdLed, - ctrl_profiles::CtrlFanAndCpu, ctrl_rog_bios::CtrlRogBios, GetSupported, -}; +use crate::{GetSupported, ctrl_anime::CtrlAnime, ctrl_charge::CtrlCharge, ctrl_leds::CtrlKbdLed, ctrl_profiles::controller::CtrlFanAndCpu, ctrl_rog_bios::CtrlRogBios}; use rog_types::supported::{ AnimeSupportedFunctions, ChargeSupportedFunctions, FanCpuSupportedFunctions, diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index 0bac8d69..f0d9d5ee 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -3,9 +3,9 @@ use daemon::{ config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported, }; use daemon::{config_anime::AnimeConfig, config_aura::AuraConfig, ctrl_charge::CtrlCharge}; -use daemon::{ctrl_anime::*, ctrl_gfx::gfx::CtrlGraphics}; +use daemon::{ctrl_anime::*, ctrl_gfx::controller::CtrlGraphics}; use daemon::{ - ctrl_profiles::{zbus::FanAndCpuZbus, CtrlFanAndCpu}, + ctrl_profiles::{zbus::FanAndCpuZbus, controller::CtrlFanAndCpu}, laptops::LaptopLedData, };