mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
11 Commits
6.3.0
...
5d52626e32
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d52626e32 | ||
|
|
f471f340d4 | ||
|
|
8095ac34ed | ||
|
|
9d629b62ca | ||
|
|
5282c56f59 | ||
|
|
0d2cd4eb10 | ||
|
|
b20ecf5378 | ||
|
|
ade839e981 | ||
|
|
d625c279a6 | ||
|
|
5ea14be3fa | ||
|
|
64c2e55db4 |
@@ -90,7 +90,7 @@ pages:
|
||||
- rm -rf public
|
||||
- mkdir public
|
||||
- cp -R ci-target/doc/* public
|
||||
- cp extra/index.html public
|
||||
- if [ -f extra/index.html ]; then cp extra/index.html public; else echo "no extra/index.html to copy"; fi
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## [6.3.1]
|
||||
|
||||
### Changes
|
||||
- Removed a lighting mode that is unavailable in windows to G835L: thanks to @shevchenko0013 again!
|
||||
|
||||
|
||||
## [6.3.0]
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -13,9 +13,7 @@ Now includes a GUI, `rog-control-center`.
|
||||
|
||||
Due to on-going driver work the minimum suggested kernel version is always **the latest*, as improvements and fixes are continuous.
|
||||
|
||||
Support for some new features is not avilable unless you run a patched kernel with the work I am doing [in this github repo](https://github.com/flukejones/linux/tree/wip/ally-6.13). Use the linked branch, or `wip/ally-6.12`. Everything that is done here is upstreamed eventually (a long process).
|
||||
|
||||
Z13 devices will need [these](https://lore.kernel.org/linux-input/20240416090402.31057-1-luke@ljones.dev/T/#t)
|
||||
Support for TDP is tied to the new asus-armoury driver: available mainline since linux 6.19: everything older is not supported.
|
||||
|
||||
## X11 support
|
||||
|
||||
@@ -180,3 +178,7 @@ Reference to any ASUS products, services, processes, or other information and/or
|
||||
The use of ROG and ASUS trademarks within this website and associated tools and libraries is only to provide a recognisable identifier to users to enable them to associate that these tools will work with ASUS ROG laptops.
|
||||
|
||||
---
|
||||
|
||||
## AI Disaclaimer
|
||||
|
||||
Portions of this code have been written by various AI tools and reviewed by the maintainer exaclty as with every other contribution.
|
||||
|
||||
@@ -25,6 +25,30 @@ pub struct Aura {
|
||||
impl Aura {
|
||||
/// Initialise the device if required.
|
||||
pub async fn do_initialization(&self) -> Result<(), RogError> {
|
||||
if let Some(hid) = &self.hid {
|
||||
let hid = hid.lock().await;
|
||||
let init_1: [u8; 2] = [
|
||||
0x5d, 0xb9,
|
||||
];
|
||||
let init_2 = b"]ASUS Tech.Inc.";
|
||||
let init_3: [u8; 6] = [
|
||||
0x5d, 0x05, 0x20, 0x31, 0, 0x1a,
|
||||
];
|
||||
|
||||
hid.write_bytes(&init_1)?;
|
||||
hid.write_bytes(init_2)?;
|
||||
hid.write_bytes(&init_3)?;
|
||||
|
||||
let config = self.config.lock().await;
|
||||
if config.support_data.device_name.contains("GZ30")
|
||||
|| config.support_data.device_name.contains("Z13")
|
||||
{
|
||||
let z13_init: [u8; 4] = [
|
||||
0x5d, 0xc0, 0x03, 0x01,
|
||||
];
|
||||
hid.write_bytes(&z13_init)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -152,9 +176,54 @@ impl Aura {
|
||||
}
|
||||
}
|
||||
|
||||
let bytes = config.enabled.to_bytes(config.led_type);
|
||||
let mut enabled = config.enabled.clone();
|
||||
if config.support_data.device_name.contains("GZ30")
|
||||
|| config.support_data.device_name.contains("Z13")
|
||||
{
|
||||
let logo_state = enabled
|
||||
.states
|
||||
.iter()
|
||||
.find(|s| s.zone == PowerZones::Logo)
|
||||
.cloned();
|
||||
if let Some(logo) = logo_state {
|
||||
let mut lid_found = false;
|
||||
let mut bar_found = false;
|
||||
|
||||
for s in enabled.states.iter_mut() {
|
||||
if s.zone == PowerZones::Lid {
|
||||
s.boot = logo.boot;
|
||||
s.awake = logo.awake;
|
||||
s.sleep = logo.sleep;
|
||||
s.shutdown = logo.shutdown;
|
||||
lid_found = true;
|
||||
}
|
||||
if s.zone == PowerZones::Lightbar {
|
||||
s.boot = logo.boot;
|
||||
s.awake = logo.awake;
|
||||
s.sleep = logo.sleep;
|
||||
s.shutdown = logo.shutdown;
|
||||
bar_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !lid_found {
|
||||
let mut new_state = logo;
|
||||
new_state.zone = PowerZones::Lid;
|
||||
enabled.states.push(new_state.clone());
|
||||
new_state.zone = PowerZones::Lightbar;
|
||||
enabled.states.push(new_state);
|
||||
} else if !bar_found {
|
||||
// Lid found but not bar?
|
||||
let mut new_state = logo;
|
||||
new_state.zone = PowerZones::Lightbar;
|
||||
enabled.states.push(new_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let bytes = enabled.to_bytes(config.led_type);
|
||||
let msg = [
|
||||
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3],
|
||||
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], bytes[3], 0xff,
|
||||
];
|
||||
hid_raw.write_bytes(&msg)?;
|
||||
}
|
||||
|
||||
23
extra/index.html
Normal file
23
extra/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>asusctl docs</title>
|
||||
<!-- Redirect to the generated crate docs -->
|
||||
<meta http-equiv="refresh" content="0;url=asusctl/index.html">
|
||||
<link rel="canonical" href="asusctl/index.html">
|
||||
<style>
|
||||
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; color:#222; display:flex; align-items:center; justify-content:center; height:100vh; margin:0 }
|
||||
.box { text-align:center }
|
||||
a { color: #0366d6 }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<h1>asusctl documentation</h1>
|
||||
<p>Redirecting to the generated docs — if your browser doesn't redirect automatically, <a href="asusctl/index.html">click here</a>.</p>
|
||||
<p>If you expected a different landing page, update <code>extra/index.html</code> accordingly.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -570,7 +570,7 @@
|
||||
device_name: "G835L",
|
||||
product_id: "",
|
||||
layout_name: "g814ji-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo],
|
||||
@@ -971,6 +971,24 @@
|
||||
advanced_type: r#None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "GZ302",
|
||||
product_id: "18c6",
|
||||
layout_name: "",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
power_zones: [Logo],
|
||||
),
|
||||
(
|
||||
device_name: "GZ302",
|
||||
product_id: "1a30",
|
||||
layout_name: "ga401q",
|
||||
basic_modes: [Static, Breathe, Pulse],
|
||||
basic_zones: [],
|
||||
advanced_type: r#None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
device_name: "RC71L",
|
||||
product_id: "",
|
||||
|
||||
@@ -123,7 +123,8 @@ impl AuraPowerState {
|
||||
| ((self.shutdown as u32) << 7)
|
||||
}
|
||||
PowerZones::Lightbar => {
|
||||
((self.boot as u32) << (7 + 2))
|
||||
((self.awake as u32) << (7 + 1))
|
||||
| ((self.boot as u32) << (7 + 2))
|
||||
| ((self.awake as u32) << (7 + 3))
|
||||
| ((self.sleep as u32) << (7 + 4))
|
||||
| ((self.shutdown as u32) << (7 + 5))
|
||||
@@ -133,12 +134,20 @@ impl AuraPowerState {
|
||||
| ((self.awake as u32) << (15 + 2))
|
||||
| ((self.sleep as u32) << (15 + 3))
|
||||
| ((self.shutdown as u32) << (15 + 4))
|
||||
| ((self.boot as u32) << (15 + 5))
|
||||
| ((self.awake as u32) << (15 + 6))
|
||||
| ((self.sleep as u32) << (15 + 7))
|
||||
| ((self.shutdown as u32) << (15 + 8))
|
||||
}
|
||||
PowerZones::RearGlow => {
|
||||
((self.boot as u32) << (23 + 1))
|
||||
| ((self.awake as u32) << (23 + 2))
|
||||
| ((self.sleep as u32) << (23 + 3))
|
||||
| ((self.shutdown as u32) << (23 + 4))
|
||||
| ((self.boot as u32) << (23 + 5))
|
||||
| ((self.awake as u32) << (23 + 6))
|
||||
| ((self.sleep as u32) << (23 + 7))
|
||||
| ((self.shutdown as u32) << (23 + 8))
|
||||
}
|
||||
PowerZones::None | PowerZones::KeyboardAndLightbar => 0,
|
||||
}
|
||||
@@ -618,19 +627,19 @@ mod test {
|
||||
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
|
||||
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
|
||||
assert_eq!(awake_bar_, "00000000, 00000101, 00000000, 00000000");
|
||||
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
||||
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
||||
assert_eq!(awake_lid_, "00000000, 00000000, 00000010, 00000000");
|
||||
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
||||
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
||||
assert_eq!(boot_lid__, "00000000, 00000000, 00010001, 00000000");
|
||||
assert_eq!(awake_lid_, "00000000, 00000000, 00100010, 00000000");
|
||||
assert_eq!(sleep_lid_, "00000000, 00000000, 01000100, 00000000");
|
||||
assert_eq!(shut_lid__, "00000000, 00000000, 10001000, 00000000");
|
||||
//
|
||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00010001");
|
||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00100010");
|
||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 01000100");
|
||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 10001000");
|
||||
|
||||
// All on
|
||||
let byte1 = to_binary_string_post2021(&LaptopAuraPower {
|
||||
@@ -657,6 +666,6 @@ mod test {
|
||||
},
|
||||
],
|
||||
});
|
||||
assert_eq!(byte1, "11111111, 00011110, 00001111, 00001111");
|
||||
assert_eq!(byte1, "11111111, 00011111, 11111111, 11111111");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +106,10 @@ impl From<&str> for AuraDeviceType {
|
||||
match s.to_lowercase().trim_start_matches("0x") {
|
||||
"tuf" => AuraDeviceType::LaptopKeyboardTuf,
|
||||
"1932" => AuraDeviceType::ScsiExtDisk,
|
||||
"1866" | "18c6" | "1869" | "1854" => Self::LaptopKeyboardPre2021,
|
||||
"1866" | "1869" | "1854" => Self::LaptopKeyboardPre2021,
|
||||
"1abe" | "1b4c" => Self::Ally,
|
||||
"19b3" | "193b" => Self::AnimeOrSlash,
|
||||
"19b6" => Self::LaptopKeyboard2021,
|
||||
"19b6" | "1a30" | "18c6" => Self::LaptopKeyboard2021,
|
||||
_ => Self::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,6 @@ impl CurveData {
|
||||
/// Write this curve to the device fan specified by `self.fan`
|
||||
pub fn write_to_device(&self, device: &mut Device) -> std::io::Result<()> {
|
||||
let pwm_num: char = self.fan.into();
|
||||
let enable = if self.enabled { '1' } else { '2' };
|
||||
|
||||
for (index, out) in self.pwm.iter().enumerate() {
|
||||
let pwm = pwm_str(pwm_num, index);
|
||||
@@ -176,10 +175,20 @@ impl CurveData {
|
||||
device.set_attribute_value(&temp, out.to_string())?;
|
||||
}
|
||||
|
||||
// Enable must be done *after* all points are written pwm3_enable
|
||||
// Note: pwm_enable is set by write_profile_curve_to_platform after all
|
||||
// curves are written, because on some devices (e.g., ASUS Z13 2025)
|
||||
// setting any pwm_enable to 2 resets ALL fan enables.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the enable state for this fan curve
|
||||
pub fn set_enable(&self, device: &mut Device) -> std::io::Result<()> {
|
||||
let pwm_num: char = self.fan.into();
|
||||
let enable = if self.enabled { "1" } else { "2" };
|
||||
let enable_attr = format!("pwm{pwm_num}_enable");
|
||||
device
|
||||
.set_attribute_value(format!("pwm{pwm_num}_enable"), enable.to_string())
|
||||
.map_err(|e| error!("Failed to set pwm{pwm_num}_enable to {enable}: {e:?}"))
|
||||
.set_attribute_value(&enable_attr, enable.to_string())
|
||||
.map_err(|e| error!("Failed to set {enable_attr} to {enable}: {e:?}"))
|
||||
.ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -181,15 +181,29 @@ impl FanCurveProfiles {
|
||||
PlatformProfile::Quiet | PlatformProfile::LowPower => &mut self.quiet,
|
||||
PlatformProfile::Custom => &mut self.custom,
|
||||
};
|
||||
for fan in fans.iter().filter(|f| !f.enabled) {
|
||||
debug!("write_profile_curve_to_platform: writing profile:{profile}, {fan:?}");
|
||||
|
||||
// First write all curve data (pwm/temp values) for all fans
|
||||
for fan in fans.iter() {
|
||||
debug!("write_profile_curve_to_platform: writing curve data for profile:{profile}, {fan:?}");
|
||||
fan.write_to_device(device)?;
|
||||
}
|
||||
// Write enabled fans last because the kernel currently resets *all* if one is
|
||||
// disabled
|
||||
|
||||
// Then set enables: disabled fans first, then enabled fans last.
|
||||
// This order is important because on some devices (e.g., ASUS Z13 2025)
|
||||
// setting any pwm_enable to 2 (disabled) resets ALL fan enables.
|
||||
for fan in fans.iter().filter(|f| !f.enabled) {
|
||||
debug!(
|
||||
"write_profile_curve_to_platform: disabling fan for profile:{profile}, {:?}",
|
||||
fan.fan
|
||||
);
|
||||
fan.set_enable(device)?;
|
||||
}
|
||||
for fan in fans.iter().filter(|f| f.enabled) {
|
||||
debug!("write_profile_curve_to_platform: writing profile:{profile}, {fan:?}");
|
||||
fan.write_to_device(device)?;
|
||||
debug!(
|
||||
"write_profile_curve_to_platform: enabling fan for profile:{profile}, {:?}",
|
||||
fan.fan
|
||||
);
|
||||
fan.set_enable(device)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user