From cf13b4f71bcc0abe13db80667869e342f9cb9e61 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 27 Jan 2021 14:05:06 +1300 Subject: [PATCH] Bugfixes and improvements - fix CLI feedback for reboot/restartx. Update readme - dracut force driver include for nvidia dedicated - change fan-mode CLI tag Closes #48 --- CHANGELOG.md | 11 ++- Cargo.lock | 4 +- README.md | 13 +++- asus-nb-ctrl/Cargo.toml | 2 +- asus-nb-ctrl/src/ctrl_fan_cpu.rs | 2 +- asus-nb-ctrl/src/ctrl_gfx/error.rs | 8 ++ asus-nb-ctrl/src/ctrl_gfx/gfx.rs | 121 ++++++++++++++++++----------- asus-nb-ctrl/src/ctrl_gfx/mod.rs | 2 +- asus-nb-ctrl/src/ctrl_leds.rs | 17 +++- asus-nb-ctrl/src/daemon.rs | 2 +- asus-nb-ctrl/src/error.rs | 4 + asus-nb-ctrl/src/main.rs | 16 ++-- asus-nb/Cargo.toml | 2 +- data/asusd-ledmodes.toml | 5 ++ 14 files changed, 146 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0f35421..94d96e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +# [2.2.1] - 2021-01-27 +### Added +- Add ROG Zephyrus M15 LED config +### Changed +- Bugfixes +- Fix reboot/restartx status for GFX switching +- Update readme +- Change CLI arg tag for fan modes +- Make dracut include the nvidia modules in initramfs + # [2.2.0] - 2021-01-26 ### Added - Dbus command to fetch all supported functions of the laptop. That is, all the @@ -13,7 +23,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bios setting toggles for: + Dedicated gfx toggle (support depends on the laptop) + Bios boot POST sound toggle - ### Changed - added config option for dedicated gfx mode on laptops with it to enable switching directly to dedicated using `asusctl graphics -m nvidia` diff --git a/Cargo.lock b/Cargo.lock index 672d9554..8f88cfee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "asus-nb" -version = "2.2.0" +version = "2.2.1" dependencies = [ "dbus", "gumdrop", @@ -45,7 +45,7 @@ dependencies = [ [[package]] name = "asus-nb-ctrl" -version = "2.2.0" +version = "2.2.1" dependencies = [ "asus-nb", "env_logger", diff --git a/README.md b/README.md index 96e24a8a..fdeb8a0d 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ but can also be used with non-asus laptops with reduced features. This app is developed and tested on fedora only. Support is not provided for Arch or Arch based distros. +**NOTICE:** +The following is *not* required for 5.11 kernel versions, as this version includes +all the required patches. +--- This program requires the kernel patch [here](https://www.spinics.net/lists/linux-input/msg68977.html) to be applied. Alternatively you may use the dkms module for 'hid-asus-rog` from one of the repositories [here](https://download.opensuse.org/repositories/home:/luke_nukem:/asus/). @@ -53,13 +57,17 @@ will probably suffer another rename once it becomes generic enough to do so. - [X] Set battery charge limit (with kernel supporting this) - [X] Fancy fan control on G14 + G15 thanks to @Yarn1 - [X] Graphics mode switching between iGPU, dGPU, and On-Demand +- [X] Toggle bios setting for boot/POST sound +- [X] Toggle bios setting for "dedicated gfx" mode on supported laptops (g-sync) # FUNCTIONS ## Graphics switching A new feature has been added to enable switching graphics modes. This can be disabled -in the config with `"manage_gfx": false,`. Please be aware it is a work in progress. +in the config with `"manage_gfx": false,`. Additionally there is an extra setting +for laptops capable of g-sync dedicated gfx mode to enable the graphics switching +to switch on dedicated gfx for "nvidia" mode. The CLI option for this does not require root until it asks for it, and provides instructions. @@ -79,7 +87,8 @@ If you have installed the Nvidia driver manually you will require the ### fedora and openSUSE You *may* need a file `/etc/dracut.conf.d/90-nvidia-dracut-G05.conf` installed -to stop dracut including the nvidia modules in the ramdisk. +to stop dracut including the nvidia modules in the ramdisk. This is espeically +true if you manually installed the nvidia drivers. ``` # filename /etc/dracut.conf.d/90-nvidia-dracut-G05.conf diff --git a/asus-nb-ctrl/Cargo.toml b/asus-nb-ctrl/Cargo.toml index c45c80e4..89358281 100644 --- a/asus-nb-ctrl/Cargo.toml +++ b/asus-nb-ctrl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "asus-nb-ctrl" -version = "2.2.0" +version = "2.2.1" license = "MPL-2.0" readme = "README.md" authors = ["Luke "] diff --git a/asus-nb-ctrl/src/ctrl_fan_cpu.rs b/asus-nb-ctrl/src/ctrl_fan_cpu.rs index d7ff6f3a..684696a9 100644 --- a/asus-nb-ctrl/src/ctrl_fan_cpu.rs +++ b/asus-nb-ctrl/src/ctrl_fan_cpu.rs @@ -132,7 +132,7 @@ impl crate::ZbusAdd for DbusFanAndCpu { server .at(&"/org/asuslinux/Profile".try_into().unwrap(), self) .map_err(|err| { - warn!("DbusFanAndCpu: {}", err); + warn!("DbusFanAndCpu: add_to_server {}", err); err }) .ok(); diff --git a/asus-nb-ctrl/src/ctrl_gfx/error.rs b/asus-nb-ctrl/src/ctrl_gfx/error.rs index 5deac872..d01036d0 100644 --- a/asus-nb-ctrl/src/ctrl_gfx/error.rs +++ b/asus-nb-ctrl/src/ctrl_gfx/error.rs @@ -1,6 +1,8 @@ use std::error; use std::fmt; +use crate::error::RogError; + #[derive(Debug)] pub enum GfxError { ParseVendor, @@ -28,3 +30,9 @@ impl fmt::Display for GfxError { } impl error::Error for GfxError {} + +impl From for RogError { + fn from(err: GfxError) -> Self { + RogError::GfxSwitching(err) + } +} diff --git a/asus-nb-ctrl/src/ctrl_gfx/gfx.rs b/asus-nb-ctrl/src/ctrl_gfx/gfx.rs index a9fad9b2..8bdc1818 100644 --- a/asus-nb-ctrl/src/ctrl_gfx/gfx.rs +++ b/asus-nb-ctrl/src/ctrl_gfx/gfx.rs @@ -7,7 +7,7 @@ use std::iter::FromIterator; use std::path::Path; use std::process::Command; use std::str::FromStr; -use std::{error::Error, sync::Arc, sync::Mutex}; +use std::{sync::Arc, sync::Mutex}; use sysfs_class::{PciDevice, SysClass}; use system::{GraphicsDevice, Module, PciBus}; use vendors::{GfxCtrlAction, GfxVendors}; @@ -66,6 +66,31 @@ impl Dbus for CtrlGraphics { fn notify_action(&self, action: &str) -> zbus::Result<()> {} } +impl ZbusAdd for CtrlGraphics { + fn add_to_server(self, server: &mut zbus::ObjectServer) { + server + .at( + &"/org/asuslinux/Gfx" + .try_into() + .expect("Couldn't add to zbus"), + self, + ) + .map_err(|err| { + warn!("CtrlGraphics: add_to_server {}", err); + err + }) + .ok(); + } +} + +impl Reloadable for CtrlGraphics { + fn reload(&mut self) -> Result<(), RogError> { + self.auto_power()?; + info!("Reloaded gfx mode: {:?}", CtrlGraphics::get_vendor()?); + Ok(()) + } +} + impl CtrlGraphics { pub fn new(config: Arc>) -> std::io::Result { let bus = PciBus::new()?; @@ -125,13 +150,12 @@ impl CtrlGraphics { cmd.arg("-u"); initfs_cmd = Some(cmd); info!("Using initramfs update command 'update-initramfs'"); + } else if Path::new(DRACUT_PATH).exists() { + let mut cmd = Command::new("dracut"); + cmd.arg("-f"); + initfs_cmd = Some(cmd); + info!("Using initramfs update command 'dracut'"); } - // } else if Path::new(DRACUT_PATH).exists() { - // let mut cmd = Command::new("dracut"); - // cmd.arg("-f"); - // initfs_cmd = Some(cmd); - // info!("Using initramfs update command 'dracut'"); - // } Ok(CtrlGraphics { bus, @@ -144,26 +168,7 @@ impl CtrlGraphics { }) } - pub fn add_to_server(self, server: &mut zbus::ObjectServer) { - server - .at( - &"/org/asuslinux/Gfx".try_into().expect("Some fail here"), - self, - ) - .map_err(|err| { - warn!("CtrlGraphics: add_to_server {}", err); - err - }) - .ok(); - } - - pub fn reload(&mut self) -> Result<(), Box> { - self.auto_power()?; - info!("Reloaded gfx mode: {:?}", CtrlGraphics::get_vendor()?); - Ok(()) - } - - fn get_prime_discrete() -> Result { + fn get_prime_discrete() -> Result { let s = std::fs::read_to_string(PRIME_DISCRETE_PATH) .map_err(|err| GfxError::Read(PRIME_DISCRETE_PATH.into(), err))? .trim() @@ -171,14 +176,14 @@ impl CtrlGraphics { Ok(s) } - fn set_prime_discrete(mode: &str) -> Result<(), GfxError> { + fn set_prime_discrete(mode: &str) -> Result<(), RogError> { std::fs::write(PRIME_DISCRETE_PATH, mode) .map_err(|err| GfxError::Read(PRIME_DISCRETE_PATH.into(), err))?; Ok(()) } /// Associated method to get which vendor mode is set - pub fn get_vendor() -> Result { + pub fn get_vendor() -> Result { let mode = match Self::get_prime_discrete() { Ok(m) => m, Err(_) => "nvidia".to_string(), @@ -214,14 +219,32 @@ impl CtrlGraphics { Ok(vendor) } - pub fn is_switching_prime_modes(vendor: &GfxVendors) -> Result { + fn is_switching_prime_modes(&self, vendor: &GfxVendors) -> Result { let prev_mode = GfxVendors::from_str(&Self::get_vendor()?)?; - let x = (prev_mode == GfxVendors::Hybrid || prev_mode == GfxVendors::Nvidia) - && (*vendor == GfxVendors::Hybrid || *vendor == GfxVendors::Nvidia); - Ok(x) + if prev_mode == GfxVendors::Integrated + && (*vendor == GfxVendors::Hybrid || *vendor == GfxVendors::Nvidia) + { + return Ok(true); + } + if (prev_mode == GfxVendors::Hybrid || prev_mode == GfxVendors::Nvidia) + && *vendor == GfxVendors::Integrated + { + return Ok(true); + } + if let Ok(config) = self.config.clone().try_lock() { + if CtrlRogBios::has_dedicated_gfx_toggle() && config.gfx_nv_mode_is_dedicated { + if prev_mode == GfxVendors::Hybrid && *vendor == GfxVendors::Nvidia { + return Ok(true); + } + if *vendor == GfxVendors::Hybrid && prev_mode == GfxVendors::Nvidia { + return Ok(true); + } + } + } + Ok(false) } - pub fn set_gfx_config(vendor: GfxVendors) -> Result<(), GfxError> { + pub fn set_gfx_config(vendor: GfxVendors) -> Result<(), RogError> { let mode = if vendor == GfxVendors::Hybrid { "on-demand\n" } else if vendor == GfxVendors::Nvidia { @@ -305,7 +328,11 @@ impl CtrlGraphics { } /// Write out config files if required, enable/disable relevant services, and update the ramdisk - pub fn set(&mut self, vendor: GfxVendors) -> Result { + fn set(&mut self, vendor: GfxVendors) -> Result { + // Switching from hybrid to/from nvidia shouldn't require a ramdisk update + // or a reboot. + let reboot = self.is_switching_prime_modes(&vendor)?; + if CtrlRogBios::has_dedicated_gfx_toggle() { if let Ok(config) = self.config.clone().try_lock() { // Switch to dedicated if config says to do so @@ -322,40 +349,44 @@ impl CtrlGraphics { } } - // Switching from hybrid to/from nvidia shouldn't require a ramdisk update - // or a reboot. - let no_reboot = Self::is_switching_prime_modes(&vendor)?; - - Self::set_gfx_config(vendor)?; + Self::set_gfx_config(vendor.clone())?; let mut required_action = GfxCtrlAction::None; - if !no_reboot { + if reboot { info!("Updating initramfs"); if let Some(cmd) = self.initfs_cmd.as_mut() { + // If switching to Nvidia dedicated we need these modules included + if Path::new(DRACUT_PATH).exists() && vendor == GfxVendors::Nvidia { + cmd.arg("--add-drivers"); + cmd.arg("nvidia nvidia-drm nvidia-modeset nvidia-uvm"); + info!("System uses dracut, forcing nvidia modules to be included in init"); + } + let status = cmd .status() .map_err(|err| GfxError::Write(format!("{:?}", cmd), err))?; if !status.success() { error!("Ram disk update failed"); + return Ok("Ram disk update failed".into()); } else { info!("Successfully updated iniramfs"); } } required_action = GfxCtrlAction::Reboot; - } else if no_reboot { + } else if !reboot { required_action = GfxCtrlAction::RestartX; } Ok(required_action.into()) } - pub fn get_runtime_status() -> Result { + fn get_runtime_status() -> Result { const PATH: &str = "/sys/bus/pci/devices/0000:01:00.0/power/runtime_status"; let buf = std::fs::read_to_string(PATH).map_err(|err| GfxError::Read(PATH.into(), err))?; Ok(buf) } - fn set_power(&self, power: bool) -> Result<(), GfxError> { + fn set_power(&self, power: bool) -> Result<(), RogError> { if power { info!("Enabling graphics power"); self.bus @@ -377,7 +408,7 @@ impl CtrlGraphics { Ok(()) } - fn auto_power(&self) -> Result<(), GfxError> { + fn auto_power(&self) -> Result<(), RogError> { let vendor = CtrlGraphics::get_vendor()?; self.set_power(vendor != "integrated") } diff --git a/asus-nb-ctrl/src/ctrl_gfx/mod.rs b/asus-nb-ctrl/src/ctrl_gfx/mod.rs index 9d065cf2..b68e2c41 100644 --- a/asus-nb-ctrl/src/ctrl_gfx/mod.rs +++ b/asus-nb-ctrl/src/ctrl_gfx/mod.rs @@ -9,7 +9,7 @@ pub mod system; const PRIME_DISCRETE_PATH: &str = "/etc/prime-discrete"; const MODPROBE_PATH: &str = "/etc/modprobe.d/asusd.conf"; const INITRAMFS_PATH: &str = "/usr/sbin/update-initramfs"; -// const DRACUT_PATH: &str = "/usr/bin/dracut"; +const DRACUT_PATH: &str = "/usr/bin/dracut"; static MODPROBE_NVIDIA: &[u8] = MODPROBE_HYBRID; diff --git a/asus-nb-ctrl/src/ctrl_leds.rs b/asus-nb-ctrl/src/ctrl_leds.rs index 07e0139e..cde1902c 100644 --- a/asus-nb-ctrl/src/ctrl_leds.rs +++ b/asus-nb-ctrl/src/ctrl_leds.rs @@ -15,7 +15,7 @@ use asus_nb::{ fancy::KeyColourArray, LED_MSG_LEN, }; -use log::{info, warn}; +use log::{error, info, warn}; use std::fs::OpenOptions; use std::io::{Read, Write}; use std::sync::Arc; @@ -91,6 +91,9 @@ impl crate::ZbusAdd for DbusKbdBacklight { fn add_to_server(self, server: &mut zbus::ObjectServer) { server .at(&"/org/asuslinux/Led".try_into().unwrap(), self) + .map_err(|err| { + error!("DbusKbdBacklight: add_to_server {}", err); + }) .ok(); } } @@ -281,8 +284,16 @@ impl CtrlKbdBacklight { let ctrl = CtrlKbdBacklight { // Using `ok` here so we can continue without keyboard features but // still get brightness control at least... maybe... - led_node: Self::get_node_failover(id_product, None, Self::scan_led_node).ok(), - kbd_node: Self::get_node_failover(id_product, condev_iface, Self::scan_kbd_node).ok(), + led_node: Some(Self::get_node_failover( + id_product, + None, + Self::scan_led_node, + )?), + kbd_node: Some(Self::get_node_failover( + id_product, + condev_iface, + Self::scan_kbd_node, + )?), // TODO: Check for existance bright_node: Self::get_kbd_bright_path()?.to_owned(), supported_modes, diff --git a/asus-nb-ctrl/src/daemon.rs b/asus-nb-ctrl/src/daemon.rs index bbb5eace..e609d475 100644 --- a/asus-nb-ctrl/src/daemon.rs +++ b/asus-nb-ctrl/src/daemon.rs @@ -112,7 +112,7 @@ fn start_daemon() -> Result<(), Box> { if ded == 1 && vendor != "nvidia" { error!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode"); error!("You must reboot to enable Nvidia driver"); - ctrl.set(GfxVendors::Nvidia)?; + CtrlGraphics::set_gfx_config(GfxVendors::Nvidia)?; } else if ded == 0 { info!("Dedicated GFX toggle is off"); } diff --git a/asus-nb-ctrl/src/error.rs b/asus-nb-ctrl/src/error.rs index b56c527c..6aca7113 100644 --- a/asus-nb-ctrl/src/error.rs +++ b/asus-nb-ctrl/src/error.rs @@ -3,6 +3,8 @@ use rog_fan_curve::CurveError; use std::convert::From; use std::fmt; +use crate::ctrl_gfx::error::GfxError; + #[derive(Debug)] pub enum RogError { ParseFanLevel, @@ -21,6 +23,7 @@ pub enum RogError { MissingFunction(String), MissingLedBrightNode(String, std::io::Error), ReloadFail(String), + GfxSwitching(GfxError), } impl fmt::Display for RogError { @@ -43,6 +46,7 @@ impl fmt::Display for RogError { RogError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets), RogError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error), RogError::ReloadFail(deets) => write!(f, "Task error: {}", deets), + RogError::GfxSwitching(deets) => write!(f, "Graphics switching error: {}", deets), } } } diff --git a/asus-nb-ctrl/src/main.rs b/asus-nb-ctrl/src/main.rs index dfc3dbb0..456f52d5 100644 --- a/asus-nb-ctrl/src/main.rs +++ b/asus-nb-ctrl/src/main.rs @@ -21,8 +21,11 @@ struct CLIStart { show_supported: bool, #[options(meta = "", help = "")] kbd_bright: Option, - #[options(meta = "", help = "")] - pwr_profile: Option, + #[options( + meta = "", + help = ", set fan mode independent of profile" + )] + fan_mode: Option, #[options(meta = "", help = "<20-100>")] chg_limit: Option, #[options(command)] @@ -246,7 +249,7 @@ fn main() -> Result<(), Box> { None => { if (!parsed.show_supported && parsed.kbd_bright.is_none() - && parsed.pwr_profile.is_none() + && parsed.fan_mode.is_none() && parsed.chg_limit.is_none()) || parsed.help { @@ -272,7 +275,7 @@ fn main() -> Result<(), Box> { println!("Supported laptop functions:\n{}", dat.to_string()); } - if let Some(fan_level) = parsed.pwr_profile { + if let Some(fan_level) = parsed.fan_mode { dbus_client.write_fan_mode(fan_level.into())?; } if let Some(chg_limit) = parsed.chg_limit { @@ -319,7 +322,10 @@ fn do_gfx( )?; std::process::exit(1) } - _ => std::process::exit(-1), + _ => { + println!("{}", Red.paint(&format!("\n{}\n", res.as_str())),); + std::process::exit(-1); + } } std::process::exit(-1) } diff --git a/asus-nb/Cargo.toml b/asus-nb/Cargo.toml index 3a25dbb4..eb4462e3 100644 --- a/asus-nb/Cargo.toml +++ b/asus-nb/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "asus-nb" -version = "2.2.0" +version = "2.2.1" license = "MPL-2.0" readme = "README.md" authors = ["Luke "] diff --git a/data/asusd-ledmodes.toml b/data/asusd-ledmodes.toml index ddb3f9d8..d39a276a 100644 --- a/data/asusd-ledmodes.toml +++ b/data/asusd-ledmodes.toml @@ -8,6 +8,11 @@ prod_family = "Zephyrus M" board_names = ["GU502GV"] led_modes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 255] +[[led_modes]] +prod_family = "ROG Zephyrus M15" +board_names = ["GU502LW"] +led_modes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 255] + [[led_modes]] prod_family = "Zephyrus" board_names = ["GM501GM", "GX531"]