mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
12 Commits
6.3.1
...
c5642c09f4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5642c09f4 | ||
|
|
6e83884c0a | ||
|
|
7edb77b41f | ||
|
|
737ffa522c | ||
|
|
0311cfb1f9 | ||
|
|
b0ee27fb74 | ||
|
|
d4eca0c93e | ||
|
|
f471f340d4 | ||
|
|
8095ac34ed | ||
|
|
9d629b62ca | ||
|
|
5282c56f59 | ||
|
|
0d2cd4eb10 |
@@ -1,5 +1,11 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [6.3.2]
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Improve the notification area, @shevchenko0013 strikes again!
|
||||||
|
- Improve firmware attributes handling
|
||||||
|
|
||||||
## [6.3.1]
|
## [6.3.1]
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
|
use rog_platform::asus_armoury::{
|
||||||
|
AttrValue, Attribute, FirmwareAttribute, FirmwareAttributeType, FirmwareAttributes,
|
||||||
|
};
|
||||||
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -168,82 +170,64 @@ impl ArmouryAttributeRegistry {
|
|||||||
impl crate::Reloadable for AsusArmouryAttribute {
|
impl crate::Reloadable for AsusArmouryAttribute {
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
info!("Reloading {}", self.attr.name());
|
info!("Reloading {}", self.attr.name());
|
||||||
let name: FirmwareAttribute = self.attr.name().into();
|
let attribute: FirmwareAttribute = self.attr.name().into();
|
||||||
|
let name = self.attr.name();
|
||||||
|
|
||||||
// Treat dGPU attributes the same as PPT attributes for power-profile
|
let config = self.config.lock().await;
|
||||||
// behaviour so they follow AC/DC tuning groups.
|
let apply_value = match attribute.property_type() {
|
||||||
if name.is_ppt() || name.is_dgpu() {
|
FirmwareAttributeType::Ppt => {
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
let power_plugged = self
|
let power_plugged = self
|
||||||
.power
|
.power
|
||||||
.get_online()
|
.get_online()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Could not get power status: {e:?}");
|
error!("Could not get power status: {e:?}");
|
||||||
e
|
e
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
|
||||||
== 1;
|
|
||||||
|
|
||||||
let apply_value = {
|
|
||||||
let config = self.config.lock().await;
|
|
||||||
config
|
|
||||||
.select_tunings_ref(power_plugged, profile)
|
|
||||||
.and_then(|tuning| {
|
|
||||||
if tuning.enabled {
|
|
||||||
tuning.group.get(&self.name()).copied()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
};
|
.unwrap_or_default()
|
||||||
|
== 1;
|
||||||
|
|
||||||
if let Some(tune) = apply_value {
|
let apply_value = {
|
||||||
self.attr
|
config.select_tunings_ref(power_plugged, profile).and_then(
|
||||||
.set_current_value(&AttrValue::Integer(tune))
|
|tuning| match tuning.enabled {
|
||||||
.map_err(|e| {
|
true => tuning.group.get(&self.name()).copied(),
|
||||||
error!("Could not set {} value: {e:?}", self.attr.name());
|
false => None,
|
||||||
self.attr.base_path_exists();
|
},
|
||||||
e
|
)
|
||||||
})?;
|
};
|
||||||
info!(
|
|
||||||
"Restored PPT armoury setting {} to {:?}",
|
apply_value.map_or(AttrValue::None, AttrValue::Integer)
|
||||||
self.attr.name(),
|
|
||||||
tune
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
info!("Ignored restoring PPT armoury setting {} as tuning group is disabled or no saved value", self.attr.name());
|
|
||||||
}
|
}
|
||||||
} else {
|
FirmwareAttributeType::Gpu => {
|
||||||
// Handle non-PPT attributes (boolean and other settings)
|
info!("Reload called on GPU attribute {name}: doing nothing");
|
||||||
if let Some(saved_value) = self.config.lock().await.armoury_settings.get(&name) {
|
AttrValue::None
|
||||||
self.attr
|
|
||||||
.set_current_value(&AttrValue::Integer(*saved_value))
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
"Error restoring armoury setting {}: {e:?}",
|
|
||||||
self.attr.name()
|
|
||||||
);
|
|
||||||
self.attr.base_path_exists();
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
info!(
|
|
||||||
"Restored armoury setting {} to {:?}",
|
|
||||||
self.attr.name(),
|
|
||||||
saved_value
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
info!(
|
|
||||||
"No saved armoury setting for {}: skipping restore",
|
|
||||||
self.attr.name()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
_ => {
|
||||||
|
info!("Reload called on firmware attribute {name}");
|
||||||
|
match config.armoury_settings.get(&attribute) {
|
||||||
|
Some(saved_value) => AttrValue::Integer(*saved_value),
|
||||||
|
None => AttrValue::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.attr.set_current_value(&apply_value).map_err(|e| {
|
||||||
|
error!("Could not set {} value: {e:?}", self.attr.name());
|
||||||
|
self.attr.base_path_exists();
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Restored asus-armoury setting {} to {:?}",
|
||||||
|
self.attr.name(),
|
||||||
|
apply_value
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If return is `-1` on a property then there is avilable value for that
|
/// If return is `-1` on a property then there is available value for that
|
||||||
/// property
|
/// property
|
||||||
#[interface(name = "xyz.ljones.AsusArmoury")]
|
#[interface(name = "xyz.ljones.AsusArmoury")]
|
||||||
impl AsusArmouryAttribute {
|
impl AsusArmouryAttribute {
|
||||||
@@ -293,7 +277,7 @@ impl AsusArmouryAttribute {
|
|||||||
|
|
||||||
async fn restore_default(&self) -> fdo::Result<()> {
|
async fn restore_default(&self) -> fdo::Result<()> {
|
||||||
self.attr.restore_default()?;
|
self.attr.restore_default()?;
|
||||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
if self.name().property_type() == FirmwareAttributeType::Ppt {
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
let power_plugged = self
|
let power_plugged = self
|
||||||
.power
|
.power
|
||||||
@@ -352,7 +336,7 @@ impl AsusArmouryAttribute {
|
|||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn current_value(&self) -> fdo::Result<i32> {
|
async fn current_value(&self) -> fdo::Result<i32> {
|
||||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
if self.name().property_type() == FirmwareAttributeType::Ppt {
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
let power_plugged = self
|
let power_plugged = self
|
||||||
.power
|
.power
|
||||||
@@ -387,66 +371,62 @@ impl AsusArmouryAttribute {
|
|||||||
|
|
||||||
#[zbus(property)]
|
#[zbus(property)]
|
||||||
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
|
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
|
||||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
let name = self.attr.name();
|
||||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
let apply_value = match self.name().property_type() {
|
||||||
let power_plugged = self
|
FirmwareAttributeType::Ppt => {
|
||||||
.power
|
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||||
.get_online()
|
let power_plugged = self
|
||||||
.map_err(|e| {
|
.power
|
||||||
error!("Could not get power status: {e:?}");
|
.get_online()
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let mut config = self.config.lock().await;
|
|
||||||
let tuning = config.select_tunings(power_plugged == 1, profile);
|
|
||||||
|
|
||||||
if let Some(tune) = tuning.group.get_mut(&self.name()) {
|
|
||||||
*tune = value;
|
|
||||||
} else {
|
|
||||||
tuning.group.insert(self.name(), value);
|
|
||||||
debug!("Store tuning config for {} = {:?}", self.attr.name(), value);
|
|
||||||
}
|
|
||||||
if tuning.enabled {
|
|
||||||
self.attr
|
|
||||||
.set_current_value(&AttrValue::Integer(value))
|
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!(
|
error!("Could not get power status: {e:?}");
|
||||||
"Could not set value to PPT property {}: {e:?}",
|
|
||||||
self.attr.name()
|
|
||||||
);
|
|
||||||
e
|
e
|
||||||
})?;
|
})
|
||||||
} else {
|
.unwrap_or_default();
|
||||||
warn!(
|
|
||||||
"Tuning group is disabled: skipping setting value to PPT property {}",
|
|
||||||
self.attr.name()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.attr
|
|
||||||
.set_current_value(&AttrValue::Integer(value))
|
|
||||||
.map_err(|e| {
|
|
||||||
error!(
|
|
||||||
"Could not set value {value} to attribute {}: {e:?}",
|
|
||||||
self.attr.name()
|
|
||||||
);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let mut settings = self.config.lock().await;
|
let mut config = self.config.lock().await;
|
||||||
settings
|
let tuning = config.select_tunings(power_plugged == 1, profile);
|
||||||
.armoury_settings
|
|
||||||
.entry(self.name())
|
if let Some(tune) = tuning.group.get_mut(&self.name()) {
|
||||||
.and_modify(|setting| {
|
*tune = value;
|
||||||
debug!("Set config for {} = {value}", self.attr.name());
|
} else {
|
||||||
*setting = value;
|
tuning.group.insert(self.name(), value);
|
||||||
})
|
debug!("Store tuning config for {name} = {:?}", value);
|
||||||
.or_insert_with(|| {
|
}
|
||||||
debug!("Adding config for {} = {value}", self.attr.name());
|
|
||||||
value
|
match tuning.enabled {
|
||||||
});
|
true => {
|
||||||
}
|
debug!("Tuning is enabled: setting value to PPT property {name} = {value}");
|
||||||
|
AttrValue::Integer(value)
|
||||||
|
}
|
||||||
|
false => {
|
||||||
|
warn!("Tuning is disabled: skipping setting value to PPT property {name}");
|
||||||
|
AttrValue::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let mut settings = self.config.lock().await;
|
||||||
|
settings
|
||||||
|
.armoury_settings
|
||||||
|
.entry(self.name())
|
||||||
|
.and_modify(|setting| {
|
||||||
|
debug!("Set config for {name} = {value}");
|
||||||
|
*setting = value;
|
||||||
|
})
|
||||||
|
.or_insert_with(|| {
|
||||||
|
debug!("Adding config for {name} = {value}");
|
||||||
|
value
|
||||||
|
});
|
||||||
|
|
||||||
|
AttrValue::Integer(value)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.attr.set_current_value(&apply_value).map_err(|e| {
|
||||||
|
error!("Could not set value {value} to attribute {name}: {e:?}");
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
// write config after setting value
|
// write config after setting value
|
||||||
self.config.lock().await.write();
|
self.config.lock().await.write();
|
||||||
@@ -515,7 +495,7 @@ pub async fn set_config_or_default(
|
|||||||
) {
|
) {
|
||||||
for attr in attrs.attributes().iter() {
|
for attr in attrs.attributes().iter() {
|
||||||
let name: FirmwareAttribute = attr.name().into();
|
let name: FirmwareAttribute = attr.name().into();
|
||||||
if name.is_ppt() || name.is_dgpu() {
|
if name.property_type() == FirmwareAttributeType::Ppt {
|
||||||
let tuning = config.select_tunings(power_plugged, profile);
|
let tuning = config.select_tunings(power_plugged, profile);
|
||||||
if !tuning.enabled {
|
if !tuning.enabled {
|
||||||
debug!("Tuning group is not enabled, skipping");
|
debug!("Tuning group is not enabled, skipping");
|
||||||
|
|||||||
@@ -25,6 +25,30 @@ pub struct Aura {
|
|||||||
impl Aura {
|
impl Aura {
|
||||||
/// Initialise the device if required.
|
/// Initialise the device if required.
|
||||||
pub async fn do_initialization(&self) -> Result<(), RogError> {
|
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(())
|
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 = [
|
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)?;
|
hid_raw.write_bytes(&msg)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
|
use rog_platform::asus_armoury::{
|
||||||
|
AttrValue, FirmwareAttribute, FirmwareAttributeType, FirmwareAttributes,
|
||||||
|
};
|
||||||
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||||
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
|
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
@@ -617,7 +619,7 @@ impl CtrlPlatform {
|
|||||||
|
|
||||||
for attr in self.attributes.attributes() {
|
for attr in self.attributes.attributes() {
|
||||||
let name: FirmwareAttribute = attr.name().into();
|
let name: FirmwareAttribute = attr.name().into();
|
||||||
if name.is_ppt() {
|
if name.property_type() == FirmwareAttributeType::Ppt {
|
||||||
// reset stored value
|
// reset stored value
|
||||||
if let Some(tune) = self
|
if let Some(tune) = self
|
||||||
.config
|
.config
|
||||||
|
|||||||
@@ -980,6 +980,24 @@
|
|||||||
advanced_type: r#None,
|
advanced_type: r#None,
|
||||||
power_zones: [Keyboard],
|
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",
|
device_name: "RC71L",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ impl AuraPowerState {
|
|||||||
| ((self.shutdown as u32) << 7)
|
| ((self.shutdown as u32) << 7)
|
||||||
}
|
}
|
||||||
PowerZones::Lightbar => {
|
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.awake as u32) << (7 + 3))
|
||||||
| ((self.sleep as u32) << (7 + 4))
|
| ((self.sleep as u32) << (7 + 4))
|
||||||
| ((self.shutdown as u32) << (7 + 5))
|
| ((self.shutdown as u32) << (7 + 5))
|
||||||
@@ -133,12 +134,20 @@ impl AuraPowerState {
|
|||||||
| ((self.awake as u32) << (15 + 2))
|
| ((self.awake as u32) << (15 + 2))
|
||||||
| ((self.sleep as u32) << (15 + 3))
|
| ((self.sleep as u32) << (15 + 3))
|
||||||
| ((self.shutdown as u32) << (15 + 4))
|
| ((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 => {
|
PowerZones::RearGlow => {
|
||||||
((self.boot as u32) << (23 + 1))
|
((self.boot as u32) << (23 + 1))
|
||||||
| ((self.awake as u32) << (23 + 2))
|
| ((self.awake as u32) << (23 + 2))
|
||||||
| ((self.sleep as u32) << (23 + 3))
|
| ((self.sleep as u32) << (23 + 3))
|
||||||
| ((self.shutdown as u32) << (23 + 4))
|
| ((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,
|
PowerZones::None | PowerZones::KeyboardAndLightbar => 0,
|
||||||
}
|
}
|
||||||
@@ -618,19 +627,19 @@ mod test {
|
|||||||
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
|
||||||
//
|
//
|
||||||
assert_eq!(boot_bar__, "00000000, 00000010, 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!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
|
||||||
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
|
||||||
//
|
//
|
||||||
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
|
assert_eq!(boot_lid__, "00000000, 00000000, 00010001, 00000000");
|
||||||
assert_eq!(awake_lid_, "00000000, 00000000, 00000010, 00000000");
|
assert_eq!(awake_lid_, "00000000, 00000000, 00100010, 00000000");
|
||||||
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
|
assert_eq!(sleep_lid_, "00000000, 00000000, 01000100, 00000000");
|
||||||
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
|
assert_eq!(shut_lid__, "00000000, 00000000, 10001000, 00000000");
|
||||||
//
|
//
|
||||||
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
|
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00010001");
|
||||||
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
|
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00100010");
|
||||||
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
|
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 01000100");
|
||||||
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
|
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 10001000");
|
||||||
|
|
||||||
// All on
|
// All on
|
||||||
let byte1 = to_binary_string_post2021(&LaptopAuraPower {
|
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") {
|
match s.to_lowercase().trim_start_matches("0x") {
|
||||||
"tuf" => AuraDeviceType::LaptopKeyboardTuf,
|
"tuf" => AuraDeviceType::LaptopKeyboardTuf,
|
||||||
"1932" => AuraDeviceType::ScsiExtDisk,
|
"1932" => AuraDeviceType::ScsiExtDisk,
|
||||||
"1866" | "18c6" | "1869" | "1854" => Self::LaptopKeyboardPre2021,
|
"1866" | "1869" | "1854" => Self::LaptopKeyboardPre2021,
|
||||||
"1abe" | "1b4c" => Self::Ally,
|
"1abe" | "1b4c" => Self::Ally,
|
||||||
"19b3" | "193b" => Self::AnimeOrSlash,
|
"19b3" | "193b" => Self::AnimeOrSlash,
|
||||||
"19b6" => Self::LaptopKeyboard2021,
|
"19b6" | "1a30" | "18c6" => Self::LaptopKeyboard2021,
|
||||||
_ => Self::Unknown,
|
_ => Self::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,8 +102,9 @@ pub fn setup_window(config: Arc<Mutex<Config>>) -> MainWindow {
|
|||||||
available.contains(&"xyz.ljones.Aura".to_string()),
|
available.contains(&"xyz.ljones.Aura".to_string()),
|
||||||
available.contains(&"xyz.ljones.Anime".to_string()),
|
available.contains(&"xyz.ljones.Anime".to_string()),
|
||||||
available.contains(&"xyz.ljones.FanCurves".to_string()),
|
available.contains(&"xyz.ljones.FanCurves".to_string()),
|
||||||
true,
|
true, // GPU Configuration
|
||||||
true,
|
true, // App Settings
|
||||||
|
true, // About
|
||||||
]
|
]
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { PageFans } from "pages/fans.slint";
|
|||||||
import { PageAnime, AnimePageData } from "pages/anime.slint";
|
import { PageAnime, AnimePageData } from "pages/anime.slint";
|
||||||
import { RogItem } from "widgets/common.slint";
|
import { RogItem } from "widgets/common.slint";
|
||||||
import { PageAura } from "pages/aura.slint";
|
import { PageAura } from "pages/aura.slint";
|
||||||
|
import { PageGPU } from "pages/gpu.slint";
|
||||||
import { Node } from "widgets/graph.slint";
|
import { Node } from "widgets/graph.slint";
|
||||||
export { Node }
|
export { Node }
|
||||||
import { FanPageData, FanType, Profile } from "types/fan_types.slint";
|
import { FanPageData, FanType, Profile } from "types/fan_types.slint";
|
||||||
@@ -24,7 +25,15 @@ export component MainWindow inherits Window {
|
|||||||
default-font-size: 14px;
|
default-font-size: 14px;
|
||||||
default-font-weight: 400;
|
default-font-weight: 400;
|
||||||
icon: @image-url("../data/rog-control-center.png");
|
icon: @image-url("../data/rog-control-center.png");
|
||||||
in property <[bool]> sidebar_items_avilable: [true, true, true, true, true, true];
|
in property <[bool]> sidebar_items_avilable: [
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true, // GPU Configuration
|
||||||
|
true, // App Settings
|
||||||
|
true, // About
|
||||||
|
];
|
||||||
private property <bool> show_notif;
|
private property <bool> show_notif;
|
||||||
private property <bool> fade_cover;
|
private property <bool> fade_cover;
|
||||||
private property <bool> toast: false;
|
private property <bool> toast: false;
|
||||||
@@ -58,8 +67,9 @@ export component MainWindow inherits Window {
|
|||||||
@tr("Menu2" => "Keyboard Aura"),
|
@tr("Menu2" => "Keyboard Aura"),
|
||||||
@tr("Menu3" => "AniMe Matrix"),
|
@tr("Menu3" => "AniMe Matrix"),
|
||||||
@tr("Menu4" => "Fan Curves"),
|
@tr("Menu4" => "Fan Curves"),
|
||||||
@tr("Menu5" => "App Settings"),
|
@tr("Menu5" => "GPU Configuration"),
|
||||||
@tr("Menu6" => "About"),
|
@tr("Menu6" => "App Settings"),
|
||||||
|
@tr("Menu7" => "About"),
|
||||||
];
|
];
|
||||||
available: root.sidebar_items_avilable;
|
available: root.sidebar_items_avilable;
|
||||||
}
|
}
|
||||||
@@ -89,26 +99,61 @@ export component MainWindow inherits Window {
|
|||||||
height: root.height + 12px;
|
height: root.height + 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
aura := PageAura {
|
/*if(side-bar.current-item == 1):*/ aura := PageAura {
|
||||||
width: root.width - side-bar.width;
|
width: root.width - side-bar.width;
|
||||||
visible: side-bar.current-item == 1;
|
visible: side-bar.current-item == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(side-bar.current-item == 2): PageAnime {
|
if(side-bar.current-item == 2): PageAnime {
|
||||||
width: root.width - side-bar.width;
|
width: root.width - side-bar.width;
|
||||||
|
visible: side-bar.current-item == 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fans := PageFans {
|
if(side-bar.current-item == 3): fans := PageFans {
|
||||||
width: root.width - side-bar.width;
|
width: root.width - side-bar.width;
|
||||||
visible: side-bar.current-item == 3;
|
visible: side-bar.current-item == 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(side-bar.current-item == 4): PageAppSettings {
|
if(side-bar.current-item == 4): PageGPU {
|
||||||
width: root.width - side-bar.width;
|
width: root.width - side-bar.width;
|
||||||
|
visible: side-bar.current-item == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(side-bar.current-item == 5): PageAbout {
|
if(side-bar.current-item == 5): PageAppSettings {
|
||||||
width: root.width - side-bar.width;
|
width: root.width - side-bar.width;
|
||||||
|
visible: side-bar.current-item == 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(side-bar.current-item == 6): PageAbout {
|
||||||
|
width: root.width - side-bar.width;
|
||||||
|
visible: side-bar.current-item == 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if toast: Rectangle {
|
||||||
|
x: 0px;
|
||||||
|
y: root.height - self.height;
|
||||||
|
width: root.width - side-bar.width;
|
||||||
|
height: 40px;
|
||||||
|
opacity: 1.0;
|
||||||
|
background: Palette.selection-background;
|
||||||
|
clip: true;
|
||||||
|
TouchArea {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
clicked => {
|
||||||
|
toast = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background: Palette.control-background;
|
||||||
|
Text {
|
||||||
|
color: Palette.control-foreground;
|
||||||
|
text: root.toast_text;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,31 +178,6 @@ export component MainWindow inherits Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if toast: Rectangle {
|
|
||||||
x: 0px;
|
|
||||||
y: 0px;
|
|
||||||
width: root.width;
|
|
||||||
height: 32px;
|
|
||||||
opacity: 1.0;
|
|
||||||
background: Colors.grey;
|
|
||||||
TouchArea {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
clicked => {
|
|
||||||
toast = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
background: Palette.control-background;
|
|
||||||
Text {
|
|
||||||
color: Palette.control-foreground;
|
|
||||||
text: root.toast_text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// // TODO: or use Dialogue
|
// // TODO: or use Dialogue
|
||||||
if show_notif: Rectangle {
|
if show_notif: Rectangle {
|
||||||
|
|||||||
102
rog-control-center/ui/pages/gpu.slint
Normal file
102
rog-control-center/ui/pages/gpu.slint
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { Palette, TabWidget, Button, CheckBox } from "std-widgets.slint";
|
||||||
|
import { Graph, Node } from "../widgets/graph.slint";
|
||||||
|
import { SystemToggle } from "../widgets/common.slint";
|
||||||
|
import { Profile, FanType, FanPageData } from "../types/fan_types.slint";
|
||||||
|
import { Palette, HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox, StandardButton} from "std-widgets.slint";
|
||||||
|
|
||||||
|
export global GPUPageData {
|
||||||
|
// GPU mode and device state
|
||||||
|
in-out property <int> gpu_mux_mode: 1; // 0 = Ultra/Discreet, 1 = Integrated/Optimus
|
||||||
|
in-out property <int> dgpu_disabled: 0; // 1 == dGPU disabled
|
||||||
|
in-out property <int> egpu_enabled: 0; // 1 == eGPU (XGMobile) enabled
|
||||||
|
callback cb_gpu_mux_mode(int);
|
||||||
|
callback cb_dgpu_disabled(int);
|
||||||
|
callback cb_egpu_enabled(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
export component PageGPU inherits Rectangle {
|
||||||
|
|
||||||
|
clip: true;
|
||||||
|
ScrollView {
|
||||||
|
VerticalLayout {
|
||||||
|
padding: 10px;
|
||||||
|
spacing: 10px;
|
||||||
|
alignment: LayoutAlignment.start;
|
||||||
|
Rectangle {
|
||||||
|
background: Palette.alternate-background;
|
||||||
|
border-color: Palette.accent-background;
|
||||||
|
border-width: 3px;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 40px;
|
||||||
|
Text {
|
||||||
|
font-size: 18px;
|
||||||
|
color: Palette.control-foreground;
|
||||||
|
horizontal-alignment: TextHorizontalAlignment.center;
|
||||||
|
text: @tr("GPU Configuration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox {
|
||||||
|
HorizontalLayout {
|
||||||
|
spacing: 10px;
|
||||||
|
|
||||||
|
// Ultra (discreet) mode button - disabled if dGPU is marked disabled
|
||||||
|
Rectangle {
|
||||||
|
width: 120px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-color: Palette.border;
|
||||||
|
border-width: 2px;
|
||||||
|
background: GPUPageData.gpu_mux_mode == 0 ? Palette.accent-background : Palette.control-background;
|
||||||
|
opacity: GPUPageData.dgpu_disabled == 1 ? 0.5 : 1.0;
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: Palette.control-foreground;
|
||||||
|
horizontal-alignment: TextHorizontalAlignment.center;
|
||||||
|
vertical-alignment: TextVerticalAlignment.center;
|
||||||
|
text: @tr("Ultra");
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchArea {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
clicked => {
|
||||||
|
if (GPUPageData.dgpu_disabled != 1 && GPUPageData.gpu_mux_mode != 0) {
|
||||||
|
GPUPageData.cb_gpu_mux_mode(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Integrated (Optimus) mode button
|
||||||
|
Rectangle {
|
||||||
|
width: 120px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 6px;
|
||||||
|
border-color: Palette.border;
|
||||||
|
border-width: 2px;
|
||||||
|
background: GPUPageData.gpu_mux_mode == 1 ? Palette.accent-background : Palette.control-background;
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: Palette.control-foreground;
|
||||||
|
horizontal-alignment: TextHorizontalAlignment.center;
|
||||||
|
vertical-alignment: TextVerticalAlignment.center;
|
||||||
|
text: @tr("Integrated");
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchArea {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
clicked => {
|
||||||
|
if (GPUPageData.gpu_mux_mode != 1) {
|
||||||
|
GPUPageData.cb_gpu_mux_mode(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -253,6 +253,66 @@ export component PageSystem inherits Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SystemPageData.kbd_leds_awake != -1 ||
|
||||||
|
SystemPageData.kbd_leds_sleep != -1 ||
|
||||||
|
SystemPageData.kbd_leds_boot != -1 ||
|
||||||
|
SystemPageData.kbd_leds_shutdown != -1: VerticalLayout {
|
||||||
|
padding: 0px;
|
||||||
|
spacing: 0px;
|
||||||
|
alignment: LayoutAlignment.start;
|
||||||
|
Rectangle {
|
||||||
|
background: Palette.alternate-background;
|
||||||
|
border-color: Palette.accent-background;
|
||||||
|
border-width: 3px;
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 40px;
|
||||||
|
Text {
|
||||||
|
font-size: 18px;
|
||||||
|
color: Palette.control-foreground;
|
||||||
|
horizontal-alignment: TextHorizontalAlignment.center;
|
||||||
|
text: @tr("Keyboard Power Management");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBox {
|
||||||
|
|
||||||
|
HorizontalLayout {
|
||||||
|
spacing: 10px;
|
||||||
|
if SystemPageData.kbd_leds_awake != -1: SystemToggleInt {
|
||||||
|
text: @tr("Keyboard Awake Effect");
|
||||||
|
checked_int <=> SystemPageData.kbd_leds_awake;
|
||||||
|
toggled => {
|
||||||
|
SystemPageData.cb_kbd_leds_awake(SystemPageData.kbd_leds_awake)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if SystemPageData.kbd_leds_sleep != -1: SystemToggleInt {
|
||||||
|
text: @tr("Keyboard Sleep Effect");
|
||||||
|
checked_int <=> SystemPageData.kbd_leds_sleep;
|
||||||
|
toggled => {
|
||||||
|
SystemPageData.cb_kbd_leds_sleep(SystemPageData.kbd_leds_sleep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if SystemPageData.kbd_leds_boot != -1: SystemToggleInt {
|
||||||
|
text: @tr("Keyboard Boot Effect");
|
||||||
|
checked_int <=> SystemPageData.kbd_leds_boot;
|
||||||
|
toggled => {
|
||||||
|
SystemPageData.cb_kbd_leds_boot(SystemPageData.kbd_leds_boot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if SystemPageData.kbd_leds_shutdown != -1: SystemToggleInt {
|
||||||
|
text: @tr("Keyboard Shutdown Effect");
|
||||||
|
checked_int <=> SystemPageData.kbd_leds_shutdown;
|
||||||
|
toggled => {
|
||||||
|
SystemPageData.cb_kbd_leds_shutdown(SystemPageData.kbd_leds_shutdown)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
background: Palette.alternate-background;
|
background: Palette.alternate-background;
|
||||||
border-color: Palette.accent-background;
|
border-color: Palette.accent-background;
|
||||||
@@ -286,44 +346,6 @@ export component PageSystem inherits Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupBox {
|
|
||||||
title: @tr("Keyboard Power Management");
|
|
||||||
HorizontalLayout {
|
|
||||||
spacing: 10px;
|
|
||||||
if SystemPageData.kbd_leds_awake != -1: SystemToggleInt {
|
|
||||||
text: @tr("Keyboard Awake Effect");
|
|
||||||
checked_int <=> SystemPageData.kbd_leds_awake;
|
|
||||||
toggled => {
|
|
||||||
SystemPageData.cb_kbd_leds_awake(SystemPageData.kbd_leds_awake)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if SystemPageData.kbd_leds_sleep != -1: SystemToggleInt {
|
|
||||||
text: @tr("Keyboard Sleep Effect");
|
|
||||||
checked_int <=> SystemPageData.kbd_leds_sleep;
|
|
||||||
toggled => {
|
|
||||||
SystemPageData.cb_kbd_leds_sleep(SystemPageData.kbd_leds_sleep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if SystemPageData.kbd_leds_boot != -1: SystemToggleInt {
|
|
||||||
text: @tr("Keyboard Boot Effect");
|
|
||||||
checked_int <=> SystemPageData.kbd_leds_boot;
|
|
||||||
toggled => {
|
|
||||||
SystemPageData.cb_kbd_leds_boot(SystemPageData.kbd_leds_boot)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if SystemPageData.kbd_leds_shutdown != -1: SystemToggleInt {
|
|
||||||
text: @tr("Keyboard Shutdown Effect");
|
|
||||||
checked_int <=> SystemPageData.kbd_leds_shutdown;
|
|
||||||
toggled => {
|
|
||||||
SystemPageData.cb_kbd_leds_shutdown(SystemPageData.kbd_leds_shutdown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HorizontalBox {
|
HorizontalBox {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
spacing: 10px;
|
spacing: 10px;
|
||||||
|
|||||||
@@ -253,8 +253,19 @@ impl FirmwareAttributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||||
|
pub enum FirmwareAttributeType {
|
||||||
|
#[default]
|
||||||
|
Immediate,
|
||||||
|
TUFKeyboard,
|
||||||
|
Ppt,
|
||||||
|
Gpu,
|
||||||
|
Bios,
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! define_attribute_getters {
|
macro_rules! define_attribute_getters {
|
||||||
($($attr:ident),*) => {
|
// Accept a list of attribute idents and an optional `types { .. }` block
|
||||||
|
( $( $attr:ident ),* $(,)? $( ; types { $( $tattr:ident : $ptype:ident ),* $(,)? } )? ) => {
|
||||||
impl FirmwareAttributes {
|
impl FirmwareAttributes {
|
||||||
$(
|
$(
|
||||||
pub fn $attr(&self) -> Option<&Attribute> {
|
pub fn $attr(&self) -> Option<&Attribute> {
|
||||||
@@ -268,6 +279,17 @@ macro_rules! define_attribute_getters {
|
|||||||
});
|
});
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FirmwareAttribute {
|
||||||
|
pub fn property_type(&self) -> FirmwareAttributeType {
|
||||||
|
match <&str>::from(*self) {
|
||||||
|
$(
|
||||||
|
$( stringify!($tattr) => FirmwareAttributeType::$ptype, )*
|
||||||
|
)?
|
||||||
|
_ => FirmwareAttributeType::Immediate,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,6 +321,38 @@ define_attribute_getters!(
|
|||||||
gpu_mux_mode,
|
gpu_mux_mode,
|
||||||
mini_led_mode,
|
mini_led_mode,
|
||||||
screen_auto_brightness
|
screen_auto_brightness
|
||||||
|
; types {
|
||||||
|
ppt_pl1_spl: Ppt,
|
||||||
|
ppt_pl2_sppt: Ppt,
|
||||||
|
ppt_apu_sppt: Ppt,
|
||||||
|
ppt_platform_sppt: Ppt,
|
||||||
|
ppt_fppt: Ppt,
|
||||||
|
nv_dynamic_boost: Ppt,
|
||||||
|
nv_temp_target: Ppt,
|
||||||
|
dgpu_base_tgp: Ppt,
|
||||||
|
dgpu_tgp: Ppt,
|
||||||
|
|
||||||
|
gpu_mux_mode: Gpu,
|
||||||
|
egpu_connected: Gpu,
|
||||||
|
egpu_enable: Gpu,
|
||||||
|
dgpu_disable: Gpu,
|
||||||
|
|
||||||
|
boot_sound: Bios,
|
||||||
|
|
||||||
|
mcu_powersave: Immediate,
|
||||||
|
|
||||||
|
screen_auto_brightness: Immediate,
|
||||||
|
mini_led_mode: Immediate,
|
||||||
|
panel_hd_mode: Immediate,
|
||||||
|
panel_od: Immediate,
|
||||||
|
|
||||||
|
kbd_leds_awake: TUFKeyboard,
|
||||||
|
kbd_leds_sleep: TUFKeyboard,
|
||||||
|
kbd_leds_boot: TUFKeyboard,
|
||||||
|
kbd_leds_shutdown: TUFKeyboard,
|
||||||
|
|
||||||
|
charge_mode: Immediate,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/// CamelCase names of the properties. Intended for use with DBUS
|
/// CamelCase names of the properties. Intended for use with DBUS
|
||||||
@@ -352,29 +406,6 @@ pub enum FirmwareAttribute {
|
|||||||
KbdLedsShutdown = 30,
|
KbdLedsShutdown = 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FirmwareAttribute {
|
|
||||||
pub fn is_ppt(&self) -> bool {
|
|
||||||
matches!(
|
|
||||||
self,
|
|
||||||
FirmwareAttribute::PptPl1Spl
|
|
||||||
| FirmwareAttribute::PptPl2Sppt
|
|
||||||
| FirmwareAttribute::PptPl3Fppt
|
|
||||||
| FirmwareAttribute::PptFppt
|
|
||||||
| FirmwareAttribute::PptApuSppt
|
|
||||||
| FirmwareAttribute::PptPlatformSppt
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_dgpu(&self) -> bool {
|
|
||||||
matches!(
|
|
||||||
self,
|
|
||||||
FirmwareAttribute::NvDynamicBoost
|
|
||||||
| FirmwareAttribute::NvTempTarget
|
|
||||||
| FirmwareAttribute::DgpuTgp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for FirmwareAttribute {
|
impl From<&str> for FirmwareAttribute {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
match s {
|
match s {
|
||||||
|
|||||||
@@ -162,7 +162,6 @@ impl CurveData {
|
|||||||
/// Write this curve to the device fan specified by `self.fan`
|
/// Write this curve to the device fan specified by `self.fan`
|
||||||
pub fn write_to_device(&self, device: &mut Device) -> std::io::Result<()> {
|
pub fn write_to_device(&self, device: &mut Device) -> std::io::Result<()> {
|
||||||
let pwm_num: char = self.fan.into();
|
let pwm_num: char = self.fan.into();
|
||||||
let enable = if self.enabled { '1' } else { '2' };
|
|
||||||
|
|
||||||
for (index, out) in self.pwm.iter().enumerate() {
|
for (index, out) in self.pwm.iter().enumerate() {
|
||||||
let pwm = pwm_str(pwm_num, index);
|
let pwm = pwm_str(pwm_num, index);
|
||||||
@@ -176,10 +175,20 @@ impl CurveData {
|
|||||||
device.set_attribute_value(&temp, out.to_string())?;
|
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
|
device
|
||||||
.set_attribute_value(format!("pwm{pwm_num}_enable"), enable.to_string())
|
.set_attribute_value(&enable_attr, enable.to_string())
|
||||||
.map_err(|e| error!("Failed to set pwm{pwm_num}_enable to {enable}: {e:?}"))
|
.map_err(|e| error!("Failed to set {enable_attr} to {enable}: {e:?}"))
|
||||||
.ok();
|
.ok();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,15 +181,29 @@ impl FanCurveProfiles {
|
|||||||
PlatformProfile::Quiet | PlatformProfile::LowPower => &mut self.quiet,
|
PlatformProfile::Quiet | PlatformProfile::LowPower => &mut self.quiet,
|
||||||
PlatformProfile::Custom => &mut self.custom,
|
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)?;
|
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) {
|
for fan in fans.iter().filter(|f| f.enabled) {
|
||||||
debug!("write_profile_curve_to_platform: writing profile:{profile}, {fan:?}");
|
debug!(
|
||||||
fan.write_to_device(device)?;
|
"write_profile_curve_to_platform: enabling fan for profile:{profile}, {:?}",
|
||||||
|
fan.fan
|
||||||
|
);
|
||||||
|
fan.set_enable(device)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user