mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Update config & dbus parts, cleanup deps, device power states
- Add extra config options and dbus methods - Add power state signals for anime and led - Refactor to use channels for dbus signal handler send/recv - Split out profiles independant parts to a rog-profiles crate - Cleanup dependencies - Fix some dbus Supported issues
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use log::{error, info, warn};
|
||||
use rog_types::{gfx_vendors::GfxVendors, profile::Profile};
|
||||
use rog_profiles::profiles::{FanLevel, Profile};
|
||||
use rog_types::gfx_vendors::GfxVendors;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::{File, OpenOptions};
|
||||
@@ -30,9 +31,39 @@ pub struct Config {
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
let mut pwr = BTreeMap::new();
|
||||
pwr.insert("normal".into(), Profile::new(0, 100, true, 0, None));
|
||||
pwr.insert("boost".into(), Profile::new(0, 100, true, 1, None));
|
||||
pwr.insert("silent".into(), Profile::new(0, 100, true, 2, None));
|
||||
pwr.insert(
|
||||
"normal".into(),
|
||||
Profile::new(
|
||||
"normal".into(),
|
||||
0,
|
||||
100,
|
||||
true,
|
||||
FanLevel::Normal,
|
||||
"".to_string(),
|
||||
),
|
||||
);
|
||||
pwr.insert(
|
||||
"boost".into(),
|
||||
Profile::new(
|
||||
"boost".into(),
|
||||
0,
|
||||
100,
|
||||
true,
|
||||
FanLevel::Boost,
|
||||
"".to_string(),
|
||||
),
|
||||
);
|
||||
pwr.insert(
|
||||
"silent".into(),
|
||||
Profile::new(
|
||||
"silent".into(),
|
||||
0,
|
||||
100,
|
||||
true,
|
||||
FanLevel::Silent,
|
||||
"".to_string(),
|
||||
),
|
||||
);
|
||||
|
||||
Config {
|
||||
gfx_mode: GfxVendors::Hybrid,
|
||||
|
||||
@@ -41,6 +41,31 @@ impl AnimeConfigV341 {
|
||||
vec![]
|
||||
},
|
||||
brightness: 1.0,
|
||||
awake_enabled: true,
|
||||
boot_anim_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AnimeConfigV352 {
|
||||
pub system: Vec<AnimeAction>,
|
||||
pub boot: Vec<AnimeAction>,
|
||||
pub wake: Vec<AnimeAction>,
|
||||
pub shutdown: Vec<AnimeAction>,
|
||||
pub brightness: f32,
|
||||
}
|
||||
|
||||
impl AnimeConfigV352 {
|
||||
pub(crate) fn into_current(self) -> AnimeConfig {
|
||||
AnimeConfig {
|
||||
system: self.system,
|
||||
boot: self.boot,
|
||||
wake: self.wake,
|
||||
shutdown: self.shutdown,
|
||||
brightness: 1.0,
|
||||
awake_enabled: true,
|
||||
boot_anim_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,6 +115,8 @@ pub struct AnimeConfig {
|
||||
pub wake: Vec<AnimeAction>,
|
||||
pub shutdown: Vec<AnimeAction>,
|
||||
pub brightness: f32,
|
||||
pub awake_enabled: bool,
|
||||
pub boot_anim_enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for AnimeConfig {
|
||||
@@ -100,6 +127,8 @@ impl Default for AnimeConfig {
|
||||
wake: Vec::new(),
|
||||
shutdown: Vec::new(),
|
||||
brightness: 1.0,
|
||||
awake_enabled: true,
|
||||
boot_anim_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,6 +159,11 @@ impl AnimeConfig {
|
||||
config.write();
|
||||
info!("Updated config version to: {}", VERSION);
|
||||
return config;
|
||||
} else if let Ok(data) = serde_json::from_str::<AnimeConfigV352>(&buf) {
|
||||
let config = data.into_current();
|
||||
config.write();
|
||||
info!("Updated config version to: {}", VERSION);
|
||||
return config;
|
||||
}
|
||||
warn!("Could not deserialise {}", ANIME_CONFIG_PATH);
|
||||
panic!("Please remove {} then restart asusd", ANIME_CONFIG_PATH);
|
||||
@@ -167,6 +201,8 @@ impl AnimeConfig {
|
||||
time: AnimTime::Infinite,
|
||||
}],
|
||||
brightness: 1.0,
|
||||
awake_enabled: true,
|
||||
boot_anim_enabled: true,
|
||||
};
|
||||
// Should be okay to unwrap this as is since it is a Default
|
||||
let json = serde_json::to_string_pretty(&config).unwrap();
|
||||
|
||||
@@ -23,6 +23,29 @@ impl AuraConfigV320 {
|
||||
current_mode: self.current_mode,
|
||||
builtins: self.builtins,
|
||||
multizone: self.multizone,
|
||||
awake_enabled: true,
|
||||
sleep_anim_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct AuraConfigV352 {
|
||||
pub brightness: LedBrightness,
|
||||
pub current_mode: AuraModeNum,
|
||||
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
|
||||
pub multizone: Option<AuraMultiZone>,
|
||||
}
|
||||
|
||||
impl AuraConfigV352 {
|
||||
pub(crate) fn into_current(self) -> AuraConfig {
|
||||
AuraConfig {
|
||||
brightness: self.brightness,
|
||||
current_mode: self.current_mode,
|
||||
builtins: self.builtins,
|
||||
multizone: self.multizone,
|
||||
awake_enabled: true,
|
||||
sleep_anim_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +56,8 @@ pub struct AuraConfig {
|
||||
pub current_mode: AuraModeNum,
|
||||
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
|
||||
pub multizone: Option<AuraMultiZone>,
|
||||
pub awake_enabled: bool,
|
||||
pub sleep_anim_enabled: bool,
|
||||
}
|
||||
|
||||
impl Default for AuraConfig {
|
||||
@@ -42,6 +67,8 @@ impl Default for AuraConfig {
|
||||
current_mode: AuraModeNum::Static,
|
||||
builtins: BTreeMap::new(),
|
||||
multizone: None,
|
||||
awake_enabled: true,
|
||||
sleep_anim_enabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,6 +99,11 @@ impl AuraConfig {
|
||||
config.write();
|
||||
info!("Updated AuraConfig version");
|
||||
return config;
|
||||
} else if let Ok(data) = serde_json::from_str::<AuraConfigV352>(&buf) {
|
||||
let config = data.into_current();
|
||||
config.write();
|
||||
info!("Updated AuraConfig version");
|
||||
return config;
|
||||
}
|
||||
warn!("Could not deserialise {}", AURA_CONFIG_PATH);
|
||||
panic!("Please remove {} then restart asusd", AURA_CONFIG_PATH);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use rog_types::{gfx_vendors::GfxVendors, profile::Profile};
|
||||
use rog_fan_curve::Curve;
|
||||
use rog_profiles::profiles::Profile;
|
||||
use rog_types::gfx_vendors::GfxVendors;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
/// for parsing old v3.1.7 config
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Deserialize)]
|
||||
pub(crate) struct ConfigV317 {
|
||||
pub gfx_mode: GfxVendors,
|
||||
pub gfx_managed: bool,
|
||||
@@ -18,7 +20,7 @@ pub(crate) struct ConfigV317 {
|
||||
pub kbd_backlight_mode: u8,
|
||||
#[serde(skip)]
|
||||
pub kbd_backlight_modes: Option<bool>,
|
||||
pub power_profiles: BTreeMap<String, Profile>,
|
||||
pub power_profiles: BTreeMap<String, ProfileV317>,
|
||||
}
|
||||
|
||||
impl ConfigV317 {
|
||||
@@ -32,7 +34,7 @@ impl ConfigV317 {
|
||||
toggle_profiles: self.toggle_profiles,
|
||||
curr_fan_mode: self.curr_fan_mode,
|
||||
bat_charge_limit: self.bat_charge_limit,
|
||||
power_profiles: self.power_profiles,
|
||||
power_profiles: ProfileV317::transform_map(self.power_profiles),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +48,7 @@ pub struct ConfigV324 {
|
||||
#[serde(skip)]
|
||||
pub curr_fan_mode: u8,
|
||||
pub bat_charge_limit: u8,
|
||||
pub power_profiles: BTreeMap<String, Profile>,
|
||||
pub power_profiles: BTreeMap<String, ProfileV317>,
|
||||
}
|
||||
|
||||
impl ConfigV324 {
|
||||
@@ -60,7 +62,7 @@ impl ConfigV324 {
|
||||
toggle_profiles: self.toggle_profiles,
|
||||
curr_fan_mode: self.curr_fan_mode,
|
||||
bat_charge_limit: self.bat_charge_limit,
|
||||
power_profiles: self.power_profiles,
|
||||
power_profiles: ProfileV317::transform_map(self.power_profiles),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +77,7 @@ pub struct ConfigV341 {
|
||||
#[serde(skip)]
|
||||
pub curr_fan_mode: u8,
|
||||
pub bat_charge_limit: u8,
|
||||
pub power_profiles: BTreeMap<String, Profile>,
|
||||
pub power_profiles: BTreeMap<String, ProfileV317>,
|
||||
}
|
||||
|
||||
impl ConfigV341 {
|
||||
@@ -89,12 +91,11 @@ impl ConfigV341 {
|
||||
toggle_profiles: self.toggle_profiles,
|
||||
curr_fan_mode: self.curr_fan_mode,
|
||||
bat_charge_limit: self.bat_charge_limit,
|
||||
power_profiles: self.power_profiles,
|
||||
power_profiles: ProfileV317::transform_map(self.power_profiles),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct ConfigV352 {
|
||||
pub gfx_mode: GfxVendors,
|
||||
@@ -107,7 +108,7 @@ pub struct ConfigV352 {
|
||||
#[serde(skip)]
|
||||
pub curr_fan_mode: u8,
|
||||
pub bat_charge_limit: u8,
|
||||
pub power_profiles: BTreeMap<String, Profile>,
|
||||
pub power_profiles: BTreeMap<String, ProfileV317>,
|
||||
}
|
||||
|
||||
impl ConfigV352 {
|
||||
@@ -121,7 +122,39 @@ impl ConfigV352 {
|
||||
toggle_profiles: self.toggle_profiles,
|
||||
curr_fan_mode: self.curr_fan_mode,
|
||||
bat_charge_limit: self.bat_charge_limit,
|
||||
power_profiles: self.power_profiles,
|
||||
power_profiles: ProfileV317::transform_map(self.power_profiles),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct ProfileV317 {
|
||||
pub min_percentage: u8,
|
||||
pub max_percentage: u8,
|
||||
pub turbo: bool,
|
||||
pub fan_preset: u8,
|
||||
pub fan_curve: Option<Curve>,
|
||||
}
|
||||
|
||||
impl ProfileV317 {
|
||||
fn into_current(self, name: String) -> Profile {
|
||||
Profile {
|
||||
name,
|
||||
min_percentage: self.min_percentage,
|
||||
max_percentage: self.max_percentage,
|
||||
turbo: self.turbo,
|
||||
fan_preset: self.fan_preset.into(),
|
||||
fan_curve: self
|
||||
.fan_curve
|
||||
.map_or_else(|| "".to_string(), |c| c.as_config_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn transform_map(map: BTreeMap<String, ProfileV317>) -> BTreeMap<String, Profile> {
|
||||
let mut new_map = BTreeMap::new();
|
||||
map.iter().for_each(|(k, v)| {
|
||||
new_map.insert(k.to_string(), v.clone().into_current(k.to_string()));
|
||||
});
|
||||
new_map
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use rog_anime::{
|
||||
pkt_for_apply, pkt_for_flush, pkt_for_set_boot, pkt_for_set_on, pkts_for_init, PROD_ID,
|
||||
VENDOR_ID,
|
||||
},
|
||||
ActionData, AnimTime, AnimeDataBuffer, AnimePacketType, ANIME_DATA_LEN,
|
||||
ActionData, AnimTime, AnimeDataBuffer, AnimePacketType, AnimePowerStates, ANIME_DATA_LEN,
|
||||
};
|
||||
use rog_types::supported::AnimeSupportedFunctions;
|
||||
use rusb::{Device, DeviceHandle};
|
||||
@@ -333,6 +333,11 @@ pub struct CtrlAnimeReloader(pub Arc<Mutex<CtrlAnime>>);
|
||||
impl crate::Reloadable for CtrlAnimeReloader {
|
||||
fn reload(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(lock) = self.0.try_lock() {
|
||||
lock.write_bytes(&pkt_for_set_on(lock.config.awake_enabled));
|
||||
lock.write_bytes(&pkt_for_apply());
|
||||
lock.write_bytes(&pkt_for_set_boot(lock.config.boot_anim_enabled));
|
||||
lock.write_bytes(&pkt_for_apply());
|
||||
|
||||
let action = lock.cache.boot.clone();
|
||||
CtrlAnime::run_thread(self.0.clone(), action, true);
|
||||
}
|
||||
@@ -392,8 +397,17 @@ impl CtrlAnimeZbus {
|
||||
|
||||
fn set_on_off(&self, status: bool) {
|
||||
'outer: loop {
|
||||
if let Ok(lock) = self.0.try_lock() {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
lock.write_bytes(&pkt_for_set_on(status));
|
||||
lock.config.awake_enabled = status;
|
||||
lock.config.write();
|
||||
|
||||
let states = AnimePowerStates {
|
||||
enabled: lock.config.awake_enabled,
|
||||
boot_anim_enabled: lock.config.boot_anim_enabled,
|
||||
};
|
||||
self.notify_power_states(&states)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
@@ -401,9 +415,18 @@ impl CtrlAnimeZbus {
|
||||
|
||||
fn set_boot_on_off(&self, on: bool) {
|
||||
'outer: loop {
|
||||
if let Ok(lock) = self.0.try_lock() {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
lock.write_bytes(&pkt_for_set_boot(on));
|
||||
lock.write_bytes(&pkt_for_apply());
|
||||
lock.config.boot_anim_enabled = on;
|
||||
lock.config.write();
|
||||
|
||||
let states = AnimePowerStates {
|
||||
enabled: lock.config.awake_enabled,
|
||||
boot_anim_enabled: lock.config.boot_anim_enabled,
|
||||
};
|
||||
self.notify_power_states(&states)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
@@ -422,4 +445,23 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn awake_enabled(&self) -> bool {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
return ctrl.config.awake_enabled;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn boot_enabled(&self) -> bool {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
return ctrl.config.boot_anim_enabled;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_power_states(&self, data: &AnimePowerStates) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ impl CtrlGraphics {
|
||||
pub fn get_gfx_mode(&self) -> Result<GfxVendors, RogError> {
|
||||
if let Ok(config) = self.config.lock() {
|
||||
if let Some(mode) = config.gfx_tmp_mode {
|
||||
return Ok(mode);
|
||||
return Ok(mode);
|
||||
}
|
||||
return Ok(config.gfx_mode);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use ::zbus::dbus_interface;
|
||||
use log::{error, info, warn};
|
||||
use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors};
|
||||
use ::zbus::{dbus_interface};
|
||||
use zvariant::ObjectPath;
|
||||
use log::{error, warn, info};
|
||||
|
||||
use crate::ZbusAdd;
|
||||
|
||||
@@ -53,4 +53,4 @@ impl ZbusAdd for CtrlGraphics {
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,12 @@ use crate::{
|
||||
error::RogError,
|
||||
laptops::{LaptopLedData, ASUS_KEYBOARD_DEVICES},
|
||||
};
|
||||
use log::{error, info, warn};
|
||||
use log::{info, warn};
|
||||
use rog_aura::{
|
||||
usb::{LED_APPLY, LED_AWAKE_OFF, LED_AWAKE_ON, LED_SET, LED_SLEEP_OFF, LED_SLEEP_ON},
|
||||
usb::{
|
||||
LED_APPLY, LED_AWAKE_OFF_SLEEP_OFF, LED_AWAKE_OFF_SLEEP_ON, LED_AWAKE_ON_SLEEP_OFF,
|
||||
LED_AWAKE_ON_SLEEP_ON, LED_SET,
|
||||
},
|
||||
AuraEffect, LedBrightness, LED_MSG_LEN,
|
||||
};
|
||||
use rog_types::supported::LedSupportedFunctions;
|
||||
@@ -17,8 +20,6 @@ use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use zbus::dbus_interface;
|
||||
use zvariant::ObjectPath;
|
||||
|
||||
use crate::GetSupported;
|
||||
|
||||
@@ -30,11 +31,7 @@ impl GetSupported for CtrlKbdLed {
|
||||
let multizone_led_mode = false;
|
||||
let per_key_led_mode = false;
|
||||
let laptop = LaptopLedData::get_data();
|
||||
let stock_led_modes = if laptop.standard.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(laptop.standard)
|
||||
};
|
||||
let stock_led_modes = laptop.standard;
|
||||
|
||||
LedSupportedFunctions {
|
||||
brightness_set: CtrlKbdLed::get_kbd_bright_path().is_some(),
|
||||
@@ -46,11 +43,11 @@ impl GetSupported for CtrlKbdLed {
|
||||
}
|
||||
|
||||
pub struct CtrlKbdLed {
|
||||
led_node: Option<String>,
|
||||
pub led_node: Option<String>,
|
||||
pub bright_node: String,
|
||||
supported_modes: LaptopLedData,
|
||||
flip_effect_write: bool,
|
||||
config: AuraConfig,
|
||||
pub supported_modes: LaptopLedData,
|
||||
pub flip_effect_write: bool,
|
||||
pub config: AuraConfig,
|
||||
}
|
||||
|
||||
pub struct CtrlKbdLedTask(pub Arc<Mutex<CtrlKbdLed>>);
|
||||
@@ -88,151 +85,28 @@ pub struct CtrlKbdLedReloader(pub Arc<Mutex<CtrlKbdLed>>);
|
||||
|
||||
impl crate::Reloadable for CtrlKbdLedReloader {
|
||||
fn reload(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(mut lock) = self.0.try_lock() {
|
||||
let current = lock.config.current_mode;
|
||||
if let Some(mode) = lock.config.builtins.get(¤t).cloned() {
|
||||
lock.do_command(mode).ok();
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
let current = ctrl.config.current_mode;
|
||||
if let Some(mode) = ctrl.config.builtins.get(¤t).cloned() {
|
||||
ctrl.do_command(mode).ok();
|
||||
}
|
||||
|
||||
ctrl.set_states_enabled(ctrl.config.awake_enabled, ctrl.config.sleep_anim_enabled)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CtrlKbdLedZbus {
|
||||
inner: Arc<Mutex<CtrlKbdLed>>,
|
||||
}
|
||||
pub struct CtrlKbdLedZbus(pub Arc<Mutex<CtrlKbdLed>>);
|
||||
|
||||
impl CtrlKbdLedZbus {
|
||||
pub fn new(inner: Arc<Mutex<CtrlKbdLed>>) -> Self {
|
||||
Self { inner }
|
||||
Self(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ZbusAdd for CtrlKbdLedZbus {
|
||||
fn add_to_server(self, server: &mut zbus::ObjectServer) {
|
||||
server
|
||||
.at(&ObjectPath::from_str_unchecked("/org/asuslinux/Led"), self)
|
||||
.map_err(|err| {
|
||||
error!("DbusKbdLed: add_to_server {}", err);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
/// The main interface for changing, reading, or notfying signals
|
||||
///
|
||||
/// LED commands are split between Brightness, Modes, Per-Key
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlKbdLedZbus {
|
||||
/// Set the keyboard brightness level (0-3)
|
||||
fn set_brightness(&mut self, brightness: LedBrightness) {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
ctrl.set_brightness(brightness)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the keyboard LED to enabled while the device is awake
|
||||
fn set_awake_enabled(&mut self, enabled: bool) {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
ctrl.set_awake_enable(enabled)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the keyboard LED suspend animation to enabled while the device is suspended
|
||||
fn set_sleep_enabled(&mut self, enabled: bool) {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
ctrl.set_sleep_anim_enable(enabled)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn set_led_mode(&mut self, effect: AuraEffect) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
let mode_name = effect.mode_name();
|
||||
match ctrl.do_command(effect) {
|
||||
Ok(_) => {
|
||||
self.notify_led(&mode_name).ok();
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("{}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next_led_mode(&self) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
ctrl.toggle_mode(false)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
if let Ok(json) = serde_json::to_string(&mode) {
|
||||
self.notify_led(&json)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prev_led_mode(&self) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
ctrl.toggle_mode(true)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
if let Ok(json) = serde_json::to_string(&mode) {
|
||||
self.notify_led(&json)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the current mode data
|
||||
#[dbus_interface(property)]
|
||||
fn led_mode(&self) -> String {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
if let Ok(json) = serde_json::to_string(&mode) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
||||
warn!("SetKeyBacklight could not deserialise");
|
||||
"SetKeyBacklight could not deserialise".to_string()
|
||||
}
|
||||
|
||||
/// Return a list of available modes
|
||||
#[dbus_interface(property)]
|
||||
fn led_modes(&self) -> String {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(json) = serde_json::to_string(&ctrl.config.builtins) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
warn!("SetKeyBacklight could not deserialise");
|
||||
"SetKeyBacklight could not serialise".to_string()
|
||||
}
|
||||
|
||||
/// Return the current LED brightness
|
||||
#[dbus_interface(property)]
|
||||
fn led_brightness(&self) -> i8 {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
return ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1);
|
||||
}
|
||||
warn!("SetKeyBacklight could not serialise");
|
||||
-1
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_led(&self, data: &str) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
impl CtrlKbdLed {
|
||||
#[inline]
|
||||
pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result<Self, RogError> {
|
||||
@@ -280,7 +154,7 @@ impl CtrlKbdLed {
|
||||
None
|
||||
}
|
||||
|
||||
fn get_brightness(&self) -> Result<u8, RogError> {
|
||||
pub(super) fn get_brightness(&self) -> Result<u8, RogError> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open(&self.bright_node)
|
||||
@@ -296,7 +170,7 @@ impl CtrlKbdLed {
|
||||
Ok(buf[0])
|
||||
}
|
||||
|
||||
fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> {
|
||||
pub(super) fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> {
|
||||
let path = Path::new(&self.bright_node);
|
||||
let mut file =
|
||||
OpenOptions::new()
|
||||
@@ -313,19 +187,19 @@ impl CtrlKbdLed {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the keyboard LED to active if laptop is awake
|
||||
fn set_awake_enable(&self, enabled: bool) -> Result<(), RogError> {
|
||||
let bytes = if enabled { LED_AWAKE_ON } else { LED_AWAKE_OFF };
|
||||
self.write_bytes(&bytes)?;
|
||||
self.write_bytes(&LED_SET)?;
|
||||
// Changes won't persist unless apply is set
|
||||
self.write_bytes(&LED_APPLY)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the keyboard suspend animation to on if plugged in
|
||||
fn set_sleep_anim_enable(&self, enabled: bool) -> Result<(), RogError> {
|
||||
let bytes = if enabled { LED_SLEEP_ON } else { LED_SLEEP_OFF };
|
||||
/// Set if awake/on LED active, and/or sleep animation active
|
||||
pub(super) fn set_states_enabled(&self, awake: bool, sleep: bool) -> Result<(), RogError> {
|
||||
let bytes = if awake && sleep {
|
||||
LED_AWAKE_ON_SLEEP_ON
|
||||
} else if awake && !sleep {
|
||||
LED_AWAKE_ON_SLEEP_OFF
|
||||
} else if !awake && sleep {
|
||||
LED_AWAKE_OFF_SLEEP_ON
|
||||
} else if !awake && !sleep {
|
||||
LED_AWAKE_OFF_SLEEP_OFF
|
||||
} else {
|
||||
LED_AWAKE_ON_SLEEP_ON
|
||||
};
|
||||
self.write_bytes(&bytes)?;
|
||||
self.write_bytes(&LED_SET)?;
|
||||
// Changes won't persist unless apply is set
|
||||
@@ -391,7 +265,7 @@ impl CtrlKbdLed {
|
||||
|
||||
/// Write an effect block
|
||||
#[inline]
|
||||
fn write_effect(&mut self, effect: &[Vec<u8>]) -> Result<(), RogError> {
|
||||
fn _write_effect(&mut self, effect: &[Vec<u8>]) -> Result<(), RogError> {
|
||||
if self.flip_effect_write {
|
||||
for row in effect.iter().rev() {
|
||||
self.write_bytes(row)?;
|
||||
@@ -419,7 +293,7 @@ impl CtrlKbdLed {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn toggle_mode(&mut self, reverse: bool) -> Result<(), RogError> {
|
||||
pub(super) fn toggle_mode(&mut self, reverse: bool) -> Result<(), RogError> {
|
||||
let current = self.config.current_mode;
|
||||
if let Some(idx) = self
|
||||
.supported_modes
|
||||
2
daemon/src/ctrl_leds/mod.rs
Normal file
2
daemon/src/ctrl_leds/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod controller;
|
||||
pub mod zbus;
|
||||
165
daemon/src/ctrl_leds/zbus.rs
Normal file
165
daemon/src/ctrl_leds/zbus.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
use log::{error, warn};
|
||||
use rog_aura::{AuraEffect, LedBrightness, LedPowerStates};
|
||||
use zbus::dbus_interface;
|
||||
use zvariant::ObjectPath;
|
||||
|
||||
use super::controller::CtrlKbdLedZbus;
|
||||
|
||||
impl crate::ZbusAdd for CtrlKbdLedZbus {
|
||||
fn add_to_server(self, server: &mut zbus::ObjectServer) {
|
||||
server
|
||||
.at(&ObjectPath::from_str_unchecked("/org/asuslinux/Led"), self)
|
||||
.map_err(|err| {
|
||||
error!("DbusKbdLed: add_to_server {}", err);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
/// The main interface for changing, reading, or notfying signals
|
||||
///
|
||||
/// LED commands are split between Brightness, Modes, Per-Key
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlKbdLedZbus {
|
||||
/// Set the keyboard brightness level (0-3)
|
||||
fn set_brightness(&mut self, brightness: LedBrightness) {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
ctrl.set_brightness(brightness)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the keyboard LED to enabled while the device is awake
|
||||
fn set_awake_enabled(&mut self, enabled: bool) {
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
ctrl.set_states_enabled(enabled, ctrl.config.sleep_anim_enabled)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
ctrl.config.awake_enabled = enabled;
|
||||
ctrl.config.write();
|
||||
|
||||
let states = LedPowerStates {
|
||||
enabled: ctrl.config.awake_enabled,
|
||||
sleep_anim_enabled: ctrl.config.sleep_anim_enabled,
|
||||
};
|
||||
self.notify_power_states(&states)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the keyboard LED suspend animation to enabled while the device is suspended
|
||||
fn set_sleep_enabled(&mut self, enabled: bool) {
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
ctrl.set_states_enabled(ctrl.config.awake_enabled, enabled)
|
||||
.map_err(|err| warn!("{}", err))
|
||||
.ok();
|
||||
ctrl.config.sleep_anim_enabled = enabled;
|
||||
ctrl.config.write();
|
||||
let states = LedPowerStates {
|
||||
enabled: ctrl.config.awake_enabled,
|
||||
sleep_anim_enabled: ctrl.config.sleep_anim_enabled,
|
||||
};
|
||||
self.notify_power_states(&states)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
|
||||
fn set_led_mode(&mut self, effect: AuraEffect) {
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
match ctrl.do_command(effect) {
|
||||
Ok(_) => {
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
self.notify_led(mode.clone())
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("{}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next_led_mode(&self) {
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
ctrl.toggle_mode(false)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
self.notify_led(mode.clone())
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prev_led_mode(&self) {
|
||||
if let Ok(mut ctrl) = self.0.try_lock() {
|
||||
ctrl.toggle_mode(true)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
self.notify_led(mode.clone())
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn awake_enabled(&self) -> bool {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
return ctrl.config.awake_enabled;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn sleep_enabled(&self) -> bool {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
return ctrl.config.sleep_anim_enabled;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Return the current mode data
|
||||
#[dbus_interface(property)]
|
||||
fn led_mode(&self) -> String {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
||||
if let Ok(json) = serde_json::to_string(&mode) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
||||
warn!("SetKeyBacklight could not deserialise");
|
||||
"SetKeyBacklight could not deserialise".to_string()
|
||||
}
|
||||
|
||||
/// Return a list of available modes
|
||||
#[dbus_interface(property)]
|
||||
fn led_modes(&self) -> String {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
if let Ok(json) = serde_json::to_string(&ctrl.config.builtins) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
warn!("SetKeyBacklight could not deserialise");
|
||||
"SetKeyBacklight could not serialise".to_string()
|
||||
}
|
||||
|
||||
/// Return the current LED brightness
|
||||
#[dbus_interface(property)]
|
||||
fn led_brightness(&self) -> i8 {
|
||||
if let Ok(ctrl) = self.0.try_lock() {
|
||||
return ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1);
|
||||
}
|
||||
warn!("SetKeyBacklight could not serialise");
|
||||
-1
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_led(&self, data: AuraEffect) -> zbus::Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_power_states(&self, data: &LedPowerStates) -> zbus::Result<()>;
|
||||
}
|
||||
@@ -1,21 +1,12 @@
|
||||
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 log::info;
|
||||
use rog_profiles::profiles::Profile;
|
||||
use rog_types::supported::FanCpuSupportedFunctions;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
||||
pub struct CtrlFanAndCpu {
|
||||
pub path: &'static str,
|
||||
pub config: Arc<Mutex<Config>>,
|
||||
}
|
||||
|
||||
@@ -24,8 +15,8 @@ impl GetSupported for CtrlFanAndCpu {
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
FanCpuSupportedFunctions {
|
||||
stock_fan_modes: CtrlFanAndCpu::get_fan_path().is_ok(),
|
||||
min_max_freq: intel_pstate::PState::new().is_ok(),
|
||||
stock_fan_modes: Profile::get_fan_path().is_ok(),
|
||||
min_max_freq: Profile::get_intel_supported(),
|
||||
fan_curve_set: rog_fan_curve::Board::from_board_name().is_some(),
|
||||
}
|
||||
}
|
||||
@@ -33,13 +24,12 @@ impl GetSupported for CtrlFanAndCpu {
|
||||
|
||||
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)
|
||||
// );
|
||||
if let Ok(mut cfg) = self.config.clone().try_lock() {
|
||||
let active = cfg.active_profile.clone();
|
||||
if let Some(existing) = cfg.power_profiles.get_mut(&active) {
|
||||
existing.set_system_all()?;
|
||||
cfg.write();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -47,21 +37,9 @@ impl crate::Reloadable for CtrlFanAndCpu {
|
||||
|
||||
impl CtrlFanAndCpu {
|
||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||
let path = CtrlFanAndCpu::get_fan_path()?;
|
||||
Profile::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(),
|
||||
))
|
||||
}
|
||||
Ok(CtrlFanAndCpu { config })
|
||||
}
|
||||
|
||||
/// Toggle to next profile in list
|
||||
@@ -84,157 +62,39 @@ impl CtrlFanAndCpu {
|
||||
.unwrap_or(&config.active_profile)
|
||||
.clone();
|
||||
|
||||
self.set(&new_profile, config)?;
|
||||
self.set_active(&new_profile)?;
|
||||
|
||||
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 set_active(&mut self, profile: &str) -> Result<(), RogError> {
|
||||
if let Ok(mut cfg) = self.config.clone().try_lock() {
|
||||
cfg.read();
|
||||
|
||||
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)?;
|
||||
if let Some(existing) = cfg.power_profiles.get_mut(profile) {
|
||||
existing.set_system_all()?;
|
||||
cfg.active_profile = existing.name.clone();
|
||||
cfg.write();
|
||||
}
|
||||
}
|
||||
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))?;
|
||||
pub(super) fn new_or_modify(&mut self, profile: &Profile) -> Result<(), RogError> {
|
||||
if let Ok(mut cfg) = self.config.clone().try_lock() {
|
||||
cfg.read();
|
||||
|
||||
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)?;
|
||||
if let Some(existing) = cfg.power_profiles.get_mut(&profile.name) {
|
||||
*existing = profile.clone();
|
||||
existing.set_system_all()?;
|
||||
} else {
|
||||
warn!("Fan curve unsupported on this board.")
|
||||
cfg.power_profiles
|
||||
.insert(profile.name.clone(), profile.clone());
|
||||
}
|
||||
cfg.active_profile = profile.name.clone();
|
||||
cfg.write();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
pub mod zbus;
|
||||
|
||||
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";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use log::warn;
|
||||
use rog_fan_curve::Curve;
|
||||
use rog_profiles::profiles::Profile;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
@@ -20,115 +20,36 @@ impl FanAndCpuZbus {
|
||||
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
impl FanAndCpuZbus {
|
||||
/// Set profile details
|
||||
/// Create new profile and make active
|
||||
fn set_profile(&self, profile: String) {
|
||||
if let Ok(event) = serde_json::from_str(&profile) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
cfg.read();
|
||||
ctrl.handle_profile_event(&event, &mut cfg)
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
ctrl.set_active(&profile)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
// Do notification
|
||||
if let Ok(cfg) = ctrl.config.clone().try_lock() {
|
||||
// Do notify
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
self.notify_profile(&profile)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
if let Ok(json) = serde_json::to_string(profile) {
|
||||
self.notify_profile(&json)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Modify the active profile
|
||||
fn set_turbo(&self, enable: bool) -> zbus::fdo::Result<()> {
|
||||
/// New or modify profile details and make active, will create if it does not exist
|
||||
fn new_or_modify(&self, profile: Profile) {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
// Update the profile then set it
|
||||
cfg.read();
|
||||
let profile = cfg.active_profile.clone();
|
||||
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
|
||||
profile.turbo = enable;
|
||||
ctrl.new_or_modify(&profile)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
// Do notification
|
||||
if let Ok(cfg) = ctrl.config.clone().try_lock() {
|
||||
// Do notify
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
self.notify_profile(&profile)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
ctrl.set(&profile, &mut cfg)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Modify the active profile
|
||||
fn set_min_frequency(&self, percentage: u8) -> zbus::fdo::Result<()> {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
// Update the profile then set it
|
||||
cfg.read();
|
||||
let profile = cfg.active_profile.clone();
|
||||
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
|
||||
profile.min_percentage = percentage;
|
||||
}
|
||||
ctrl.set(&profile, &mut cfg)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Modify the active profile
|
||||
fn set_max_frequency(&self, percentage: u8) -> zbus::fdo::Result<()> {
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
// Update the profile then set it
|
||||
cfg.read();
|
||||
let profile = cfg.active_profile.clone();
|
||||
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
|
||||
profile.max_percentage = percentage;
|
||||
}
|
||||
ctrl.set(&profile, &mut cfg)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Modify the active profile
|
||||
fn set_fan_preset(&self, preset: u8) -> zbus::fdo::Result<()> {
|
||||
if preset > 2 {
|
||||
return Err(zbus::fdo::Error::InvalidArgs(
|
||||
"Fan preset must be 0, 1, or 2".to_string(),
|
||||
));
|
||||
}
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
// Update the profile then set it
|
||||
cfg.read();
|
||||
let profile = cfg.active_profile.clone();
|
||||
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
|
||||
profile.fan_preset = preset;
|
||||
}
|
||||
ctrl.set(&profile, &mut cfg)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Modify the active profile
|
||||
fn set_fan_curve(&self, curve: String) -> zbus::fdo::Result<()> {
|
||||
let curve = Curve::from_config_str(&curve)
|
||||
.map_err(|err| zbus::fdo::Error::InvalidArgs(format!("Fan curve error: {}", err)))?;
|
||||
if let Ok(mut ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.clone().try_lock() {
|
||||
// Update the profile then set it
|
||||
cfg.read();
|
||||
let profile = cfg.active_profile.clone();
|
||||
if let Some(profile) = cfg.power_profiles.get_mut(&profile) {
|
||||
profile.fan_curve = Some(curve);
|
||||
}
|
||||
ctrl.set(&profile, &mut cfg)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Fetch the active profile name
|
||||
@@ -139,17 +60,15 @@ impl FanAndCpuZbus {
|
||||
ctrl.do_next_profile(&mut cfg)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
if let Ok(json) = serde_json::to_string(profile) {
|
||||
self.notify_profile(&json)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
self.notify_profile(&profile)
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Fetch the active profile name
|
||||
fn active_profile_name(&mut self) -> zbus::fdo::Result<String> {
|
||||
fn active_name(&mut self) -> zbus::fdo::Result<String> {
|
||||
if let Ok(ctrl) = self.inner.try_lock() {
|
||||
if let Ok(mut cfg) = ctrl.config.try_lock() {
|
||||
cfg.read();
|
||||
@@ -163,14 +82,12 @@ impl FanAndCpuZbus {
|
||||
|
||||
// TODO: Profile can't implement Type because of Curve
|
||||
/// Fetch the active profile details
|
||||
fn profile(&mut self) -> zbus::fdo::Result<String> {
|
||||
fn active_data(&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();
|
||||
if let Some(profile) = cfg.power_profiles.get(&cfg.active_profile) {
|
||||
if let Ok(json) = serde_json::to_string_pretty(profile) {
|
||||
return Ok(json);
|
||||
}
|
||||
return Ok(profile.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -180,13 +97,11 @@ impl FanAndCpuZbus {
|
||||
}
|
||||
|
||||
/// Fetch all profile data
|
||||
fn profiles(&mut self) -> zbus::fdo::Result<String> {
|
||||
fn 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 Ok(json) = serde_json::to_string_pretty(&cfg.power_profiles) {
|
||||
return Ok(json);
|
||||
}
|
||||
return Ok(cfg.power_profiles.values().cloned().collect());
|
||||
}
|
||||
}
|
||||
Err(Error::Failed(
|
||||
@@ -236,7 +151,7 @@ impl FanAndCpuZbus {
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
fn notify_profile(&self, profile: &str) -> zbus::Result<()> {}
|
||||
fn notify_profile(&self, profile: &Profile) -> zbus::Result<()> {}
|
||||
}
|
||||
|
||||
impl crate::ZbusAdd for FanAndCpuZbus {
|
||||
|
||||
@@ -309,11 +309,9 @@ impl CtrlRogBios {
|
||||
|
||||
let mut buf = Vec::new();
|
||||
// remove modules
|
||||
for line in std::io::BufReader::new(file).lines() {
|
||||
if let Ok(l) = line {
|
||||
if !modules.contains(&l.as_ref()) {
|
||||
buf.append(&mut l.as_bytes().to_vec());
|
||||
}
|
||||
for line in std::io::BufReader::new(file).lines().flatten() {
|
||||
if !modules.contains(&line.as_str()) {
|
||||
buf.append(&mut line.as_bytes().to_vec());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,15 +2,19 @@ use log::warn;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use zbus::dbus_interface;
|
||||
use zvariant::ObjectPath;
|
||||
use zvariant_derive::Type;
|
||||
|
||||
use crate::{GetSupported, ctrl_anime::CtrlAnime, ctrl_charge::CtrlCharge, ctrl_leds::CtrlKbdLed, ctrl_profiles::controller::CtrlFanAndCpu, ctrl_rog_bios::CtrlRogBios};
|
||||
use crate::{
|
||||
ctrl_anime::CtrlAnime, ctrl_charge::CtrlCharge, ctrl_leds::controller::CtrlKbdLed,
|
||||
ctrl_profiles::controller::CtrlFanAndCpu, ctrl_rog_bios::CtrlRogBios, GetSupported,
|
||||
};
|
||||
|
||||
use rog_types::supported::{
|
||||
AnimeSupportedFunctions, ChargeSupportedFunctions, FanCpuSupportedFunctions,
|
||||
LedSupportedFunctions, RogBiosSupportedFunctions,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Type)]
|
||||
pub struct SupportedFunctions {
|
||||
pub anime_ctrl: AnimeSupportedFunctions,
|
||||
pub charge_ctrl: ChargeSupportedFunctions,
|
||||
@@ -21,8 +25,8 @@ pub struct SupportedFunctions {
|
||||
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
impl SupportedFunctions {
|
||||
fn supported_functions(&self) -> String {
|
||||
serde_json::to_string_pretty(self).unwrap()
|
||||
fn supported_functions(&self) -> &SupportedFunctions {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +50,8 @@ impl GetSupported for SupportedFunctions {
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
SupportedFunctions {
|
||||
keyboard_led: CtrlKbdLed::get_supported(),
|
||||
anime_ctrl: CtrlAnime::get_supported(),
|
||||
keyboard_led: CtrlKbdLed::get_supported(),
|
||||
charge_ctrl: CtrlCharge::get_supported(),
|
||||
fan_cpu_ctrl: CtrlFanAndCpu::get_supported(),
|
||||
rog_bios_ctrl: CtrlRogBios::get_supported(),
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use daemon::ctrl_leds::{CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus};
|
||||
use daemon::ctrl_leds::controller::{
|
||||
CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus,
|
||||
};
|
||||
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::controller::CtrlGraphics};
|
||||
use daemon::{
|
||||
ctrl_profiles::{zbus::FanAndCpuZbus, controller::CtrlFanAndCpu},
|
||||
ctrl_profiles::{controller::CtrlFanAndCpu, zbus::FanAndCpuZbus},
|
||||
laptops::LaptopLedData,
|
||||
};
|
||||
|
||||
@@ -33,9 +35,12 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.filter(None, LevelFilter::Info)
|
||||
.init();
|
||||
|
||||
info!(" daemon v{}", daemon::VERSION);
|
||||
info!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||
info!("rog-types v{}", rog_types::VERSION);
|
||||
info!(" daemon v{}", daemon::VERSION);
|
||||
info!(" rog-anime v{}", rog_anime::VERSION);
|
||||
info!(" rog-aura v{}", rog_aura::VERSION);
|
||||
info!(" rog-dbus v{}", rog_dbus::VERSION);
|
||||
info!("rog-profiles v{}", rog_profiles::VERSION);
|
||||
info!(" rog-types v{}", rog_types::VERSION);
|
||||
|
||||
start_daemon()?;
|
||||
Ok(())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use intel_pstate::PStateError;
|
||||
use rog_fan_curve::CurveError;
|
||||
use rog_profiles::error::ProfileError;
|
||||
use rog_types::error::GraphicsError;
|
||||
use std::convert::From;
|
||||
use std::fmt;
|
||||
@@ -18,13 +18,13 @@ pub enum RogError {
|
||||
Write(String, std::io::Error),
|
||||
NotSupported,
|
||||
NotFound(String),
|
||||
IntelPstate(PStateError),
|
||||
FanCurve(CurveError),
|
||||
DoTask(String),
|
||||
MissingFunction(String),
|
||||
MissingLedBrightNode(String, std::io::Error),
|
||||
ReloadFail(String),
|
||||
GfxSwitching(GfxError),
|
||||
Profiles(ProfileError),
|
||||
Initramfs(String),
|
||||
Modprobe(String),
|
||||
Command(String, std::io::Error),
|
||||
@@ -46,13 +46,13 @@ impl fmt::Display for RogError {
|
||||
RogError::Write(path, error) => write!(f, "Write {}: {}", path, error),
|
||||
RogError::NotSupported => write!(f, "Not supported"),
|
||||
RogError::NotFound(deets) => write!(f, "Not found: {}", deets),
|
||||
RogError::IntelPstate(err) => write!(f, "Intel pstate error: {}", err),
|
||||
RogError::FanCurve(err) => write!(f, "Custom fan-curve error: {}", err),
|
||||
RogError::DoTask(deets) => write!(f, "Task error: {}", deets),
|
||||
RogError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets),
|
||||
RogError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error),
|
||||
RogError::ReloadFail(deets) => write!(f, "Task error: {}", deets),
|
||||
RogError::GfxSwitching(deets) => write!(f, "Graphics switching error: {}", deets),
|
||||
RogError::Profiles(deets) => write!(f, "Profile error: {}", deets),
|
||||
RogError::Initramfs(detail) => write!(f, "Initiramfs error: {}", detail),
|
||||
RogError::Modprobe(detail) => write!(f, "Modprobe error: {}", detail),
|
||||
RogError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error),
|
||||
@@ -64,12 +64,6 @@ impl fmt::Display for RogError {
|
||||
|
||||
impl std::error::Error for RogError {}
|
||||
|
||||
impl From<PStateError> for RogError {
|
||||
fn from(err: PStateError) -> Self {
|
||||
RogError::IntelPstate(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CurveError> for RogError {
|
||||
fn from(err: CurveError) -> Self {
|
||||
RogError::FanCurve(err)
|
||||
@@ -85,6 +79,12 @@ impl From<GraphicsError> for RogError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ProfileError> for RogError {
|
||||
fn from(err: ProfileError) -> Self {
|
||||
RogError::Profiles(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<zbus::Error> for RogError {
|
||||
fn from(err: zbus::Error) -> Self {
|
||||
RogError::Zbus(err)
|
||||
|
||||
Reference in New Issue
Block a user