diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index cc04d33..1ee9b12 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -246,6 +246,16 @@ impl EcRequest<()> for EcRequestPwmSetFanDutyV1 { pub const PWM_MAX_DUTY: u16 = 0xFFFF; +pub fn percent_to_duty(percent: u8) -> u16 { + let duty = percent as u32 * PWM_MAX_DUTY as u32; + (duty / 100) as u16 +} + +pub fn duty_to_percent(duty: u16) -> u8 { + let percent = duty as u32 * 100; + (percent / PWM_MAX_DUTY as u32) as u8 +} + #[repr(C, packed)] pub struct EcRequestPwmSetDuty { /// Duty cycle, min 0, max 0xFFFF diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 2aa9e67..2b3d7e9 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -770,24 +770,49 @@ impl CrosEc { /// * `percent` - An integer from 0 to 100. 0 being off, 100 being full brightness pub fn set_keyboard_backlight(&self, percent: u8) { debug_assert!(percent <= 100); + let duty = percent_to_duty(percent); + let res = EcRequestPwmSetDuty { - duty: percent as u16 * (PWM_MAX_DUTY / 100), + duty, pwm_type: PwmType::KbLight as u8, index: 0, } .send_command(self); + + // Early systems (hx20/hx30) don't enable CONFIG_PWM_KBLIGHT in their EC firmware; + // keyboard backlight is at generic PWM channel index 1. + let res = match res { + Err(EcError::Response(EcResponseStatus::InvalidParameter)) => EcRequestPwmSetDuty { + duty, + pwm_type: PwmType::Generic as u8, + index: 1, + } + .send_command(self), + other => other, + }; debug_assert!(res.is_ok()); } /// Check the current brightness of the keyboard backlight pub fn get_keyboard_backlight(&self) -> EcResult { - let kblight = EcRequestPwmGetDuty { + let res = EcRequestPwmGetDuty { pwm_type: PwmType::KbLight as u8, index: 0, } - .send_command(self)?; + .send_command(self); + + // Early systems (hx20/hx30) don't enable CONFIG_PWM_KBLIGHT in their EC firmware; + // keyboard backlight is at generic PWM channel index 1. + let kblight = match res { + Err(EcError::Response(EcResponseStatus::InvalidParameter)) => EcRequestPwmGetDuty { + pwm_type: PwmType::Generic as u8, + index: 1, + } + .send_command(self)?, + other => other?, + }; - Ok((kblight.duty / (PWM_MAX_DUTY / 100)) as u8) + Ok(duty_to_percent(kblight.duty)) } pub fn ps2_emulation_enable(&self, enable: bool) -> EcResult<()> { diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index d965b67..7114c7a 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -1430,8 +1430,11 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } else if let Some(maybe_brightness) = &args.fp_brightness { print_err(handle_fp_brightness(&ec, *maybe_brightness)); } else if let Some(Some(kblight)) = args.kblight { - assert!(kblight <= 100); - ec.set_keyboard_backlight(kblight); + if kblight > 100 { + error!("--kblight must be percentage 0-100"); + } else { + ec.set_keyboard_backlight(kblight); + } } else if let Some(None) = args.kblight { print!("Keyboard backlight: "); if let Some(percentage) = print_err(ec.get_keyboard_backlight()) {