mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
working with hardcoded devnode. need to change
This commit is contained in:
@@ -119,6 +119,7 @@ Models GA401, GA502, GU502 support LED brightness change only (no RGB).
|
||||
- `libdbus-1-dev`
|
||||
- `llvm`
|
||||
- `libclang-dev`
|
||||
- `libudev-dev`
|
||||
|
||||
## Installing
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@ pub mod anime_matrix;
|
||||
|
||||
pub mod error;
|
||||
|
||||
// static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
// static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||
// static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
// static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
||||
// static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
|
||||
/// Writes aout the correct byte string for brightness
|
||||
///
|
||||
/// The HID descriptor looks like:
|
||||
|
||||
@@ -34,21 +34,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
info!("Config loaded");
|
||||
|
||||
let mut rogcore = RogCore::new(
|
||||
laptop.usb_vendor(),
|
||||
laptop.usb_product(),
|
||||
laptop.key_endpoint(),
|
||||
)
|
||||
.map_or_else(
|
||||
|err| {
|
||||
error!("{}", err);
|
||||
panic!("{}", err);
|
||||
},
|
||||
|daemon| {
|
||||
info!("RogCore loaded");
|
||||
daemon
|
||||
},
|
||||
);
|
||||
let mut rogcore = RogCore::new(laptop.usb_vendor(), laptop.usb_product());
|
||||
|
||||
// Reload settings
|
||||
rogcore
|
||||
@@ -59,8 +45,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
.unwrap_or_else(|err| warn!("Battery charge limit: {}", err));
|
||||
|
||||
let mut led_writer = LedWriter::new(
|
||||
rogcore.get_raw_device_handle(),
|
||||
laptop.led_endpoint(),
|
||||
"/dev/hidraw2".to_string(),
|
||||
laptop.supported_modes().to_owned(),
|
||||
);
|
||||
|
||||
@@ -136,6 +121,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
// spawning this in a function causes a segfault for reasons I haven't investigated yet
|
||||
tokio::spawn(async move {
|
||||
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() {
|
||||
@@ -154,7 +140,7 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
.unwrap_or_else(|err| warn!("{:?}", err));
|
||||
}
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -262,4 +248,3 @@ async fn send_boot_signals(
|
||||
.unwrap_or_else(|_| 0);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use rog_client::{
|
||||
aura_modes::{
|
||||
AuraModes, BREATHING, COMET, FLASH, HIGHLIGHT, LASER, MULTISTATIC, PULSE, RAIN, RAINBOW,
|
||||
RGB, RIPPLE, SINGLE, STAR, STROBE,
|
||||
},
|
||||
};
|
||||
use log::{info, warn};
|
||||
use rog_client::aura_modes::{
|
||||
AuraModes, BREATHING, COMET, FLASH, HIGHLIGHT, LASER, MULTISTATIC, PULSE, RAIN, RAINBOW, RGB,
|
||||
RIPPLE, SINGLE, STAR, STROBE,
|
||||
};
|
||||
|
||||
static HELP_ADDRESS: &str = "https://github.com/flukejones/rog-core";
|
||||
|
||||
@@ -21,8 +19,6 @@ pub(crate) fn match_laptop() -> LaptopBase {
|
||||
usb_product: 0x1854,
|
||||
//from `lsusb -vd 0b05:1866`
|
||||
led_endpoint: 0x04,
|
||||
//from `lsusb -vd 0b05:1866`
|
||||
key_endpoint: 0x83,
|
||||
supported_modes: vec![SINGLE, BREATHING, STROBE],
|
||||
support_animatrix: false,
|
||||
};
|
||||
@@ -47,8 +43,6 @@ fn select_1866_device(prod: u16) -> LaptopBase {
|
||||
usb_product: prod,
|
||||
//from `lsusb -vd 0b05:1866`
|
||||
led_endpoint: 0x04,
|
||||
//from `lsusb -vd 0b05:1866`
|
||||
key_endpoint: 0x83,
|
||||
supported_modes: vec![],
|
||||
support_animatrix: false,
|
||||
};
|
||||
@@ -72,12 +66,22 @@ fn select_1866_device(prod: u16) -> LaptopBase {
|
||||
SINGLE, BREATHING, STROBE, RAINBOW, STAR, RAIN, HIGHLIGHT, LASER, RIPPLE, PULSE, COMET,
|
||||
FLASH, RGB,
|
||||
];
|
||||
} else if board_name.starts_with("G531")
|
||||
|| board_name.starts_with("G731")
|
||||
{
|
||||
} else if board_name.starts_with("G531") || board_name.starts_with("G731") {
|
||||
laptop.supported_modes = vec![
|
||||
SINGLE, BREATHING, STROBE, RAINBOW, STAR, RAIN, HIGHLIGHT, LASER, RIPPLE, PULSE, COMET,
|
||||
FLASH, MULTISTATIC, RGB,
|
||||
SINGLE,
|
||||
BREATHING,
|
||||
STROBE,
|
||||
RAINBOW,
|
||||
STAR,
|
||||
RAIN,
|
||||
HIGHLIGHT,
|
||||
LASER,
|
||||
RIPPLE,
|
||||
PULSE,
|
||||
COMET,
|
||||
FLASH,
|
||||
MULTISTATIC,
|
||||
RGB,
|
||||
];
|
||||
// RGB, limited effects, no zones
|
||||
} else if board_name.starts_with("G512LI") || board_name.starts_with("G712LI") {
|
||||
@@ -116,7 +120,6 @@ pub(super) struct LaptopBase {
|
||||
usb_vendor: u16,
|
||||
usb_product: u16,
|
||||
led_endpoint: u8,
|
||||
key_endpoint: u8,
|
||||
supported_modes: Vec<u8>,
|
||||
support_animatrix: bool,
|
||||
}
|
||||
@@ -125,9 +128,6 @@ impl LaptopBase {
|
||||
pub(super) fn led_endpoint(&self) -> u8 {
|
||||
self.led_endpoint
|
||||
}
|
||||
pub(super) fn key_endpoint(&self) -> u8 {
|
||||
self.key_endpoint
|
||||
}
|
||||
pub(super) fn usb_vendor(&self) -> u16 {
|
||||
self.usb_vendor
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||
static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||
static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
|
||||
static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
||||
|
||||
// Only these two packets must be 17 bytes
|
||||
static LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 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];
|
||||
@@ -13,104 +7,46 @@ use log::{error, info, warn};
|
||||
use rog_client::{
|
||||
aura_brightness_bytes, aura_modes::AuraModes, fancy::KeyColourArray, LED_MSG_LEN,
|
||||
};
|
||||
use rusb::DeviceHandle;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::NonNull;
|
||||
use std::time::Duration;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
|
||||
/// UNSAFE: Must live as long as RogCore
|
||||
///
|
||||
/// Because we're holding a pointer to something that *may* go out of scope while the
|
||||
/// pointer is held. We're relying on access to struct to be behind a Mutex, and for behaviour
|
||||
/// that may cause invalididated pointer to cause the program to panic rather than continue.
|
||||
pub struct LedWriter<'d, C: 'd>
|
||||
where
|
||||
C: rusb::UsbContext,
|
||||
{
|
||||
handle: NonNull<DeviceHandle<C>>,
|
||||
pub struct LedWriter {
|
||||
dev_node: String,
|
||||
supported_modes: Vec<u8>,
|
||||
led_endpoint: u8,
|
||||
initialised: bool,
|
||||
flip_effect_write: bool,
|
||||
_phantom: PhantomData<&'d DeviceHandle<C>>,
|
||||
}
|
||||
|
||||
/// UNSAFE
|
||||
unsafe impl<'d, C> Send for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
unsafe impl<'d, C> Sync for LedWriter<'d, C> where C: rusb::UsbContext {}
|
||||
|
||||
impl<'d, C> LedWriter<'d, C>
|
||||
where
|
||||
C: rusb::UsbContext,
|
||||
{
|
||||
impl LedWriter {
|
||||
#[inline]
|
||||
pub fn new(
|
||||
device_handle: NonNull<DeviceHandle<C>>,
|
||||
led_endpoint: u8,
|
||||
supported_modes: Vec<u8>,
|
||||
) -> Self {
|
||||
pub fn new(dev_node: String, supported_modes: Vec<u8>) -> Self {
|
||||
LedWriter {
|
||||
handle: device_handle,
|
||||
led_endpoint,
|
||||
dev_node,
|
||||
supported_modes,
|
||||
initialised: false,
|
||||
flip_effect_write: false,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
async fn initialise(&mut self) -> Result<(), RogError> {
|
||||
if !self.initialised {
|
||||
self.write_bytes(&LED_INIT1).await?;
|
||||
self.write_bytes(LED_INIT2.as_bytes()).await?;
|
||||
self.write_bytes(&LED_INIT3).await?;
|
||||
self.write_bytes(LED_INIT4.as_bytes()).await?;
|
||||
self.write_bytes(&LED_INIT5).await?;
|
||||
self.initialised = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn do_command(
|
||||
&mut self,
|
||||
mode: AuraModes,
|
||||
config: &mut Config,
|
||||
) -> Result<(), RogError> {
|
||||
self.initialise().await?;
|
||||
self.set_and_save(mode, config).await
|
||||
}
|
||||
|
||||
/// Should only be used if the bytes you are writing are verified correct
|
||||
#[inline]
|
||||
async fn write_bytes(&self, message: &[u8]) -> Result<(), RogError> {
|
||||
println!("1 Wrote: {:X?}", message);
|
||||
match unsafe { self.handle.as_ref() }.write_interrupt(
|
||||
self.led_endpoint,
|
||||
message,
|
||||
Duration::from_millis(5),
|
||||
) {
|
||||
Ok(_) => {
|
||||
let mut buf = [0; 32];
|
||||
match unsafe { self.handle.as_ref() }.read_interrupt(
|
||||
0x83,
|
||||
&mut buf,
|
||||
Duration::from_millis(5),
|
||||
) {
|
||||
Ok(_) => {
|
||||
println!("2 Read: {:X?}", buf);
|
||||
}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to read to led interrupt: {:?}", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(err) => match err {
|
||||
rusb::Error::Timeout => {}
|
||||
_ => error!("Failed to write to led interrupt: {:?}", err),
|
||||
},
|
||||
if let Ok(mut file) = OpenOptions::new().write(true).open(&self.dev_node) {
|
||||
file.write_all(message).unwrap();
|
||||
return Ok(());
|
||||
}
|
||||
Ok(())
|
||||
Err(RogError::NotSupported)
|
||||
}
|
||||
|
||||
/// Write an effect block
|
||||
@@ -150,10 +86,6 @@ where
|
||||
config.current_mode = mode_num;
|
||||
config.set_mode_data(mode);
|
||||
config.write();
|
||||
info!(
|
||||
"Switched LED mode to {}",
|
||||
<&str>::from(&<AuraModes>::from(config.current_mode))
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -198,7 +130,6 @@ where
|
||||
|
||||
#[inline]
|
||||
pub async fn reload_last_builtin(&mut self, config: &mut Config) -> Result<(), RogError> {
|
||||
self.initialise().await?;
|
||||
// set current mode (if any)
|
||||
if self.supported_modes.len() > 1 {
|
||||
if self.supported_modes.contains(&config.current_mode) {
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
|
||||
use crate::{config::Config, error::RogError};
|
||||
use log::{error, info, warn};
|
||||
use rusb::{Device, DeviceHandle};
|
||||
use std::error::Error;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::marker::{PhantomPinned};
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::ptr::NonNull;
|
||||
use std::str::FromStr;
|
||||
|
||||
static FAN_TYPE_1_PATH: &str = "/sys/devices/platform/asus-nb-wmi/throttle_thermal_policy";
|
||||
@@ -26,72 +23,11 @@ static BAT_CHARGE_PATH: &str = "/sys/class/power_supply/BAT0/charge_control_end_
|
||||
/// - `LED_INIT4`
|
||||
/// - `LED_INIT2`
|
||||
/// - `LED_INIT4`
|
||||
pub struct RogCore {
|
||||
handle: DeviceHandle<rusb::GlobalContext>,
|
||||
_pin: PhantomPinned,
|
||||
}
|
||||
pub struct RogCore {}
|
||||
|
||||
impl RogCore {
|
||||
pub fn new(vendor: u16, product: u16, match_endpoint: u8) -> Result<RogCore, Box<dyn Error>> {
|
||||
let device = RogCore::get_device(vendor, product).map_err(|err| {
|
||||
error!("Could not find keyboard device: {:?}", err);
|
||||
err
|
||||
})?;
|
||||
|
||||
let dev_config = device.config_descriptor(0).map_err(|err| {
|
||||
error!("Could not get keyboard device config: {:?}", err);
|
||||
err
|
||||
})?;
|
||||
info!("ACTIVE CONFIG: {:?}", dev_config.number());
|
||||
|
||||
// Interface with outputs
|
||||
let mut interface = 2; // The interface with keyboard consumer device and LED control
|
||||
// is #2 on 0x1866 device at least
|
||||
for iface in dev_config.interfaces() {
|
||||
for desc in iface.descriptors() {
|
||||
for endpoint in desc.endpoint_descriptors() {
|
||||
if endpoint.address() == match_endpoint {
|
||||
info!("INTERVAL: {:?}", endpoint.interval());
|
||||
info!("MAX_PKT_SIZE: {:?}", endpoint.max_packet_size());
|
||||
info!("SYNC: {:?}", endpoint.sync_type());
|
||||
info!("TRANSFER_TYPE: {:?}", endpoint.transfer_type());
|
||||
info!("ENDPOINT: {:X?}", endpoint.address());
|
||||
info!("INTERFACE: {:X?}", desc.interface_number());
|
||||
interface = desc.interface_number();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut device = device.open().map_err(|err| {
|
||||
error!("Could not open device: {:?}", err);
|
||||
err
|
||||
})?;
|
||||
|
||||
if let Err(err) = device.set_auto_detach_kernel_driver(true) {
|
||||
warn!("Auto-detach kernel driver failed: {:?}", err);
|
||||
warn!("Trying device reset");
|
||||
device.reset()?;
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
device.set_auto_detach_kernel_driver(true)?;
|
||||
}
|
||||
|
||||
// std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
Ok(RogCore {
|
||||
handle: device,
|
||||
_pin: PhantomPinned,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_device(vendor: u16, product: u16) -> Result<Device<rusb::GlobalContext>, rusb::Error> {
|
||||
for device in rusb::devices()?.iter() {
|
||||
let device_desc = device.device_descriptor()?;
|
||||
if device_desc.vendor_id() == vendor && device_desc.product_id() == product {
|
||||
return Ok(device);
|
||||
}
|
||||
}
|
||||
Err(rusb::Error::NoDevice)
|
||||
pub fn new(vendor: u16, product: u16) -> Self {
|
||||
RogCore {}
|
||||
}
|
||||
|
||||
fn get_fan_path() -> Result<&'static str, std::io::Error> {
|
||||
@@ -318,7 +254,6 @@ impl RogCore {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FanLevel {
|
||||
Normal,
|
||||
|
||||
Reference in New Issue
Block a user