mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Manage max CPU freq/boost-mode in combination with fan modes
This commit is contained in:
109
Cargo.lock
generated
109
Cargo.lock
generated
@@ -197,6 +197,20 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "err-derive"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.9"
|
||||
@@ -360,6 +374,15 @@ dependencies = [
|
||||
"quick-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "intel-pstate"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/flukejones/intel-pstate#f70ab9726bdada99f5cb01c64c056f2093f3a008"
|
||||
dependencies = [
|
||||
"err-derive",
|
||||
"smart-default",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
@@ -519,12 +542,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numtoa"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e521b6adefa0b2c1fa5d2abdf9a5216288686fe6146249215d884c0e5ab320b0"
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
@@ -549,6 +566,32 @@ version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn-mid",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.15"
|
||||
@@ -624,11 +667,11 @@ dependencies = [
|
||||
"dbus-tokio",
|
||||
"env_logger",
|
||||
"gumdrop",
|
||||
"intel-pstate",
|
||||
"log",
|
||||
"rusb",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sysfs-class",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"toml",
|
||||
@@ -652,6 +695,17 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.106"
|
||||
@@ -681,6 +735,17 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
|
||||
[[package]]
|
||||
name = "smart-default"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
@@ -699,12 +764,26 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysfs-class"
|
||||
version = "0.1.3"
|
||||
name = "syn-mid"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e1bbcf869732c45a77898f7f61ed6d411dfc37613517e444842f58d428856d1"
|
||||
checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
|
||||
dependencies = [
|
||||
"numtoa",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -745,18 +824,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b3d3d2ff68104100ab257bb6bb0cb26c901abe4bd4ba15961f3bf867924012"
|
||||
checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca972988113b7715266f91250ddb98070d033c62a011fa0fcc57434a649310dd"
|
||||
checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
15
Cargo.toml
15
Cargo.toml
@@ -14,18 +14,25 @@ path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
rusb = "^0.5.5"
|
||||
# cli crate
|
||||
gumdrop = "^0.8.0"
|
||||
log = "^0.4.8"
|
||||
env_logger = "^0.7.1"
|
||||
# async
|
||||
dbus = { version = "^0.8.2", features = ["futures"] }
|
||||
dbus-tokio = "^0.5.1"
|
||||
tokio = { version = "0.2.4", features = ["rt-threaded", "macros"] }
|
||||
|
||||
# serialisation
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
toml = "0.5"
|
||||
sysfs-class = "^0.1.2"
|
||||
# used for backlight control mostly
|
||||
# sysfs-class = "^0.1.2"
|
||||
# cpu power management
|
||||
intel-pstate = { git = "https://github.com/flukejones/intel-pstate" }
|
||||
#
|
||||
aho-corasick = "^0.7.10"
|
||||
thiserror = "^1.0.15"
|
||||
log = "^0.4.8"
|
||||
# virtualisation of HID, mainly for outputting consumer key codes
|
||||
uhid-virt = "^0.0.4"
|
||||
#keycode = "0.3"
|
||||
env_logger = "^0.7.1"
|
||||
162
src/core.rs
162
src/core.rs
@@ -1,10 +1,9 @@
|
||||
// Return show-stopping errors, otherwise map error to a log level
|
||||
|
||||
use crate::{
|
||||
aura::{aura_brightness_bytes, BuiltInModeByte, KeyColourArray},
|
||||
aura::{aura_brightness_bytes, BuiltInModeByte},
|
||||
config::Config,
|
||||
error::AuraError,
|
||||
laptops::*,
|
||||
virt_device::VirtKeys,
|
||||
};
|
||||
use aho_corasick::AhoCorasick;
|
||||
@@ -18,7 +17,6 @@ use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use sysfs_class::{Brightness, SysClass};
|
||||
|
||||
pub const LED_MSG_LEN: usize = 17;
|
||||
static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
@@ -47,7 +45,6 @@ pub(crate) struct RogCore {
|
||||
handle: DeviceHandle<rusb::GlobalContext>,
|
||||
initialised: bool,
|
||||
led_endpoint: u8,
|
||||
keys_endpoint: u8,
|
||||
config: Config,
|
||||
virt_keys: VirtKeys,
|
||||
}
|
||||
@@ -88,8 +85,7 @@ impl RogCore {
|
||||
Ok(RogCore {
|
||||
handle: dev_handle,
|
||||
initialised: false,
|
||||
led_endpoint: led_endpoint,
|
||||
keys_endpoint: key_endpoint,
|
||||
led_endpoint,
|
||||
config: Config::default().read(),
|
||||
virt_keys: VirtKeys::new(),
|
||||
})
|
||||
@@ -115,6 +111,7 @@ impl RogCore {
|
||||
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
file.write(format!("{:?}\n", self.config.fan_mode).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(self.config.fan_mode))?;
|
||||
info!("Reloaded last saved settings");
|
||||
Ok(())
|
||||
}
|
||||
@@ -169,17 +166,6 @@ impl RogCore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialise and clear the keyboard for custom effects
|
||||
pub fn aura_effect_init(&mut self) -> Result<(), AuraError> {
|
||||
let mut init = [0u8; 64];
|
||||
init[0] = 0x5d; // Report ID
|
||||
init[1] = 0xbc; // Mode = custom??, 0xb3 is builtin
|
||||
self.aura_write(&init)?;
|
||||
self.initialised = true;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
///
|
||||
/// `aura_effect_init` must be called any effect routine, and called only once.
|
||||
@@ -301,27 +287,54 @@ impl RogCore {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let mut file = OpenOptions::new().read(true).write(true).open(path)?;
|
||||
let mut fan_ctrl = OpenOptions::new().read(true).write(true).open(path)?;
|
||||
|
||||
let mut buf = String::new();
|
||||
if let Ok(_) = file.read_to_string(&mut buf) {
|
||||
if let Ok(_) = fan_ctrl.read_to_string(&mut buf) {
|
||||
let mut n = u8::from_str_radix(&buf.trim_end(), 10)?;
|
||||
info!("Current fan mode: {:#?}", FanLevel::from(n));
|
||||
|
||||
// wrap around the step number
|
||||
if n < 2 {
|
||||
n += 1;
|
||||
} else {
|
||||
n = 0;
|
||||
}
|
||||
|
||||
info!("Fan mode stepped to: {:#?}", FanLevel::from(n));
|
||||
file.write(format!("{:?}\n", n).as_bytes())?;
|
||||
fan_ctrl.write(format!("{:?}\n", n).as_bytes())?;
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(n))?;
|
||||
self.config.fan_mode = n;
|
||||
self.config.write();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_pstate_for_fan_mode(&self, mode: FanLevel) -> Result<(), Box<dyn Error>> {
|
||||
// Set CPU pstate
|
||||
if let Ok(pstate) = intel_pstate::PState::new() {
|
||||
match mode {
|
||||
FanLevel::Normal => {
|
||||
pstate.set_min_perf_pct(0)?;
|
||||
pstate.set_max_perf_pct(100)?;
|
||||
pstate.set_no_turbo(false)?;
|
||||
info!("CPU pstate: normal");
|
||||
}
|
||||
FanLevel::Boost => {
|
||||
pstate.set_min_perf_pct(50)?;
|
||||
pstate.set_max_perf_pct(100)?;
|
||||
pstate.set_no_turbo(false)?;
|
||||
info!("CPU pstate: boost");
|
||||
}
|
||||
FanLevel::Silent => {
|
||||
pstate.set_min_perf_pct(0)?;
|
||||
pstate.set_max_perf_pct(70)?;
|
||||
pstate.set_no_turbo(true)?;
|
||||
info!("CPU pstate: silent, no-turbo");
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write the bytes read from the device interrupt to the buffer arg, and returns the
|
||||
/// count of bytes written
|
||||
///
|
||||
@@ -403,59 +416,60 @@ impl RogCore {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Backlight {
|
||||
backlight: sysfs_class::Backlight,
|
||||
step: u64,
|
||||
max: u64,
|
||||
}
|
||||
// use sysfs_class::{Brightness, SysClass};
|
||||
// pub(crate) struct Backlight {
|
||||
// backlight: sysfs_class::Backlight,
|
||||
// step: u64,
|
||||
// max: u64,
|
||||
// }
|
||||
|
||||
impl Backlight {
|
||||
pub(crate) fn new(id: &str) -> Result<Backlight, std::io::Error> {
|
||||
for bl in sysfs_class::Backlight::iter() {
|
||||
let bl = bl?;
|
||||
if bl.id() == id {
|
||||
let max = bl.max_brightness()?;
|
||||
let step = max / 50;
|
||||
return Ok(Backlight {
|
||||
backlight: bl,
|
||||
step,
|
||||
max,
|
||||
});
|
||||
}
|
||||
}
|
||||
panic!("Backlight not found")
|
||||
}
|
||||
pub(crate) fn step_up(&self) {
|
||||
let brightness = self
|
||||
.backlight
|
||||
.brightness()
|
||||
.map_err(|err| warn!("Failed to fetch backlight level: {}", err))
|
||||
.unwrap();
|
||||
if brightness + self.step <= self.max {
|
||||
self.backlight
|
||||
.set_brightness(brightness + self.step)
|
||||
.map_or_else(
|
||||
|err| warn!("Failed to increment backlight level: {}", err),
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
}
|
||||
pub(crate) fn step_down(&self) {
|
||||
let brightness = self
|
||||
.backlight
|
||||
.brightness()
|
||||
.map_err(|err| warn!("Failed to fetch backlight level: {}", err))
|
||||
.unwrap();
|
||||
if brightness > self.step {
|
||||
self.backlight
|
||||
.set_brightness(brightness - self.step)
|
||||
.map_or_else(
|
||||
|err| warn!("Failed to increment backlight level: {}", err),
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl Backlight {
|
||||
// pub(crate) fn new(id: &str) -> Result<Backlight, std::io::Error> {
|
||||
// for bl in sysfs_class::Backlight::iter() {
|
||||
// let bl = bl?;
|
||||
// if bl.id() == id {
|
||||
// let max = bl.max_brightness()?;
|
||||
// let step = max / 50;
|
||||
// return Ok(Backlight {
|
||||
// backlight: bl,
|
||||
// step,
|
||||
// max,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// panic!("Backlight not found")
|
||||
// }
|
||||
// pub(crate) fn step_up(&self) {
|
||||
// let brightness = self
|
||||
// .backlight
|
||||
// .brightness()
|
||||
// .map_err(|err| warn!("Failed to fetch backlight level: {}", err))
|
||||
// .unwrap();
|
||||
// if brightness + self.step <= self.max {
|
||||
// self.backlight
|
||||
// .set_brightness(brightness + self.step)
|
||||
// .map_or_else(
|
||||
// |err| warn!("Failed to increment backlight level: {}", err),
|
||||
// |_| {},
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// pub(crate) fn step_down(&self) {
|
||||
// let brightness = self
|
||||
// .backlight
|
||||
// .brightness()
|
||||
// .map_err(|err| warn!("Failed to fetch backlight level: {}", err))
|
||||
// .unwrap();
|
||||
// if brightness > self.step {
|
||||
// self.backlight
|
||||
// .set_brightness(brightness - self.step)
|
||||
// .map_or_else(
|
||||
// |err| warn!("Failed to increment backlight level: {}", err),
|
||||
// |_| {},
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[derive(Debug, Options)]
|
||||
pub struct LedBrightness {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::aura::BuiltInModeByte;
|
||||
use crate::core::{Backlight, RogCore};
|
||||
use crate::core::RogCore;
|
||||
use crate::error::AuraError;
|
||||
use crate::virt_device::ConsumerKeys;
|
||||
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
|
||||
@@ -17,7 +17,7 @@ pub(super) struct LaptopGL753 {
|
||||
led_endpoint: u8,
|
||||
key_endpoint: u8,
|
||||
supported_modes: [BuiltInModeByte; 3],
|
||||
backlight: Backlight,
|
||||
// backlight: Backlight,
|
||||
}
|
||||
|
||||
impl LaptopGL753 {
|
||||
@@ -41,7 +41,7 @@ impl LaptopGL753 {
|
||||
BuiltInModeByte::Breathing,
|
||||
BuiltInModeByte::Cycle,
|
||||
],
|
||||
backlight: Backlight::new("intel_backlight").unwrap(),
|
||||
// backlight: Backlight::new("intel_backlight").unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,8 +59,12 @@ impl LaptopGL753 {
|
||||
GL753Keys::LedBrightDown => {
|
||||
rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?;
|
||||
}
|
||||
GL753Keys::ScreenBrightUp => self.backlight.step_up(),
|
||||
GL753Keys::ScreenBrightDown => self.backlight.step_down(),
|
||||
GL753Keys::ScreenBrightUp => {
|
||||
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
|
||||
}
|
||||
GL753Keys::ScreenBrightDown => {
|
||||
rogcore.virt_keys().press(ConsumerKeys::BacklightDec.into())
|
||||
}
|
||||
GL753Keys::Sleep => rogcore.suspend_with_systemd(),
|
||||
GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
|
||||
GL753Keys::ScreenToggle => {
|
||||
@@ -80,8 +84,7 @@ impl LaptopGL753 {
|
||||
}
|
||||
GL753Keys::None => {
|
||||
if key_buf[0] != 0x5A {
|
||||
info!("Unmapped key array: {:X?}", &key_buf);
|
||||
info!("Attempting passthrough: {:X?}", &key_buf[1]);
|
||||
info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
|
||||
rogcore.virt_keys().press(key_buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::aura::{BuiltInModeByte, Key, KeyColourArray};
|
||||
use crate::core::{Backlight, RogCore};
|
||||
use crate::aura::BuiltInModeByte;
|
||||
use crate::core::RogCore;
|
||||
use crate::error::AuraError;
|
||||
use crate::virt_device::ConsumerKeys;
|
||||
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
|
||||
|
||||
Reference in New Issue
Block a user