rog-platform: add power (basics)

- Refactor the macros
- Add inotify creator for each attribute
This commit is contained in:
Luke D. Jones
2022-08-20 21:07:34 +12:00
parent 033f2141ef
commit f8cdde2adf
17 changed files with 345 additions and 187 deletions

View File

@@ -4,7 +4,7 @@ use log::{info, warn};
use crate::error::{PlatformError, Result};
#[derive(Debug, PartialEq, PartialOrd)]
#[derive(Debug, PartialEq, PartialOrd, Clone)]
pub struct HidRaw(PathBuf);
impl HidRaw {

View File

@@ -3,13 +3,15 @@ use std::path::PathBuf;
use log::warn;
use crate::{
attr_u8, attr_u8_array,
attr_u8,
error::{PlatformError, Result},
to_device,
has_attr, set_attr_u8_array, to_device,
};
#[derive(Debug, Default, PartialEq, PartialOrd)]
pub struct KeyboardLed(PathBuf);
#[derive(Debug, Default, PartialEq, PartialOrd, Clone)]
pub struct KeyboardLed {
path: PathBuf,
}
impl KeyboardLed {
pub fn new() -> Result<Self> {
@@ -34,26 +36,28 @@ impl KeyboardLed {
warn!("{}", err);
PlatformError::Udev("scan_devices failed".into(), err)
})? {
return Ok(Self(device.syspath().to_owned()));
return Ok(Self {
path: device.syspath().to_owned(),
});
}
Err(PlatformError::MissingFunction(
"asus::kbd_backlight not found".into(),
))
}
attr_u8!(has_brightness, get_brightness, set_brightness, "brightness");
attr_u8!("brightness", path);
attr_u8_array!(
has_keyboard_rgb_mode,
get_keyboard_rgb_mode,
set_keyboard_rgb_mode,
has_attr!("kbd_rgb_mode" path);
set_attr_u8_array!(
/// kbd_rgb_mode can only be set, not read back
"kbd_rgb_mode"
path
);
attr_u8_array!(
has_keyboard_rgb_state,
get_keyboard_rgb_state,
set_keyboard_rgb_state,
has_attr!("kbd_rgb_state" path);
set_attr_u8_array!(
/// kbd_rgb_state can only be set, not read back
"kbd_rgb_state"
path
);
}

View File

@@ -4,7 +4,9 @@
pub mod error;
pub mod hid_raw;
pub mod keyboard_led;
pub(crate) mod macros;
pub mod platform;
pub mod power;
pub mod supported;
pub mod usb_raw;
@@ -15,66 +17,6 @@ use udev::Device;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
#[macro_export]
macro_rules! attr_bool {
($hasser:ident, $getter:ident, $setter:ident, $attr_name:literal) => {
pub fn $hasser(&self) -> bool {
match to_device(&self.0) {
Ok(p) => crate::has_attr(&p, $attr_name),
Err(_) => false,
}
}
pub fn $getter(&self) -> Result<bool> {
crate::read_attr_bool(&to_device(&self.0)?, $attr_name)
}
pub fn $setter(&self, value: bool) -> Result<()> {
crate::write_attr_bool(&mut to_device(&self.0)?, $attr_name, value)
}
};
}
#[macro_export]
macro_rules! attr_u8 {
($hasser:ident, $getter:ident, $setter:ident, $attr_name:literal) => {
pub fn $hasser(&self) -> bool {
match to_device(&self.0) {
Ok(p) => crate::has_attr(&p, $attr_name),
Err(_) => false,
}
}
pub fn $getter(&self) -> Result<u8> {
crate::read_attr_u8(&to_device(&self.0)?, $attr_name)
}
pub fn $setter(&self, value: u8) -> Result<()> {
crate::write_attr_u8(&mut to_device(&self.0)?, $attr_name, value)
}
};
}
#[macro_export]
macro_rules! attr_u8_array {
($hasser:ident, $getter:ident, $setter:ident, $attr_name:literal) => {
pub fn $hasser(&self) -> bool {
match to_device(&self.0) {
Ok(p) => crate::has_attr(&p, $attr_name),
Err(_) => false,
}
}
pub fn $getter(&self) -> Result<Vec<u8>> {
crate::read_attr_u8_array(&to_device(&self.0)?, $attr_name)
}
pub fn $setter(&self, values: &[u8]) -> Result<()> {
crate::write_attr_u8_array(&mut to_device(&self.0)?, $attr_name, values)
}
};
}
pub(crate) fn to_device(sys_path: &Path) -> Result<Device> {
Device::from_syspath(sys_path)
.map_err(|e| PlatformError::Udev("Couldn't transform syspath to device".to_string(), e))

131
rog-platform/src/macros.rs Normal file
View File

@@ -0,0 +1,131 @@
#[macro_export]
macro_rules! has_attr {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = has_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self) -> bool {
match to_device(&self.$item) {
Ok(p) => crate::has_attr(&p, $attr_name),
Err(_) => false,
}
}
});
};
}
#[macro_export]
macro_rules! watch_attr {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = monitor_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self) -> Result<inotify::Inotify> {
let mut path = self.$item.clone();
path.push($attr_name);
let mut inotify = inotify::Inotify::init().unwrap();
inotify.add_watch(path.to_str().unwrap(), inotify::WatchMask::MODIFY).unwrap();
Ok(inotify)
}
});
};
}
#[macro_export]
macro_rules! get_attr_bool {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = get_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self) -> Result<bool> {
crate::read_attr_bool(&to_device(&self.$item)?, $attr_name)
}
});
};
}
#[macro_export]
macro_rules! set_attr_bool {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = set_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self, value: bool) -> Result<()> {
crate::write_attr_bool(&mut to_device(&self.$item)?, $attr_name, value)
}
});
};
}
#[macro_export]
macro_rules! attr_bool {
($attr_name:literal, $item:ident) => {
crate::has_attr!($attr_name $item);
crate::get_attr_bool!( $attr_name $item);
crate::set_attr_bool!($attr_name $item);
crate::watch_attr!($attr_name $item);
};
}
#[macro_export]
macro_rules! get_attr_u8 {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = get_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self) -> Result<u8> {
crate::read_attr_u8(&to_device(&self.$item)?, $attr_name)
}
});
};
}
#[macro_export]
macro_rules! set_attr_u8 {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = set_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self, value: u8) -> Result<()> {
crate::write_attr_u8(&mut to_device(&self.$item)?, $attr_name, value)
}
});
};
}
#[macro_export]
macro_rules! attr_u8 {
($attr_name:literal, $item:ident) => {
crate::has_attr!($attr_name $item);
crate::get_attr_u8!($attr_name $item);
crate::set_attr_u8!($attr_name $item);
crate::watch_attr!($attr_name $item);
};
}
#[macro_export]
macro_rules! get_attr_u8_array {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = get_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self) -> Result<Vec<u8>> {
crate::read_attr_u8_array(&to_device(&self.$item)?, $attr_name)
}
});
};
}
#[macro_export]
macro_rules! set_attr_u8_array {
($(#[$doc_comment:meta])? $attr_name:literal $item:ident) => {
concat_idents::concat_idents!(fn_name = set_, $attr_name {
$(#[$doc_comment])*
pub fn fn_name(&self, values: &[u8]) -> Result<()> {
crate::write_attr_u8_array(&mut to_device(&self.$item)?, $attr_name, values)
}
});
};
}
#[macro_export]
macro_rules! attr_u8_array {
($attr_name:literal, $item:ident) => {
crate::has_attr!($attr_name $item);
crate::get_attr_u8_array!($attr_name $item);
crate::set_attr_u8_array!($attr_name $item);
};
}

View File

@@ -17,8 +17,10 @@ use crate::{
/// - dgpu_only
/// - keyboard_mode, set keyboard RGB mode and speed
/// - keyboard_state, set keyboard power states
#[derive(Debug, PartialEq, PartialOrd)]
pub struct AsusPlatform(PathBuf);
#[derive(Debug, PartialEq, PartialOrd, Clone)]
pub struct AsusPlatform {
path: PathBuf,
}
impl AsusPlatform {
pub fn new() -> Result<Self> {
@@ -39,35 +41,19 @@ impl AsusPlatform {
warn!("{}", err);
PlatformError::Udev("scan_devices failed".into(), err)
})? {
return Ok(Self(device.syspath().to_owned()));
return Ok(Self {
path: device.syspath().to_owned(),
});
}
Err(PlatformError::MissingFunction(
"asus-nb-wmi not found".into(),
))
}
attr_bool!(
has_dgpu_disable,
get_dgpu_disable,
set_dgpu_disable,
"dgpu_disable"
);
attr_bool!(
has_egpu_enable,
get_egpu_enable,
set_egpu_enable,
"egpu_enable"
);
attr_bool!(has_panel_od, get_panel_od, set_panel_od, "panel_od");
attr_u8!(
has_gpu_mux_mode,
get_gpu_mux_mode,
set_gpu_mux_mode,
"gpu_mux_mode"
);
attr_bool!("dgpu_disable", path);
attr_bool!("egpu_enable", path);
attr_bool!("panel_od", path);
attr_u8!("gpu_mux_mode", path);
}
#[derive(Serialize, Deserialize, Type, Debug, PartialEq, Clone, Copy)]

62
rog-platform/src/power.rs Normal file
View File

@@ -0,0 +1,62 @@
use std::path::PathBuf;
use log::warn;
use crate::{
attr_u8,
error::{PlatformError, Result},
to_device,
};
/// The "platform" device provides access to things like:
/// - dgpu_disable
/// - egpu_enable
/// - panel_od
/// - dgpu_only
/// - keyboard_mode, set keyboard RGB mode and speed
/// - keyboard_state, set keyboard power states
#[derive(Debug, PartialEq, PartialOrd, Clone)]
pub struct AsusPower {
mains: PathBuf,
battery: PathBuf,
usb: Option<PathBuf>,
}
impl AsusPower {
pub fn new() -> Result<Self> {
let mut mains = PathBuf::new();
let mut battery = PathBuf::new();
let mut usb = None;
let mut enumerator = udev::Enumerator::new().map_err(|err| {
warn!("{}", err);
PlatformError::Udev("enumerator failed".into(), err)
})?;
enumerator.match_subsystem("power_supply").map_err(|err| {
warn!("{}", err);
PlatformError::Udev("match_subsystem failed".into(), err)
})?;
for device in enumerator.scan_devices().map_err(|err| {
warn!("{}", err);
PlatformError::Udev("scan_devices failed".into(), err)
})? {
if let Some(attr) = device.attribute_value("type") {
match attr.to_os_string().as_os_str().to_str() {
Some("Mains") => mains = device.syspath().to_path_buf(),
Some("Battery") => battery = device.syspath().to_path_buf(),
Some("USB") => usb = Some(device.syspath().to_path_buf()),
_ => {}
};
}
}
Ok(Self {
mains,
battery,
usb,
})
}
attr_u8!("charge_control_end_threshold", battery);
}

View File

@@ -3,7 +3,7 @@ use serde_derive::{Deserialize, Serialize};
use std::fmt;
use zvariant_derive::Type;
#[derive(Serialize, Deserialize, Type, Debug, Default)]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct SupportedFunctions {
pub anime_ctrl: AnimeSupportedFunctions,
pub charge_ctrl: ChargeSupportedFunctions,
@@ -12,21 +12,21 @@ pub struct SupportedFunctions {
pub rog_bios_ctrl: RogBiosSupportedFunctions,
}
#[derive(Serialize, Deserialize, Type, Debug, Default)]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct AnimeSupportedFunctions(pub bool);
#[derive(Serialize, Deserialize, Type, Debug, Default)]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct ChargeSupportedFunctions {
pub charge_level_set: bool,
}
#[derive(Serialize, Deserialize, Type, Debug, Default)]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct PlatformProfileFunctions {
pub platform_profile: bool,
pub fan_curves: bool,
}
#[derive(Serialize, Deserialize, Type, Debug, Default)]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct LedSupportedFunctions {
pub prod_id: AuraDevice,
pub brightness_set: bool,
@@ -35,7 +35,7 @@ pub struct LedSupportedFunctions {
pub per_key_led_mode: bool,
}
#[derive(Serialize, Deserialize, Type, Debug, Default)]
#[derive(Serialize, Deserialize, Type, Debug, Default, Clone)]
pub struct RogBiosSupportedFunctions {
pub post_sound: bool,
pub dgpu_only: bool,