diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index a0205780..cad2be87 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -33,6 +33,7 @@ pub enum EcCommands { PwmSetFanDuty = 0x0024, PwmSetDuty = 0x0025, PwmGetDuty = 0x0026, + SetTabletMode = 0x0031, GpioGet = 0x93, I2cPassthrough = 0x9e, ConsoleSnapshot = 0x97, diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 82057165..1265c798 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -225,6 +225,24 @@ impl EcRequest for EcRequestPwmGetDuty { } } +pub enum TabletModeOverride { + Default = 0, + ForceTablet = 1, + ForceClamshell = 2, +} + +#[repr(C, packed)] +pub struct EcRequestSetTabletMode { + /// See TabletModeOverride + pub mode: u8, +} + +impl EcRequest<()> for EcRequestSetTabletMode { + fn command_id() -> EcCommands { + EcCommands::SetTabletMode + } +} + #[repr(C, packed)] pub struct EcRequestGpioGetV0 { pub name: [u8; 32], diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 399aca05..137a37fe 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -387,7 +387,6 @@ impl CrosEc { } /// Check the current brightness of the keyboard backlight - /// pub fn get_keyboard_backlight(&self) -> EcResult { let kblight = EcRequestPwmGetDuty { pwm_type: PwmType::KbLight as u8, @@ -398,6 +397,13 @@ impl CrosEc { Ok((kblight.duty / (PWM_MAX_DUTY / 100)) as u8) } + /// Set tablet mode + pub fn set_tablet_mode(&self, mode: TabletModeOverride) { + let mode = mode as u8; + let res = EcRequestSetTabletMode { mode }.send_command(self); + print_err(res); + } + /// Overwrite RO and RW regions of EC flash /// MEC/Legacy EC /// | Start | End | Size | Region | diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index 30e54d2e..140cb151 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -6,6 +6,7 @@ use clap::Parser; use crate::chromium_ec::CrosEcDriverType; use crate::commandline::{ Cli, ConsoleArg, FpBrightnessArg, HardwareDeviceType, InputDeckModeArg, RebootEcArg, + TabletModeArg, }; /// Swiss army knife for Framework laptops @@ -144,6 +145,11 @@ struct ClapCli { #[arg(long)] kblight: Option>, + /// Set tablet mode override + #[clap(value_enum)] + #[arg(long)] + tablet_mode: Option, + /// Get EC console, choose whether recent or to follow the output #[clap(value_enum)] #[arg(long)] @@ -263,6 +269,7 @@ pub fn parse(args: &[String]) -> Cli { get_gpio: args.get_gpio, fp_brightness: args.fp_brightness, kblight: args.kblight, + tablet_mode: args.tablet_mode, console: args.console, reboot_ec: args.reboot_ec, hash: args.hash.map(|x| x.into_os_string().into_string().unwrap()), diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 9a28c66b..e911f773 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -35,6 +35,7 @@ use crate::chromium_ec; use crate::chromium_ec::commands::DeckStateMode; use crate::chromium_ec::commands::FpLedBrightnessLevel; use crate::chromium_ec::commands::RebootEcCmd; +use crate::chromium_ec::commands::TabletModeOverride; use crate::chromium_ec::EcResponseStatus; use crate::chromium_ec::{print_err, EcFlashType}; use crate::chromium_ec::{EcError, EcResult}; @@ -61,6 +62,14 @@ use crate::chromium_ec::{CrosEc, CrosEcDriverType, HardwareDeviceType}; #[cfg(feature = "uefi")] use core::prelude::rust_2021::derive; +#[cfg_attr(not(feature = "uefi"), derive(clap::ValueEnum))] +#[derive(Clone, Debug, PartialEq)] +pub enum TabletModeArg { + Auto, + Tablet, + Laptop, +} + #[cfg_attr(not(feature = "uefi"), derive(clap::ValueEnum))] #[derive(Clone, Debug, PartialEq)] pub enum ConsoleArg { @@ -152,6 +161,7 @@ pub struct Cli { pub get_gpio: Option, pub fp_brightness: Option>, pub kblight: Option>, + pub tablet_mode: Option, pub console: Option, pub reboot_ec: Option, pub hash: Option, @@ -743,6 +753,13 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { } else { println!("Unable to tell"); } + } else if let Some(tablet_arg) = &args.tablet_mode { + let mode = match tablet_arg { + TabletModeArg::Auto => TabletModeOverride::Default, + TabletModeArg::Tablet => TabletModeOverride::ForceTablet, + TabletModeArg::Laptop => TabletModeOverride::ForceClamshell, + }; + ec.set_tablet_mode(mode); } else if let Some(console_arg) = &args.console { match console_arg { ConsoleArg::Follow => { diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index 121fc052..69dee466 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -12,7 +12,7 @@ use uefi::Identify; use crate::chromium_ec::{CrosEcDriverType, HardwareDeviceType}; use crate::commandline::Cli; -use super::{ConsoleArg, FpBrightnessArg, InputDeckModeArg, RebootEcArg}; +use super::{ConsoleArg, FpBrightnessArg, InputDeckModeArg, RebootEcArg, TabletModeArg}; /// Get commandline arguments from UEFI environment pub fn get_args(boot_services: &BootServices) -> Vec { @@ -86,6 +86,7 @@ pub fn parse(args: &[String]) -> Cli { get_gpio: None, fp_brightness: None, kblight: None, + tablet_mode: None, console: None, reboot_ec: None, hash: None, @@ -214,6 +215,28 @@ pub fn parse(args: &[String]) -> Cli { Some(None) }; found_an_option = true; + } else if arg == "--tablet-mode" { + cli.tablet_mode = if args.len() > i + 1 { + let tablet_mode_arg = &args[i + 1]; + if tablet_mode_arg == "auto" { + Some(TabletModeArg::Auto) + } else if tablet_mode_arg == "tablet" { + Some(TabletModeArg::Tablet) + } else if tablet_mode_arg == "laptop" { + Some(TabletModeArg::Laptop) + } else { + println!( + "Need to provide a value for --tablet-mode: '{}'. {}", + args[i + 1], + "Must be one of: `auto`, `tablet` or `laptop`", + ); + None + } + } else { + println!("Need to provide a value for --tablet-mode. One of: `auto`, `tablet` or `laptop`"); + None + }; + found_an_option = true; } else if arg == "--fp-brightness" { cli.fp_brightness = if args.len() > i + 1 { let fp_brightness_arg = &args[i + 1];