Skip to content

Commit 4ff42b8

Browse files
Merge pull request #85 from FrameworkComputer/auto-custom
fp-brightness: Add support for V1 host command
2 parents 456e7dc + fd9696a commit 4ff42b8

5 files changed

Lines changed: 145 additions & 24 deletions

File tree

framework_lib/src/chromium_ec/commands.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -844,10 +844,14 @@ pub enum FpLedBrightnessLevel {
844844
High = 0,
845845
Medium = 1,
846846
Low = 2,
847+
UltraLow = 3,
848+
/// Custom: Only get, never set
849+
Custom = 0xFE,
850+
Auto = 0xFF,
847851
}
848852

849853
#[repr(C, packed)]
850-
pub struct EcRequestFpLedLevelControl {
854+
pub struct EcRequestFpLedLevelControlV0 {
851855
/// See enum FpLedBrightnessLevel
852856
pub set_level: u8,
853857
/// Boolean. >1 to get the level
@@ -856,12 +860,42 @@ pub struct EcRequestFpLedLevelControl {
856860

857861
#[repr(C, packed)]
858862
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
859-
pub struct EcResponseFpLedLevelControl {
863+
pub struct EcResponseFpLedLevelControlV0 {
864+
/// Current brightness, 1-100%
865+
pub percentage: u8,
866+
}
867+
868+
impl EcRequest<EcResponseFpLedLevelControlV0> for EcRequestFpLedLevelControlV0 {
869+
fn command_id() -> EcCommands {
870+
EcCommands::FpLedLevelControl
871+
}
872+
fn command_version() -> u8 {
873+
0
874+
}
875+
}
876+
877+
#[repr(C, packed)]
878+
pub struct EcRequestFpLedLevelControlV1 {
879+
/// Percentage 1-100
880+
pub set_percentage: u8,
881+
/// Boolean. >1 to get the level
882+
pub get_level: u8,
883+
}
884+
885+
#[repr(C, packed)]
886+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
887+
pub struct EcResponseFpLedLevelControlV1 {
888+
/// Current brightness, 1-100%
889+
pub percentage: u8,
890+
/// Requested level. See enum FpLedBrightnessLevel
860891
pub level: u8,
861892
}
862893

863-
impl EcRequest<EcResponseFpLedLevelControl> for EcRequestFpLedLevelControl {
894+
impl EcRequest<EcResponseFpLedLevelControlV1> for EcRequestFpLedLevelControlV1 {
864895
fn command_id() -> EcCommands {
865896
EcCommands::FpLedLevelControl
866897
}
898+
fn command_version() -> u8 {
899+
1
900+
}
867901
}

framework_lib/src/chromium_ec/mod.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,17 @@ impl CrosEc {
313313
Ok((limits.min_percentage, limits.max_percentage))
314314
}
315315

316+
pub fn set_fp_led_percentage(&self, percentage: u8) -> EcResult<()> {
317+
// Sending bytes manually because the Set command, as opposed to the Get command,
318+
// does not return any data
319+
let limits = &[percentage, 0x00];
320+
let data = self.send_command(EcCommands::FpLedLevelControl as u16, 1, limits)?;
321+
322+
util::assert_win_len(data.len(), 0);
323+
324+
Ok(())
325+
}
326+
316327
pub fn set_fp_led_level(&self, level: FpLedBrightnessLevel) -> EcResult<()> {
317328
// Sending bytes manually because the Set command, as opposed to the Get command,
318329
// does not return any data
@@ -325,16 +336,33 @@ impl CrosEc {
325336
}
326337

327338
/// Get fingerprint led brightness level
328-
pub fn get_fp_led_level(&self) -> EcResult<u8> {
329-
let res = EcRequestFpLedLevelControl {
330-
set_level: 0xFF,
339+
pub fn get_fp_led_level(&self) -> EcResult<(u8, Option<FpLedBrightnessLevel>)> {
340+
let res = EcRequestFpLedLevelControlV1 {
341+
set_percentage: 0xFF,
331342
get_level: 0xFF,
332343
}
333-
.send_command(self)?;
344+
.send_command(self);
345+
346+
// If V1 does not exist, fall back
347+
if let Err(EcError::Response(EcResponseStatus::InvalidVersion)) = res {
348+
let res = EcRequestFpLedLevelControlV0 {
349+
set_level: 0xFF,
350+
get_level: 0xFF,
351+
}
352+
.send_command(self)?;
353+
debug!("Current Brightness: {}%", res.percentage);
354+
return Ok((res.percentage, None));
355+
}
356+
357+
let res = res?;
334358

335-
debug!("Level Raw: {}", res.level);
359+
debug!("Current Brightness: {}%", res.percentage);
360+
debug!("Level Raw: {}", res.level);
336361

337-
Ok(res.level)
362+
// TODO: can turn this into None and log
363+
let level = FromPrimitive::from_u8(res.level)
364+
.ok_or(EcError::DeviceError(format!("Invalid level {}", res.level)))?;
365+
Ok((res.percentage, Some(level)))
338366
}
339367

340368
/// Get the intrusion switch status (whether the chassis is open or not)

framework_lib/src/commandline/clap_std.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,13 @@ struct ClapCli {
137137
#[arg(long)]
138138
get_gpio: Option<String>,
139139

140-
/// Get or set fingerprint LED brightness
140+
/// Get or set fingerprint LED brightness level
141141
#[arg(long)]
142-
fp_brightness: Option<Option<FpBrightnessArg>>,
142+
fp_led_level: Option<Option<FpBrightnessArg>>,
143+
144+
/// Get or set fingerprint LED brightness percentage
145+
#[arg(long)]
146+
fp_brightness: Option<Option<u8>>,
143147

144148
/// Set keyboard backlight percentage or get, if no value provided
145149
#[arg(long)]
@@ -267,6 +271,7 @@ pub fn parse(args: &[String]) -> Cli {
267271
input_deck_mode: args.input_deck_mode,
268272
charge_limit: args.charge_limit,
269273
get_gpio: args.get_gpio,
274+
fp_led_level: args.fp_led_level,
270275
fp_brightness: args.fp_brightness,
271276
kblight: args.kblight,
272277
tablet_mode: args.tablet_mode,

framework_lib/src/commandline/mod.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,17 @@ pub enum FpBrightnessArg {
9393
High,
9494
Medium,
9595
Low,
96+
UltraLow,
97+
Auto,
9698
}
9799
impl From<FpBrightnessArg> for FpLedBrightnessLevel {
98100
fn from(w: FpBrightnessArg) -> FpLedBrightnessLevel {
99101
match w {
100102
FpBrightnessArg::High => FpLedBrightnessLevel::High,
101103
FpBrightnessArg::Medium => FpLedBrightnessLevel::Medium,
102104
FpBrightnessArg::Low => FpLedBrightnessLevel::Low,
105+
FpBrightnessArg::UltraLow => FpLedBrightnessLevel::UltraLow,
106+
FpBrightnessArg::Auto => FpLedBrightnessLevel::Auto,
103107
}
104108
}
105109
}
@@ -159,7 +163,8 @@ pub struct Cli {
159163
pub input_deck_mode: Option<InputDeckModeArg>,
160164
pub charge_limit: Option<Option<u8>>,
161165
pub get_gpio: Option<String>,
162-
pub fp_brightness: Option<Option<FpBrightnessArg>>,
166+
pub fp_led_level: Option<Option<FpBrightnessArg>>,
167+
pub fp_brightness: Option<Option<u8>>,
163168
pub kblight: Option<Option<u8>>,
164169
pub tablet_mode: Option<TabletModeArg>,
165170
pub console: Option<ConsoleArg>,
@@ -741,6 +746,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 {
741746
} else {
742747
println!("Not found");
743748
}
749+
} else if let Some(maybe_led_level) = &args.fp_led_level {
750+
print_err(handle_fp_led_level(&ec, *maybe_led_level));
744751
} else if let Some(maybe_brightness) = &args.fp_brightness {
745752
print_err(handle_fp_brightness(&ec, *maybe_brightness));
746753
} else if let Some(Some(kblight)) = args.kblight {
@@ -1009,7 +1016,8 @@ Options:
10091016
--input-deck-mode Set input deck power mode [possible values: auto, off, on] (Framework 16 only)
10101017
--charge-limit [<VAL>] Get or set battery charge limit (Percentage number as arg, e.g. '100')
10111018
--get-gpio <GET_GPIO> Get GPIO value by name
1012-
--fp-brightness [<VAL>]Get or set fingerprint LED brightness level [possible values: high, medium, low]
1019+
--fp-led-level [<VAL>] Get or set fingerprint LED brightness level [possible values: high, medium, low]
1020+
--fp-brightness [<VAL>]Get or set fingerprint LED brightness percentage
10131021
--kblight [<KBLIGHT>] Set keyboard backlight percentage or get, if no value provided
10141022
--console <CONSOLE> Get EC console, choose whether recent or to follow the output [possible values: recent, follow]
10151023
--hash <HASH> Hash a file of arbitrary data
@@ -1355,13 +1363,34 @@ fn handle_charge_limit(ec: &CrosEc, maybe_limit: Option<u8>) -> EcResult<()> {
13551363
Ok(())
13561364
}
13571365

1358-
fn handle_fp_brightness(ec: &CrosEc, maybe_brightness: Option<FpBrightnessArg>) -> EcResult<()> {
1366+
fn handle_fp_led_level(ec: &CrosEc, maybe_led_level: Option<FpBrightnessArg>) -> EcResult<()> {
1367+
if let Some(led_level) = maybe_led_level {
1368+
ec.set_fp_led_level(led_level.into())?;
1369+
}
1370+
1371+
let (brightness, level) = ec.get_fp_led_level()?;
1372+
// TODO: Rename to power button
1373+
println!("Fingerprint LED Brightness");
1374+
if let Some(level) = level {
1375+
println!(" Requested: {:?}", level);
1376+
}
1377+
println!(" Brightness: {}%", brightness);
1378+
1379+
Ok(())
1380+
}
1381+
1382+
fn handle_fp_brightness(ec: &CrosEc, maybe_brightness: Option<u8>) -> EcResult<()> {
13591383
if let Some(brightness) = maybe_brightness {
1360-
ec.set_fp_led_level(brightness.into())?;
1384+
ec.set_fp_led_percentage(brightness)?;
13611385
}
13621386

1363-
let level = ec.get_fp_led_level()?;
1364-
println!("Fingerprint LED Brightness: {:?}%", level);
1387+
let (brightness, level) = ec.get_fp_led_level()?;
1388+
// TODO: Rename to power button
1389+
println!("Fingerprint LED Brightness");
1390+
if let Some(level) = level {
1391+
println!(" Requested: {:?}", level);
1392+
}
1393+
println!(" Brightness: {}%", brightness);
13651394

13661395
Ok(())
13671396
}

framework_lib/src/commandline/uefi.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub fn parse(args: &[String]) -> Cli {
8484
input_deck_mode: None,
8585
charge_limit: None,
8686
get_gpio: None,
87+
fp_led_level: None,
8788
fp_brightness: None,
8889
kblight: None,
8990
tablet_mode: None,
@@ -237,17 +238,41 @@ pub fn parse(args: &[String]) -> Cli {
237238
None
238239
};
239240
found_an_option = true;
240-
} else if arg == "--fp-brightness" {
241-
cli.fp_brightness = if args.len() > i + 1 {
242-
let fp_brightness_arg = &args[i + 1];
243-
if fp_brightness_arg == "high" {
241+
} else if arg == "--fp-led-level" {
242+
cli.fp_led_level = if args.len() > i + 1 {
243+
let fp_led_level_arg = &args[i + 1];
244+
if fp_led_level_arg == "high" {
244245
Some(Some(FpBrightnessArg::High))
245-
} else if fp_brightness_arg == "medium" {
246+
} else if fp_led_level_arg == "medium" {
246247
Some(Some(FpBrightnessArg::Medium))
247-
} else if fp_brightness_arg == "low" {
248+
} else if fp_led_level_arg == "low" {
248249
Some(Some(FpBrightnessArg::Low))
250+
} else if fp_led_level_arg == "ultra-low" {
251+
Some(Some(FpBrightnessArg::UltraLow))
252+
} else if fp_led_level_arg == "auto" {
253+
Some(Some(FpBrightnessArg::Auto))
254+
} else {
255+
println!("Invalid value for --fp-led-level: {}", fp_led_level_arg);
256+
None
257+
}
258+
} else {
259+
Some(None)
260+
};
261+
found_an_option = true;
262+
} else if arg == "--fp-brightness" {
263+
cli.fp_brightness = if args.len() > i + 1 {
264+
if let Ok(fp_brightness_arg) = args[i + 1].parse::<u8>() {
265+
if fp_brightness_arg == 0 || fp_brightness_arg > 100 {
266+
println!(
267+
"Invalid value for --fp-brightness: {}. Must be in the range of 1-100",
268+
fp_brightness_arg
269+
);
270+
None
271+
} else {
272+
Some(Some(fp_brightness_arg))
273+
}
249274
} else {
250-
println!("Invalid value for --fp-brightness: {}", fp_brightness_arg);
275+
println!("Invalid value for --fp-brightness. Must be in the range of 1-100");
251276
None
252277
}
253278
} else {

0 commit comments

Comments
 (0)