From d0668c43bffb20aea47a37d383766730ddac23aa Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 9 Jan 2026 22:21:44 +0800 Subject: [PATCH 1/2] chromium_ec: Implement GpioSet Allow setting individual GPIOs. You need to be careful because the definitions can change between each platform and controlling some GPIOs can cause mainboard damaged if controlled in correctly. Co-Authored-by: Kieran Levin Signed-off-by: Daniel Schaefer --- framework_lib/src/chromium_ec/command.rs | 1 + framework_lib/src/chromium_ec/commands.rs | 12 ++++++++++++ framework_lib/src/chromium_ec/mod.rs | 13 +++++++++++++ 3 files changed, 26 insertions(+) diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index 56e51664..feb4fe7b 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -37,6 +37,7 @@ pub enum EcCommands { PwmGetDuty = 0x0026, SetTabletMode = 0x0031, AutoFanCtrl = 0x0052, + GpioSet = 0x0092, GpioGet = 0x0093, I2cPassthrough = 0x009e, ConsoleSnapshot = 0x0097, diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index 1984d46c..651f80a9 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -452,6 +452,18 @@ impl EcRequest<()> for EcRequestAutoFanCtrlV1 { } } +#[repr(C, packed)] +pub struct EcRequestGpioSetV0 { + pub name: [u8; 32], + pub value: u8, +} + +impl EcRequest<()> for EcRequestGpioSetV0 { + fn command_id() -> EcCommands { + EcCommands::GpioSet + } +} + #[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 fb59e08d..1137739b 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -1566,6 +1566,19 @@ impl CrosEc { .send_command(self) } + pub fn set_gpio(&self, name: &str, value: bool) -> EcResult<()> { + const MAX_LEN: usize = 32; + let mut request = EcRequestGpioSetV0 { + name: [0; MAX_LEN], + value: value as u8, + }; + + let end = MAX_LEN.min(name.len()); + request.name[..end].copy_from_slice(&name.as_bytes()[..end]); + + request.send_command(self)?; + Ok(()) + } pub fn get_gpio(&self, name: &str) -> EcResult { const MAX_LEN: usize = 32; let mut request = EcRequestGpioGetV0 { name: [0; MAX_LEN] }; From 541e27980d7528c1c075767d79e8394c38427515 Mon Sep 17 00:00:00 2001 From: Kieran Levin Date: Fri, 9 Jan 2026 22:23:20 +0800 Subject: [PATCH 2/2] turn on bay power when programming dGPU eeprom For fresh expansion bay modules that are unprogrammed, we need to turn on the power to program them if they are not preprogrammed with dummy values. Signed-off-by: Kieran Levin --- framework_lib/src/chromium_ec/mod.rs | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 1137739b..d49fc8c2 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -1325,6 +1325,30 @@ impl CrosEc { "Writing GPU EEPROM {}", if dry_run { " (DRY RUN)" } else { "" } ); + let mut force_power = false; + + let info = EcRequestExpansionBayStatus {}.send_command(self)?; + println!(" Enabled: {}", info.module_enabled()); + println!(" No fault: {}", !info.module_fault()); + println!(" Door closed: {}", info.hatch_switch_closed()); + + match info.expansion_bay_board() { + Ok(board) => println!(" Board: {:?}", board), + Err(err) => println!(" Board: {:?}", err), + } + + if let Ok(ExpansionBayBoard::DualInterposer) = info.expansion_bay_board() { + /* Force power to the GPU if we are writing the EEPROM */ + let res = self.set_gpio("gpu_3v_5v_en", true); + if let Err(err) = res { + println!(" Failed to set ALW power to GPU off {:?}", err); + return Err(err); + } + println!("Forcing Power to GPU"); + os_specific::sleep(100_000); + force_power = true; + } + // Need to program the EEPROM 32 bytes at a time. let chunk_size = 32; @@ -1360,6 +1384,15 @@ impl CrosEc { } } println!(); + + if force_power { + let res = self.set_gpio("gpu_3v_5v_en", false); + if let Err(err) = res { + println!(" Failed to set ALW power to GPU off {:?}", err); + return Err(err); + } + }; + Ok(()) }