mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
More logigng. Adjust the aura init process. Fix TUF led power
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [v6.0.6]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Add GX650R laptop to aura DB
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Further tweaks to aura init
|
||||||
|
- More logging
|
||||||
|
- Fix TUF laptop led power
|
||||||
|
|
||||||
## [v6.0.5]
|
## [v6.0.5]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -12,11 +12,15 @@ use rog_aura::{
|
|||||||
};
|
};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardBacklight;
|
use rog_platform::keyboard_led::KeyboardBacklight;
|
||||||
|
use udev::Device;
|
||||||
use zbus::zvariant::OwnedObjectPath;
|
use zbus::zvariant::OwnedObjectPath;
|
||||||
|
use zbus::Connection;
|
||||||
|
|
||||||
use super::config::AuraConfig;
|
use super::config::AuraConfig;
|
||||||
use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf};
|
use crate::ctrl_aura::manager::{dbus_path_for_dev, dbus_path_for_tuf, start_tasks};
|
||||||
|
use crate::ctrl_aura::trait_impls::CtrlAuraZbus;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
|
use crate::CtrlTask;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum LEDNode {
|
pub enum LEDNode {
|
||||||
@@ -99,10 +103,84 @@ pub struct CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlKbdLed {
|
impl CtrlKbdLed {
|
||||||
|
pub fn add_to_dbus_and_start(
|
||||||
|
self,
|
||||||
|
interfaces: &mut HashSet<OwnedObjectPath>,
|
||||||
|
conn: Connection,
|
||||||
|
) -> Result<(), RogError> {
|
||||||
|
let dbus_path = self.dbus_path.clone();
|
||||||
|
interfaces.insert(dbus_path.clone());
|
||||||
|
info!(
|
||||||
|
"AuraManager starting device at: {:?}, {:?}",
|
||||||
|
dbus_path, self.led_type
|
||||||
|
);
|
||||||
|
let conn_copy = conn.clone();
|
||||||
|
let sig_ctx1 = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||||
|
let sig_ctx2 = CtrlAuraZbus::signal_context(&conn_copy)?;
|
||||||
|
let zbus = CtrlAuraZbus::new(self, sig_ctx1);
|
||||||
|
tokio::spawn(
|
||||||
|
async move { start_tasks(zbus, conn_copy.clone(), sig_ctx2, dbus_path).await },
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build and init a `CtrlKbdLed` from a udev device. Maybe.
|
||||||
|
/// This will initialise the config also.
|
||||||
|
pub fn maybe_device(
|
||||||
|
device: Device,
|
||||||
|
interfaces: &mut HashSet<OwnedObjectPath>,
|
||||||
|
) -> Result<Option<Self>, RogError> {
|
||||||
|
// usb_device gives us a product and vendor ID
|
||||||
|
if let Some(usb_device) = device.parent_with_subsystem_devtype("usb", "usb_device")? {
|
||||||
|
let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default();
|
||||||
|
if interfaces.contains(&dbus_path) {
|
||||||
|
debug!("Already a ctrl at {dbus_path:?}");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The asus_wmi driver latches MCU that controls the USB endpoints
|
||||||
|
if let Some(parent) = device.parent() {
|
||||||
|
if let Some(driver) = parent.driver() {
|
||||||
|
// There is a tree of devices added so filter by driver
|
||||||
|
if driver != "asus" {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Device is something like 002, while its parent is the MCU
|
||||||
|
// Think of it like the device is an endpoint of the USB device attached
|
||||||
|
let mut prod_id = String::new();
|
||||||
|
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
||||||
|
prod_id = usb_id.to_string_lossy().to_string();
|
||||||
|
let aura_device = AuraDeviceType::from(prod_id.as_str());
|
||||||
|
if aura_device == AuraDeviceType::Unknown {
|
||||||
|
log::debug!("Unknown or invalid device: {usb_id:?}, skipping");
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let dev_node = if let Some(dev_node) = usb_device.devnode() {
|
||||||
|
dev_node
|
||||||
|
} else {
|
||||||
|
debug!("Device has no devnode, skipping");
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
info!("AuraControl found device at: {:?}", dev_node);
|
||||||
|
let dev = HidRaw::from_device(device)?;
|
||||||
|
let mut controller = Self::from_hidraw(dev, dbus_path.clone())?;
|
||||||
|
controller.config = Self::init_config(&prod_id);
|
||||||
|
interfaces.insert(dbus_path);
|
||||||
|
return Ok(Some(controller));
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn find_all() -> Result<Vec<Self>, RogError> {
|
pub fn find_all() -> Result<Vec<Self>, RogError> {
|
||||||
info!("Searching for all Aura devices");
|
info!("Searching for all Aura devices");
|
||||||
let mut devices = Vec::new();
|
let mut devices = Vec::new();
|
||||||
let mut found = HashSet::new(); // track and ensure we use only one hidraw per prod_id
|
let mut interfaces = HashSet::new(); // track and ensure we use only one hidraw per prod_id
|
||||||
|
|
||||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||||
warn!("{}", err);
|
warn!("{}", err);
|
||||||
@@ -115,46 +193,9 @@ impl CtrlKbdLed {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
for end_point in enumerator.scan_devices()? {
|
for end_point in enumerator.scan_devices()? {
|
||||||
// usb_device gives us a product and vendor ID
|
// maybe?
|
||||||
if let Some(usb_device) =
|
if let Some(device) = Self::maybe_device(end_point, &mut interfaces)? {
|
||||||
end_point.parent_with_subsystem_devtype("usb", "usb_device")?
|
devices.push(device);
|
||||||
{
|
|
||||||
// The asus_wmi driver latches MCU that controls the USB endpoints
|
|
||||||
if let Some(parent) = end_point.parent() {
|
|
||||||
if let Some(driver) = parent.driver() {
|
|
||||||
// There is a tree of devices added so filter by driver
|
|
||||||
if driver != "asus" {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Device is something like 002, while its parent is the MCU
|
|
||||||
// Think of it like the device is an endpoint of the USB device attached
|
|
||||||
let mut prod_id = String::new();
|
|
||||||
if let Some(usb_id) = usb_device.attribute_value("idProduct") {
|
|
||||||
prod_id = usb_id.to_string_lossy().to_string();
|
|
||||||
let aura_dev = AuraDeviceType::from(prod_id.as_str());
|
|
||||||
if aura_dev == AuraDeviceType::Unknown || found.contains(&aura_dev) {
|
|
||||||
log::debug!("Unknown or invalid device: {usb_id:?}, skipping");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
found.insert(aura_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
let dev_node = if let Some(dev_node) = usb_device.devnode() {
|
|
||||||
dev_node
|
|
||||||
} else {
|
|
||||||
debug!("Device has no devnode, skipping");
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
info!("AuraControl found device at: {:?}", dev_node);
|
|
||||||
let dbus_path = dbus_path_for_dev(&usb_device).unwrap_or_default();
|
|
||||||
let dev = HidRaw::from_device(end_point)?;
|
|
||||||
let mut dev = Self::from_hidraw(dev, dbus_path)?;
|
|
||||||
dev.config = Self::init_config(&prod_id);
|
|
||||||
devices.push(dev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,13 +305,10 @@ impl CtrlKbdLed {
|
|||||||
/// Set combination state for boot animation/sleep animation/all leds/keys
|
/// Set combination state for boot animation/sleep animation/all leds/keys
|
||||||
/// leds/side leds LED active
|
/// leds/side leds LED active
|
||||||
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
||||||
if let LEDNode::KbdLed(_platform) = &mut self.led_node {
|
if let LEDNode::KbdLed(platform) = &mut self.led_node {
|
||||||
// TODO: tuf bool array
|
// TODO: tuf bool array
|
||||||
// if let Some(pwr) =
|
let buf = self.config.enabled.to_bytes(self.led_type);
|
||||||
// AuraPowerConfig::to_tuf_bool_array(&self.config.enabled) {
|
platform.set_kbd_rgb_state(&buf)?;
|
||||||
// let buf = [1, pwr[1] as u8, pwr[2] as u8, pwr[3] as u8,
|
|
||||||
// pwr[4] as u8]; platform.set_kbd_rgb_state(&buf)?;
|
|
||||||
// }
|
|
||||||
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
} else if let LEDNode::Rog(_, hid_raw) = &self.led_node {
|
||||||
let bytes = self.config.enabled.to_bytes(self.led_type);
|
let bytes = self.config.enabled.to_bytes(self.led_type);
|
||||||
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
|
let message = [0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3]];
|
||||||
|
|||||||
@@ -6,10 +6,8 @@
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use log::{debug, error, info, warn};
|
use log::{error, info, warn};
|
||||||
use mio::{Events, Interest, Poll, Token};
|
use mio::{Events, Interest, Poll, Token};
|
||||||
use rog_aura::AuraDeviceType;
|
|
||||||
use rog_platform::hid_raw::HidRaw;
|
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
use udev::{Device, MonitorBuilder};
|
use udev::{Device, MonitorBuilder};
|
||||||
use zbus::object_server::SignalContext;
|
use zbus::object_server::SignalContext;
|
||||||
@@ -59,93 +57,42 @@ impl AuraManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for event in monitor.iter() {
|
for event in monitor.iter() {
|
||||||
let parent = if let Some(parent) =
|
let action = event.action().unwrap_or_default();
|
||||||
|
|
||||||
|
if let Some(parent) =
|
||||||
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
event.parent_with_subsystem_devtype("usb", "usb_device")?
|
||||||
{
|
{
|
||||||
parent
|
if action == "remove" {
|
||||||
} else {
|
if let Some(path) = dbus_path_for_dev(&parent) {
|
||||||
continue;
|
if interfaces.remove(&path) {
|
||||||
};
|
info!("AuraManager removing: {path:?}");
|
||||||
|
|
||||||
let action = if let Some(action) = event.action() {
|
|
||||||
action
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let id_product = if let Some(id_product) = parent.attribute_value("idProduct") {
|
|
||||||
id_product.to_string_lossy()
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let path = if let Some(path) = dbus_path_for_dev(&parent) {
|
|
||||||
path
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let aura_device = AuraDeviceType::from(&*id_product);
|
|
||||||
if aura_device == AuraDeviceType::Unknown {
|
|
||||||
warn!("idProduct:{id_product:?} is unknown, not using");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if action == "remove" {
|
|
||||||
if interfaces.remove(&path) {
|
|
||||||
info!("AuraManager removing: {path:?}");
|
|
||||||
let conn_copy = conn_copy.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let res = conn_copy
|
|
||||||
.object_server()
|
|
||||||
.remove::<CtrlAuraZbus, _>(&path)
|
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("Failed to remove {path:?}, {e:?}");
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
info!("AuraManager removed: {path:?}, {res}");
|
|
||||||
Ok::<(), RogError>(())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if action == "add" {
|
|
||||||
if interfaces.contains(&path) {
|
|
||||||
debug!("Already a ctrl at {path:?}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to check the driver is asus to prevent using hid_generic
|
|
||||||
if let Some(p2) = event.parent() {
|
|
||||||
if let Some(driver) = p2.driver() {
|
|
||||||
// There is a tree of devices added so filter by driver
|
|
||||||
if driver != "asus" {
|
|
||||||
debug!("{id_product:?} driver was not asus, skipping");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(dev_node) = event.devnode() {
|
|
||||||
if let Ok(raw) = HidRaw::from_device(event.device())
|
|
||||||
.map_err(|e| error!("device path error: {e:?}"))
|
|
||||||
{
|
|
||||||
if let Ok(mut ctrl) = CtrlKbdLed::from_hidraw(raw, path.clone()) {
|
|
||||||
ctrl.config = CtrlKbdLed::init_config(&id_product);
|
|
||||||
interfaces.insert(path.clone());
|
|
||||||
info!("AuraManager starting device at: {dev_node:?}, {path:?}");
|
|
||||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
|
||||||
let zbus = CtrlAuraZbus::new(ctrl, sig_ctx);
|
|
||||||
let sig_ctx = CtrlAuraZbus::signal_context(&conn_copy)?;
|
|
||||||
let conn_copy = conn_copy.clone();
|
let conn_copy = conn_copy.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
start_tasks(zbus, conn_copy.clone(), sig_ctx, path).await
|
let res = conn_copy
|
||||||
|
.object_server()
|
||||||
|
.remove::<CtrlAuraZbus, _>(&path)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Failed to remove {path:?}, {e:?}");
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
info!("AuraManager removed: {path:?}, {res}");
|
||||||
|
Ok::<(), RogError>(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if action == "add" {
|
||||||
};
|
if let Ok(Some(ctrl)) =
|
||||||
|
CtrlKbdLed::maybe_device(event.device(), &mut interfaces)
|
||||||
|
{
|
||||||
|
ctrl.add_to_dbus_and_start(&mut interfaces, conn_copy.clone())
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Couldn't start aura device on dbus: {e:?}")
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Required for return type on spawn
|
// Required for return type on spawn
|
||||||
@@ -169,7 +116,7 @@ pub(crate) fn dbus_path_for_tuf() -> OwnedObjectPath {
|
|||||||
ObjectPath::from_str_unchecked(&format!("{AURA_ZBUS_PATH}/tuf")).into()
|
ObjectPath::from_str_unchecked(&format!("{AURA_ZBUS_PATH}/tuf")).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn start_tasks(
|
pub async fn start_tasks(
|
||||||
mut zbus: CtrlAuraZbus,
|
mut zbus: CtrlAuraZbus,
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
_signal_ctx: SignalContext<'static>,
|
_signal_ctx: SignalContext<'static>,
|
||||||
@@ -180,7 +127,12 @@ async fn start_tasks(
|
|||||||
zbus.reload()
|
zbus.reload()
|
||||||
.await
|
.await
|
||||||
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
.unwrap_or_else(|err| warn!("Controller error: {}", err));
|
||||||
connection.object_server().at(path, zbus).await.unwrap();
|
connection
|
||||||
|
.object_server()
|
||||||
|
.at(path.clone(), zbus)
|
||||||
|
.await
|
||||||
|
.map_err(|e| error!("Couldn't add server at path: {path}, {e:?}"))
|
||||||
|
.ok();
|
||||||
// TODO: skip this until we keep handles to tasks so they can be killed
|
// TODO: skip this until we keep handles to tasks so they can be killed
|
||||||
// task.create_tasks(signal_ctx).await
|
// task.create_tasks(signal_ctx).await
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -279,8 +279,10 @@ impl CtrlTask for CtrlAuraZbus {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.for_each(|_| async {
|
.for_each(|_| async {
|
||||||
if let Some(lock) = ctrl2.try_lock() {
|
if let Some(lock) = ctrl2.try_lock() {
|
||||||
load_save(true, lock).unwrap(); // unwrap as we want to
|
load_save(true, lock).unwrap(); // unwrap as we want
|
||||||
// bomb out of the task
|
// to
|
||||||
|
// bomb out of the
|
||||||
|
// task
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@@ -746,6 +746,15 @@
|
|||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
device_name: "GX650R",
|
||||||
|
product_id: "",
|
||||||
|
layout_name: "gx531-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
power_zones: [Keyboard],
|
||||||
|
),
|
||||||
(
|
(
|
||||||
device_name: "GX701",
|
device_name: "GX701",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ impl LedSupportData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!("Using generic LED control for keyboard brightness only");
|
info!("Using generic LED control for keyboard brightness only");
|
||||||
LedSupportData::default()
|
let mut data = LedSupportData::default();
|
||||||
|
data.power_zones.push(PowerZones::Keyboard);
|
||||||
|
data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ impl AuraPowerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tuf_to_bytes(&self) -> Vec<u8> {
|
fn tuf_to_bytes(&self) -> Vec<u8> {
|
||||||
todo!("0s and 1s for bool array")
|
// &cmd, &boot, &awake, &sleep, &keyboard
|
||||||
|
vec![1, self.boot as u8, self.awake as u8, self.sleep as u8, 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Bits for older 0x1866 keyboard model
|
/// # Bits for older 0x1866 keyboard model
|
||||||
|
|||||||
Reference in New Issue
Block a user