Conversation
There was a problem hiding this comment.
Pull request overview
Fixes --kblight on certain early Framework systems by detecting whether the EC supports PwmType::KbLight and falling back to an alternative PWM mapping when it does not.
Changes:
- Added a capability probe (
has_pwmtype_kblight()) based onPwmGetDuty. - Updated
set_keyboard_backlight()to fall back toPwmType::Genericwith a different index whenKbLightisn’t supported. - Updated
get_keyboard_backlight()to use the same fallback logic.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
7d35797 to
fae7898
Compare
There was a problem hiding this comment.
Pull request overview
Improves keyboard backlight support on early Framework systems whose EC firmware doesn’t expose the dedicated CONFIG_PWM_KBLIGHT channel by falling back to a generic PWM channel.
Changes:
- Add fallback in
set_keyboard_backlight()to usePwmType::Genericindex1whenPwmType::KbLightreturnsInvalidParameter. - Add corresponding fallback in
get_keyboard_backlight()for the same early-system behavior. - Refactor shared duty calculation into a local
dutyvariable.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Early systems (hx20/hx30) don't enable CONFIG_PWM_KBLIGHT in their EC firmware; | ||
| // keyboard backlight is at generic PWM channel index 1. | ||
| if let Err(EcError::Response(EcResponseStatus::InvalidParameter)) = res { | ||
| let res = EcRequestPwmSetDuty { | ||
| duty, | ||
| pwm_type: PwmType::Generic as u8, | ||
| index: 1, | ||
| } | ||
| .send_command(self); | ||
| debug_assert!(res.is_ok()); | ||
| return; | ||
| } | ||
| debug_assert!(res.is_ok()); | ||
| } |
There was a problem hiding this comment.
res is moved into the if let Err(...) = res pattern match, but then it’s used again afterwards in debug_assert!(res.is_ok()). This won’t compile because EcResult<()> isn’t Copy. Match on &res (or restructure with match res { ... }) so you can both detect InvalidParameter and still use/inspect the original result.
There was a problem hiding this comment.
it definitely does compile
framework_lib/src/chromium_ec/mod.rs
Outdated
| let kblight = if let Err(EcError::Response(EcResponseStatus::InvalidParameter)) = res { | ||
| EcRequestPwmGetDuty { | ||
| pwm_type: PwmType::Generic as u8, | ||
| index: 1, | ||
| } | ||
| .send_command(self)? | ||
| } else { | ||
| res? |
There was a problem hiding this comment.
res is moved into if let Err(...) = res, but the else branch then tries to use res?. This won’t compile due to use-after-move. Consider rewriting as a match res { Err(EcError::Response(InvalidParameter)) => { ... }, other => other? } or pattern match on &res and then handle the owned res separately.
| let kblight = if let Err(EcError::Response(EcResponseStatus::InvalidParameter)) = res { | |
| EcRequestPwmGetDuty { | |
| pwm_type: PwmType::Generic as u8, | |
| index: 1, | |
| } | |
| .send_command(self)? | |
| } else { | |
| res? | |
| let kblight = match res { | |
| Err(EcError::Response(EcResponseStatus::InvalidParameter)) => { | |
| EcRequestPwmGetDuty { | |
| pwm_type: PwmType::Generic as u8, | |
| index: 1, | |
| } | |
| .send_command(self)? | |
| } | |
| other => other?, |
framework_lib/src/chromium_ec/mod.rs
Outdated
| /// * `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 as u16 * (PWM_MAX_DUTY / 100); |
There was a problem hiding this comment.
duty is computed with percent as u16 * (PWM_MAX_DUTY / 100), which (a) truncates such that percent == 100 does not reach PWM_MAX_DUTY (0xFFFF), and (b) can wrap on overflow in release builds if a caller passes percent > 100 (the current debug_assert! won’t protect release builds). Compute in a wider integer type (e.g., u32) and clamp/validate percent before converting back to u16.
| let duty = percent as u16 * (PWM_MAX_DUTY / 100); | |
| let clamped_percent = u32::from(percent).min(100); | |
| let duty = ((clamped_percent * u32::from(PWM_MAX_DUTY)) / 100) as u16; |
I tested on Laptop 13 Intel 13th gen and kblight didn't work. Signed-off-by: Daniel Schaefer <[email protected]>
Signed-off-by: Daniel Schaefer <[email protected]>
fae7898 to
9b915be
Compare
Tested on: