Manage max CPU freq/boost-mode in combination with fan modes

This commit is contained in:
Luke
2020-04-29 10:50:17 +12:00
parent 7f5b0f4c53
commit f818ffa191
5 changed files with 205 additions and 102 deletions

109
Cargo.lock generated
View File

@@ -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",

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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);
}
}

View File

@@ -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};