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", "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]] [[package]]
name = "filetime" name = "filetime"
version = "0.2.9" version = "0.2.9"
@@ -360,6 +374,15 @@ dependencies = [
"quick-error", "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]] [[package]]
name = "iovec" name = "iovec"
version = "0.1.4" version = "0.1.4"
@@ -519,12 +542,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "numtoa"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e521b6adefa0b2c1fa5d2abdf9a5216288686fe6146249215d884c0e5ab320b0"
[[package]] [[package]]
name = "peeking_take_while" name = "peeking_take_while"
version = "0.1.2" version = "0.1.2"
@@ -549,6 +566,32 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 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]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.15" version = "0.5.15"
@@ -624,11 +667,11 @@ dependencies = [
"dbus-tokio", "dbus-tokio",
"env_logger", "env_logger",
"gumdrop", "gumdrop",
"intel-pstate",
"log", "log",
"rusb", "rusb",
"serde", "serde",
"serde_derive", "serde_derive",
"sysfs-class",
"thiserror", "thiserror",
"tokio", "tokio",
"toml", "toml",
@@ -652,6 +695,17 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 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]] [[package]]
name = "serde" name = "serde"
version = "1.0.106" version = "1.0.106"
@@ -681,6 +735,17 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 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]] [[package]]
name = "strsim" name = "strsim"
version = "0.8.0" version = "0.8.0"
@@ -699,12 +764,26 @@ dependencies = [
] ]
[[package]] [[package]]
name = "sysfs-class" name = "syn-mid"
version = "0.1.3" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e1bbcf869732c45a77898f7f61ed6d411dfc37613517e444842f58d428856d1" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
dependencies = [ 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]] [[package]]
@@ -745,18 +824,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54b3d3d2ff68104100ab257bb6bb0cb26c901abe4bd4ba15961f3bf867924012" checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca972988113b7715266f91250ddb98070d033c62a011fa0fcc57434a649310dd" checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@@ -14,18 +14,25 @@ path = "src/main.rs"
[dependencies] [dependencies]
rusb = "^0.5.5" rusb = "^0.5.5"
# cli crate
gumdrop = "^0.8.0" gumdrop = "^0.8.0"
log = "^0.4.8"
env_logger = "^0.7.1"
# async
dbus = { version = "^0.8.2", features = ["futures"] } dbus = { version = "^0.8.2", features = ["futures"] }
dbus-tokio = "^0.5.1" dbus-tokio = "^0.5.1"
tokio = { version = "0.2.4", features = ["rt-threaded", "macros"] } tokio = { version = "0.2.4", features = ["rt-threaded", "macros"] }
# serialisation
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
toml = "0.5" 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" aho-corasick = "^0.7.10"
thiserror = "^1.0.15" thiserror = "^1.0.15"
log = "^0.4.8" # virtualisation of HID, mainly for outputting consumer key codes
uhid-virt = "^0.0.4" uhid-virt = "^0.0.4"
#keycode = "0.3" #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 // Return show-stopping errors, otherwise map error to a log level
use crate::{ use crate::{
aura::{aura_brightness_bytes, BuiltInModeByte, KeyColourArray}, aura::{aura_brightness_bytes, BuiltInModeByte},
config::Config, config::Config,
error::AuraError, error::AuraError,
laptops::*,
virt_device::VirtKeys, virt_device::VirtKeys,
}; };
use aho_corasick::AhoCorasick; use aho_corasick::AhoCorasick;
@@ -18,7 +17,6 @@ use std::path::Path;
use std::process::Command; use std::process::Command;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use sysfs_class::{Brightness, SysClass};
pub const LED_MSG_LEN: usize = 17; pub const LED_MSG_LEN: usize = 17;
static LED_INIT1: [u8; 2] = [0x5d, 0xb9]; static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
@@ -47,7 +45,6 @@ pub(crate) struct RogCore {
handle: DeviceHandle<rusb::GlobalContext>, handle: DeviceHandle<rusb::GlobalContext>,
initialised: bool, initialised: bool,
led_endpoint: u8, led_endpoint: u8,
keys_endpoint: u8,
config: Config, config: Config,
virt_keys: VirtKeys, virt_keys: VirtKeys,
} }
@@ -88,8 +85,7 @@ impl RogCore {
Ok(RogCore { Ok(RogCore {
handle: dev_handle, handle: dev_handle,
initialised: false, initialised: false,
led_endpoint: led_endpoint, led_endpoint,
keys_endpoint: key_endpoint,
config: Config::default().read(), config: Config::default().read(),
virt_keys: VirtKeys::new(), virt_keys: VirtKeys::new(),
}) })
@@ -115,6 +111,7 @@ impl RogCore {
let mut file = OpenOptions::new().write(true).open(path)?; let mut file = OpenOptions::new().write(true).open(path)?;
file.write(format!("{:?}\n", self.config.fan_mode).as_bytes())?; 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"); info!("Reloaded last saved settings");
Ok(()) Ok(())
} }
@@ -169,17 +166,6 @@ impl RogCore {
Ok(()) 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 /// Write an effect block
/// ///
/// `aura_effect_init` must be called any effect routine, and called only once. /// `aura_effect_init` must be called any effect routine, and called only once.
@@ -301,27 +287,54 @@ impl RogCore {
return Ok(()); 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(); 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)?; let mut n = u8::from_str_radix(&buf.trim_end(), 10)?;
info!("Current fan mode: {:#?}", FanLevel::from(n)); info!("Current fan mode: {:#?}", FanLevel::from(n));
// wrap around the step number
if n < 2 { if n < 2 {
n += 1; n += 1;
} else { } else {
n = 0; n = 0;
} }
info!("Fan mode stepped to: {:#?}", FanLevel::from(n)); 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.fan_mode = n;
self.config.write(); self.config.write();
} }
Ok(()) 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 /// Write the bytes read from the device interrupt to the buffer arg, and returns the
/// count of bytes written /// count of bytes written
/// ///
@@ -403,59 +416,60 @@ impl RogCore {
} }
} }
pub(crate) struct Backlight { // use sysfs_class::{Brightness, SysClass};
backlight: sysfs_class::Backlight, // pub(crate) struct Backlight {
step: u64, // backlight: sysfs_class::Backlight,
max: u64, // step: u64,
} // max: u64,
// }
impl Backlight { // impl Backlight {
pub(crate) fn new(id: &str) -> Result<Backlight, std::io::Error> { // pub(crate) fn new(id: &str) -> Result<Backlight, std::io::Error> {
for bl in sysfs_class::Backlight::iter() { // for bl in sysfs_class::Backlight::iter() {
let bl = bl?; // let bl = bl?;
if bl.id() == id { // if bl.id() == id {
let max = bl.max_brightness()?; // let max = bl.max_brightness()?;
let step = max / 50; // let step = max / 50;
return Ok(Backlight { // return Ok(Backlight {
backlight: bl, // backlight: bl,
step, // step,
max, // max,
}); // });
} // }
} // }
panic!("Backlight not found") // panic!("Backlight not found")
} // }
pub(crate) fn step_up(&self) { // pub(crate) fn step_up(&self) {
let brightness = self // let brightness = self
.backlight // .backlight
.brightness() // .brightness()
.map_err(|err| warn!("Failed to fetch backlight level: {}", err)) // .map_err(|err| warn!("Failed to fetch backlight level: {}", err))
.unwrap(); // .unwrap();
if brightness + self.step <= self.max { // if brightness + self.step <= self.max {
self.backlight // self.backlight
.set_brightness(brightness + self.step) // .set_brightness(brightness + self.step)
.map_or_else( // .map_or_else(
|err| warn!("Failed to increment backlight level: {}", err), // |err| warn!("Failed to increment backlight level: {}", err),
|_| {}, // |_| {},
); // );
} // }
} // }
pub(crate) fn step_down(&self) { // pub(crate) fn step_down(&self) {
let brightness = self // let brightness = self
.backlight // .backlight
.brightness() // .brightness()
.map_err(|err| warn!("Failed to fetch backlight level: {}", err)) // .map_err(|err| warn!("Failed to fetch backlight level: {}", err))
.unwrap(); // .unwrap();
if brightness > self.step { // if brightness > self.step {
self.backlight // self.backlight
.set_brightness(brightness - self.step) // .set_brightness(brightness - self.step)
.map_or_else( // .map_or_else(
|err| warn!("Failed to increment backlight level: {}", err), // |err| warn!("Failed to increment backlight level: {}", err),
|_| {}, // |_| {},
); // );
} // }
} // }
} // }
#[derive(Debug, Options)] #[derive(Debug, Options)]
pub struct LedBrightness { pub struct LedBrightness {

View File

@@ -1,5 +1,5 @@
use crate::aura::BuiltInModeByte; use crate::aura::BuiltInModeByte;
use crate::core::{Backlight, RogCore}; use crate::core::RogCore;
use crate::error::AuraError; use crate::error::AuraError;
use crate::virt_device::ConsumerKeys; use crate::virt_device::ConsumerKeys;
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState}; //use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};
@@ -17,7 +17,7 @@ pub(super) struct LaptopGL753 {
led_endpoint: u8, led_endpoint: u8,
key_endpoint: u8, key_endpoint: u8,
supported_modes: [BuiltInModeByte; 3], supported_modes: [BuiltInModeByte; 3],
backlight: Backlight, // backlight: Backlight,
} }
impl LaptopGL753 { impl LaptopGL753 {
@@ -41,7 +41,7 @@ impl LaptopGL753 {
BuiltInModeByte::Breathing, BuiltInModeByte::Breathing,
BuiltInModeByte::Cycle, BuiltInModeByte::Cycle,
], ],
backlight: Backlight::new("intel_backlight").unwrap(), // backlight: Backlight::new("intel_backlight").unwrap(),
} }
} }
} }
@@ -59,8 +59,12 @@ impl LaptopGL753 {
GL753Keys::LedBrightDown => { GL753Keys::LedBrightDown => {
rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?; rogcore.aura_bright_dec(&self.supported_modes, self.min_led_bright)?;
} }
GL753Keys::ScreenBrightUp => self.backlight.step_up(), GL753Keys::ScreenBrightUp => {
GL753Keys::ScreenBrightDown => self.backlight.step_down(), rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
}
GL753Keys::ScreenBrightDown => {
rogcore.virt_keys().press(ConsumerKeys::BacklightDec.into())
}
GL753Keys::Sleep => rogcore.suspend_with_systemd(), GL753Keys::Sleep => rogcore.suspend_with_systemd(),
GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(), GL753Keys::AirplaneMode => rogcore.toggle_airplane_mode(),
GL753Keys::ScreenToggle => { GL753Keys::ScreenToggle => {
@@ -80,8 +84,7 @@ impl LaptopGL753 {
} }
GL753Keys::None => { GL753Keys::None => {
if key_buf[0] != 0x5A { if key_buf[0] != 0x5A {
info!("Unmapped key array: {:X?}", &key_buf); info!("Unmapped key, attempt passthrough: {:X?}", &key_buf[1]);
info!("Attempting passthrough: {:X?}", &key_buf[1]);
rogcore.virt_keys().press(key_buf); rogcore.virt_keys().press(key_buf);
} }
} }

View File

@@ -1,5 +1,5 @@
use crate::aura::{BuiltInModeByte, Key, KeyColourArray}; use crate::aura::BuiltInModeByte;
use crate::core::{Backlight, RogCore}; use crate::core::RogCore;
use crate::error::AuraError; use crate::error::AuraError;
use crate::virt_device::ConsumerKeys; use crate::virt_device::ConsumerKeys;
//use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState}; //use keycode::{KeyMap, KeyMappingId, KeyState, KeyboardState};