mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Rearchitect
This commit is contained in:
69
rog-core/src/ctrl_charge.rs
Normal file
69
rog-core/src/ctrl_charge.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
use crate::config::Config;
|
||||
use log::{error, info, warn};
|
||||
use std::error::Error;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
static BAT_CHARGE_PATH: &str = "/sys/class/power_supply/BAT0/charge_control_end_threshold";
|
||||
|
||||
pub struct CtrlCharge {
|
||||
path: &'static str,
|
||||
}
|
||||
|
||||
impl CtrlCharge {
|
||||
pub(super) fn new() -> Result<Self, Box<dyn Error>> {
|
||||
let path = CtrlCharge::get_battery_path()?;
|
||||
|
||||
Ok(CtrlCharge { path })
|
||||
}
|
||||
|
||||
fn get_battery_path() -> Result<&'static str, std::io::Error> {
|
||||
if Path::new(BAT_CHARGE_PATH).exists() {
|
||||
Ok(BAT_CHARGE_PATH)
|
||||
} else {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::NotFound,
|
||||
"Charge control not available",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn bat_charge_limit_reload(
|
||||
&self,
|
||||
config: &mut Config,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
config.read();
|
||||
info!("Reloaded battery charge limit");
|
||||
self.set_charge_limit(config.bat_charge_limit, config)
|
||||
}
|
||||
|
||||
pub(super) fn set_charge_limit(
|
||||
&self,
|
||||
limit: u8,
|
||||
config: &mut Config,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
if limit < 20 || limit > 100 {
|
||||
warn!(
|
||||
"Unable to set battery charge limit, must be between 20-100: requested {}",
|
||||
limit
|
||||
);
|
||||
}
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.open(self.path)
|
||||
.map_err(|err| {
|
||||
warn!("Failed to open battery charge limit path: {:?}", err);
|
||||
err
|
||||
})?;
|
||||
file.write_all(limit.to_string().as_bytes())
|
||||
.unwrap_or_else(|err| error!("Could not write to {}, {:?}", BAT_CHARGE_PATH, err));
|
||||
info!("Battery charge limit: {}", limit);
|
||||
|
||||
config.bat_charge_limit = limit;
|
||||
config.write();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,24 @@
|
||||
// Return show-stopping errors, otherwise map error to a log level
|
||||
|
||||
use crate::{config::Config, error::RogError};
|
||||
use crate::config::Config;
|
||||
use log::{error, info, warn};
|
||||
use std::error::Error;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::str::FromStr;
|
||||
|
||||
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";
|
||||
static BAT_CHARGE_PATH: &str = "/sys/class/power_supply/BAT0/charge_control_end_threshold";
|
||||
|
||||
/// ROG device controller
|
||||
///
|
||||
/// For the GX502GW the LED setup sequence looks like:
|
||||
///
|
||||
/// -` LED_INIT1`
|
||||
/// - `LED_INIT3`
|
||||
/// - `LED_INIT4`
|
||||
/// - `LED_INIT2`
|
||||
/// - `LED_INIT4`
|
||||
pub struct RogCore {}
|
||||
pub struct CtrlFanAndCPU {
|
||||
path: &'static str,
|
||||
}
|
||||
|
||||
impl RogCore {
|
||||
pub fn new(vendor: u16, product: u16) -> Self {
|
||||
RogCore {}
|
||||
impl CtrlFanAndCPU {
|
||||
pub(super) fn new() -> Result<Self, Box<dyn Error>> {
|
||||
let path = CtrlFanAndCPU::get_fan_path()?;
|
||||
|
||||
Ok(CtrlFanAndCPU { path })
|
||||
}
|
||||
|
||||
fn get_fan_path() -> Result<&'static str, std::io::Error> {
|
||||
@@ -43,44 +34,58 @@ impl RogCore {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fan_mode_reload(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let path = RogCore::get_fan_path()?;
|
||||
let mut file = OpenOptions::new().write(true).open(path)?;
|
||||
pub(super) fn fan_mode_reload(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let mut file = OpenOptions::new().write(true).open(self.path)?;
|
||||
file.write_all(format!("{:?}\n", config.fan_mode).as_bytes())
|
||||
.unwrap_or_else(|err| error!("Could not write to {}, {:?}", path, err));
|
||||
.unwrap_or_else(|err| error!("Could not write to {}, {:?}", self.path, err));
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(config.fan_mode), config)?;
|
||||
info!("Reloaded fan mode: {:?}", FanLevel::from(config.fan_mode));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_fan_mode(&mut self, n: u8, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
let path = RogCore::get_fan_path()?;
|
||||
let mut fan_ctrl = OpenOptions::new().read(true).write(true).open(path)?;
|
||||
pub(super) fn fan_mode_check_change(
|
||||
&mut self,
|
||||
config: &mut Config,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut file = OpenOptions::new().read(true).open(self.path)?;
|
||||
let mut buf = [0u8; 1];
|
||||
file.read_exact(&mut buf)?;
|
||||
if let Some(num) = char::from(buf[0]).to_digit(10) {
|
||||
if config.fan_mode != num as u8 {
|
||||
config.fan_mode = num as u8;
|
||||
config.write();
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(config.fan_mode), config)?;
|
||||
info!(
|
||||
"Fan mode was changed: {:?}",
|
||||
FanLevel::from(config.fan_mode)
|
||||
);
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
let err = std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
"Fan-level could not be parsed",
|
||||
);
|
||||
Err(Box::new(err))
|
||||
}
|
||||
|
||||
pub(super) fn set_fan_mode(
|
||||
&mut self,
|
||||
n: u8,
|
||||
config: &mut Config,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut fan_ctrl = OpenOptions::new().write(true).open(self.path)?;
|
||||
|
||||
config.fan_mode = n;
|
||||
config.write();
|
||||
fan_ctrl
|
||||
.write_all(format!("{:?}\n", config.fan_mode).as_bytes())
|
||||
.unwrap_or_else(|err| error!("Could not write to {}, {:?}", path, err));
|
||||
.unwrap_or_else(|err| error!("Could not write to {}, {:?}", self.path, err));
|
||||
info!("Fan mode set to: {:?}", FanLevel::from(config.fan_mode));
|
||||
self.set_pstate_for_fan_mode(FanLevel::from(n), config)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fan_mode_step(&mut self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
// re-read the config here in case a user changed the pstate settings
|
||||
config.read();
|
||||
|
||||
let mut n = config.fan_mode;
|
||||
// wrap around the step number
|
||||
if n < 2 {
|
||||
n += 1;
|
||||
} else {
|
||||
n = 0;
|
||||
}
|
||||
self.set_fan_mode(n, config)
|
||||
}
|
||||
|
||||
fn set_pstate_for_fan_mode(
|
||||
&self,
|
||||
mode: FanLevel,
|
||||
@@ -171,89 +176,10 @@ impl RogCore {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn bat_charge_limit_reload(&self, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
config.read();
|
||||
info!("Reloaded battery charge limit");
|
||||
self.set_charge_limit(config.bat_charge_limit, config)
|
||||
}
|
||||
|
||||
pub fn set_charge_limit(&self, limit: u8, config: &mut Config) -> Result<(), Box<dyn Error>> {
|
||||
if limit < 20 || limit > 100 {
|
||||
warn!(
|
||||
"Unable to set battery charge limit, must be between 20-100: requested {}",
|
||||
limit
|
||||
);
|
||||
}
|
||||
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.open(BAT_CHARGE_PATH)
|
||||
.map_err(|err| {
|
||||
warn!("Failed to open battery charge limit path: {:?}", err);
|
||||
err
|
||||
})?;
|
||||
file.write_all(limit.to_string().as_bytes())
|
||||
.unwrap_or_else(|err| error!("Could not write to {}, {:?}", BAT_CHARGE_PATH, err));
|
||||
info!("Battery charge limit: {}", limit);
|
||||
|
||||
config.bat_charge_limit = limit;
|
||||
config.write();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// A direct call to systemd to suspend the PC.
|
||||
///
|
||||
/// This avoids desktop environments being required to handle it
|
||||
/// (which means it works while in a TTY also)
|
||||
pub fn suspend_with_systemd(&self) {
|
||||
std::process::Command::new("systemctl")
|
||||
.arg("suspend")
|
||||
.spawn()
|
||||
.map_or_else(|err| warn!("Failed to suspend: {}", err), |_| {});
|
||||
}
|
||||
|
||||
/// A direct call to rfkill to suspend wireless devices.
|
||||
///
|
||||
/// This avoids desktop environments being required to handle it (which
|
||||
/// means it works while in a TTY also)
|
||||
pub fn toggle_airplane_mode(&self) {
|
||||
match Command::new("rfkill").arg("list").output() {
|
||||
Ok(output) => {
|
||||
if output.status.success() {
|
||||
if let Ok(out) = String::from_utf8(output.stdout) {
|
||||
if out.contains(": yes") {
|
||||
Command::new("rfkill")
|
||||
.arg("unblock")
|
||||
.arg("all")
|
||||
.spawn()
|
||||
.map_or_else(
|
||||
|err| warn!("Could not unblock rf devices: {}", err),
|
||||
|_| {},
|
||||
);
|
||||
} else {
|
||||
Command::new("rfkill")
|
||||
.arg("block")
|
||||
.arg("all")
|
||||
.spawn()
|
||||
.map_or_else(
|
||||
|err| warn!("Could not block rf devices: {}", err),
|
||||
|_| {},
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("Could not list rf devices");
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("Could not list rf devices: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use crate::error::RogError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FanLevel {
|
||||
Normal,
|
||||
@@ -3,7 +3,7 @@ static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
use crate::{config::Config, error::RogError};
|
||||
use log::{error, info, warn};
|
||||
use log::{info, warn};
|
||||
use rog_client::{
|
||||
aura_brightness_bytes, aura_modes::AuraModes, fancy::KeyColourArray, LED_MSG_LEN,
|
||||
};
|
||||
@@ -18,17 +18,18 @@ pub struct LedWriter {
|
||||
|
||||
impl LedWriter {
|
||||
#[inline]
|
||||
pub fn new(idProduct: &str, supported_modes: Vec<u8>) -> Result<Self, std::io::Error> {
|
||||
pub fn new(id_product: &str, supported_modes: Vec<u8>) -> Result<Self, std::io::Error> {
|
||||
let mut enumerator = udev::Enumerator::new()?;
|
||||
enumerator.match_subsystem("hidraw")?;
|
||||
|
||||
for device in enumerator.scan_devices()? {
|
||||
if let Some(parent) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
|
||||
if parent.attribute_value("idProduct").unwrap() == idProduct
|
||||
if let Some(parent) = device
|
||||
.parent_with_subsystem_devtype("usb", "usb_device")? {
|
||||
if parent.attribute_value("idProduct").unwrap() == id_product
|
||||
// && device.parent().unwrap().sysnum().unwrap() == 3
|
||||
{
|
||||
if let Some(dev_node) = device.devnode() {
|
||||
info!("Using device at: {:?}", dev_node);
|
||||
info!("Using device at: {:?} for LED control", dev_node);
|
||||
return Ok(LedWriter {
|
||||
dev_node: dev_node.to_string_lossy().to_string(),
|
||||
supported_modes,
|
||||
@@ -1,10 +1,11 @@
|
||||
use crate::{
|
||||
animatrix_control::{AniMeWriter, AnimatrixCommand},
|
||||
config::Config,
|
||||
ctrl_anime::{AniMeWriter, AnimatrixCommand},
|
||||
ctrl_charge::CtrlCharge,
|
||||
ctrl_fan_cpu::CtrlFanAndCPU,
|
||||
ctrl_leds::LedWriter,
|
||||
dbus::dbus_create_tree,
|
||||
laptops::match_laptop,
|
||||
led_control::LedWriter,
|
||||
rog_dbus::dbus_create_tree,
|
||||
rogcore::*,
|
||||
};
|
||||
|
||||
use dbus::{channel::Sender, nonblock::Process, nonblock::SyncConnection, tree::Signal};
|
||||
@@ -34,34 +35,58 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
info!("Config loaded");
|
||||
|
||||
let mut rogcore = RogCore::new(laptop.usb_vendor(), laptop.usb_product());
|
||||
let mut led_control = LedWriter::new(laptop.usb_product(), laptop.supported_modes().to_owned())
|
||||
.map_or_else(
|
||||
|err| {
|
||||
error!("{}", err);
|
||||
None
|
||||
},
|
||||
|ledwriter| {
|
||||
info!("LED Writer loaded");
|
||||
Some(ledwriter)
|
||||
},
|
||||
);
|
||||
|
||||
// Reload settings
|
||||
rogcore
|
||||
.fan_mode_reload(&mut config)
|
||||
.unwrap_or_else(|err| warn!("Fan mode: {}", err));
|
||||
rogcore
|
||||
.bat_charge_limit_reload(&mut config)
|
||||
.unwrap_or_else(|err| warn!("Battery charge limit: {}", err));
|
||||
|
||||
let mut led_writer = LedWriter::new(
|
||||
"1866",
|
||||
laptop.supported_modes().to_owned(),
|
||||
).map_or_else(
|
||||
let mut charge_control = CtrlCharge::new().map_or_else(
|
||||
|err| {
|
||||
error!("{}", err);
|
||||
None
|
||||
},
|
||||
|ledwriter| {
|
||||
info!("LED Writer loaded");
|
||||
info!("Charge control loaded");
|
||||
Some(ledwriter)
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(writer) = led_writer.as_mut() {
|
||||
writer.reload_last_builtin(&mut config)
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("Reload settings: {}", err));
|
||||
let mut fan_control = CtrlFanAndCPU::new().map_or_else(
|
||||
|err| {
|
||||
error!("{}", err);
|
||||
None
|
||||
},
|
||||
|ledwriter| {
|
||||
info!("Fan & CPU control loaded");
|
||||
Some(ledwriter)
|
||||
},
|
||||
);
|
||||
|
||||
// Reload settings
|
||||
if let Some(ctrlr) = fan_control.as_mut() {
|
||||
ctrlr
|
||||
.fan_mode_reload(&mut config)
|
||||
.unwrap_or_else(|err| warn!("Fan mode: {}", err));
|
||||
}
|
||||
|
||||
if let Some(ctrlr) = charge_control.as_mut() {
|
||||
ctrlr
|
||||
.bat_charge_limit_reload(&mut config)
|
||||
.unwrap_or_else(|err| warn!("Battery charge limit: {}", err));
|
||||
}
|
||||
|
||||
if let Some(writer) = led_control.as_mut() {
|
||||
writer
|
||||
.reload_last_builtin(&mut config)
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("Reload settings: {}", err));
|
||||
}
|
||||
|
||||
// Set up the mutexes
|
||||
@@ -133,24 +158,34 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
loop {
|
||||
// TODO: MAKE SYS COMMANDS OPERATE USING CHANNEL LIKE AURA MODES
|
||||
// Fan mode
|
||||
if let Ok(mut lock) = fan_mode.try_lock() {
|
||||
if let Some(n) = lock.take() {
|
||||
let mut config = config1.lock().await;
|
||||
rogcore
|
||||
.set_fan_mode(n, &mut config)
|
||||
.unwrap_or_else(|err| warn!("{:?}", err));
|
||||
if let Some(ctrlr) = fan_control.as_mut() {
|
||||
let mut config = config1.lock().await;
|
||||
ctrlr
|
||||
.fan_mode_check_change(&mut config)
|
||||
.unwrap_or_else(|err| warn!("{:?}", err));
|
||||
|
||||
if let Ok(mut lock) = fan_mode.try_lock() {
|
||||
if let Some(n) = lock.take() {
|
||||
let mut config = config1.lock().await;
|
||||
ctrlr
|
||||
.set_fan_mode(n, &mut config)
|
||||
.unwrap_or_else(|err| warn!("{:?}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Charge limit
|
||||
if let Ok(mut lock) = charge_limit.try_lock() {
|
||||
if let Some(n) = lock.take() {
|
||||
let mut config = config1.lock().await;
|
||||
rogcore
|
||||
.set_charge_limit(n, &mut config)
|
||||
.unwrap_or_else(|err| warn!("{:?}", err));
|
||||
if let Some(ctrlr) = charge_control.as_mut() {
|
||||
if let Ok(mut lock) = charge_limit.try_lock() {
|
||||
if let Some(n) = lock.take() {
|
||||
let mut config = config1.lock().await;
|
||||
ctrlr
|
||||
.set_charge_limit(n, &mut config)
|
||||
.unwrap_or_else(|err| warn!("{:?}", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
tokio::time::delay_for(std::time::Duration::from_millis(500)).await;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -159,30 +194,31 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
connection.process_all();
|
||||
|
||||
while let Some(command) = aura_command_recv.recv().await {
|
||||
if let Some(writer) = led_writer.as_mut() {
|
||||
let mut config = config.lock().await;
|
||||
match &command {
|
||||
AuraModes::RGB(_) => {
|
||||
writer
|
||||
.do_command(command, &mut config)
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
if let Some(writer) = led_control.as_mut() {
|
||||
let mut config = config.lock().await;
|
||||
match &command {
|
||||
AuraModes::RGB(_) => {
|
||||
writer
|
||||
.do_command(command, &mut config)
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
}
|
||||
_ => {
|
||||
let json = serde_json::to_string(&command)?;
|
||||
writer
|
||||
.do_command(command, &mut config)
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
connection
|
||||
.send(
|
||||
led_changed_signal
|
||||
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
|
||||
.append1(json),
|
||||
)
|
||||
.unwrap_or_else(|_| 0);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let json = serde_json::to_string(&command)?;
|
||||
writer
|
||||
.do_command(command, &mut config)
|
||||
.await
|
||||
.unwrap_or_else(|err| warn!("{}", err));
|
||||
connection
|
||||
.send(
|
||||
led_changed_signal
|
||||
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
|
||||
.append1(json),
|
||||
)
|
||||
.unwrap_or_else(|_| 0);
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,12 @@ pub(crate) fn match_laptop() -> LaptopBase {
|
||||
let device_desc = device.device_descriptor().unwrap();
|
||||
if device_desc.vendor_id() == 0x0b05 {
|
||||
match device_desc.product_id() {
|
||||
0x1869 | 0x1866 => return select_1866_device(device_desc.product_id()),
|
||||
0x1866 => return select_1866_device("1866".to_owned()),
|
||||
0x1869 => return select_1866_device("1869".to_owned()),
|
||||
0x1854 => {
|
||||
info!("Found GL753 or similar");
|
||||
return LaptopBase {
|
||||
usb_vendor: 0x0B05,
|
||||
usb_product: 0x1854,
|
||||
//from `lsusb -vd 0b05:1866`
|
||||
led_endpoint: 0x04,
|
||||
usb_product: "1854".to_string(),
|
||||
supported_modes: vec![SINGLE, BREATHING, STROBE],
|
||||
support_animatrix: false,
|
||||
};
|
||||
@@ -30,7 +28,7 @@ pub(crate) fn match_laptop() -> LaptopBase {
|
||||
panic!("could not match laptop");
|
||||
}
|
||||
|
||||
fn select_1866_device(prod: u16) -> LaptopBase {
|
||||
fn select_1866_device(prod: String) -> LaptopBase {
|
||||
let dmi = sysfs_class::DmiId::default();
|
||||
let board_name = dmi.board_name().expect("Could not get board_name");
|
||||
let prod_name = dmi.product_name().expect("Could not get board_name");
|
||||
@@ -39,10 +37,7 @@ fn select_1866_device(prod: u16) -> LaptopBase {
|
||||
info!("Board name: {}", board_name.trim());
|
||||
|
||||
let mut laptop = LaptopBase {
|
||||
usb_vendor: 0x0B05,
|
||||
usb_product: prod,
|
||||
//from `lsusb -vd 0b05:1866`
|
||||
led_endpoint: 0x04,
|
||||
supported_modes: vec![],
|
||||
support_animatrix: false,
|
||||
};
|
||||
@@ -117,22 +112,14 @@ fn select_1866_device(prod: u16) -> LaptopBase {
|
||||
}
|
||||
|
||||
pub(super) struct LaptopBase {
|
||||
usb_vendor: u16,
|
||||
usb_product: u16,
|
||||
led_endpoint: u8,
|
||||
usb_product: String,
|
||||
supported_modes: Vec<u8>,
|
||||
support_animatrix: bool,
|
||||
}
|
||||
|
||||
impl LaptopBase {
|
||||
pub(super) fn led_endpoint(&self) -> u8 {
|
||||
self.led_endpoint
|
||||
}
|
||||
pub(super) fn usb_vendor(&self) -> u16 {
|
||||
self.usb_vendor
|
||||
}
|
||||
pub(super) fn usb_product(&self) -> u16 {
|
||||
self.usb_product
|
||||
pub(super) fn usb_product(&self) -> &str {
|
||||
&self.usb_product
|
||||
}
|
||||
pub(super) fn supported_modes(&self) -> &[u8] {
|
||||
&self.supported_modes
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#![deny(unused_must_use)]
|
||||
///
|
||||
mod animatrix_control;
|
||||
/// Configuration loading, saving
|
||||
mod config;
|
||||
///
|
||||
mod ctrl_anime;
|
||||
///
|
||||
mod ctrl_charge;
|
||||
///
|
||||
pub mod ctrl_fan_cpu;
|
||||
///
|
||||
mod ctrl_leds;
|
||||
/// Start the daemon loop
|
||||
pub mod daemon;
|
||||
///
|
||||
mod dbus;
|
||||
/// Laptop matching to determine capabilities
|
||||
mod laptops;
|
||||
///
|
||||
mod led_control;
|
||||
///
|
||||
mod rog_dbus;
|
||||
/// The core module which allows writing to LEDs or polling the
|
||||
/// laptop keyboard attached devices
|
||||
pub mod rogcore;
|
||||
|
||||
mod error;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use daemon::ctrl_fan_cpu::FanLevel;
|
||||
use daemon::daemon::start_daemon;
|
||||
use daemon::rogcore::FanLevel;
|
||||
use gumdrop::Options;
|
||||
use log::info;
|
||||
use log::LevelFilter;
|
||||
|
||||
Reference in New Issue
Block a user