From 71823ec678c77d1e6cac10ecbc28e6b47cb1183c Mon Sep 17 00:00:00 2001 From: Kieran Levin Date: Tue, 16 Dec 2025 03:43:36 -0800 Subject: [PATCH] turn on bay power when programming 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/command.rs | 1 + framework_lib/src/chromium_ec/commands.rs | 12 ++++++ framework_lib/src/chromium_ec/mod.rs | 46 +++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index f1d994a2..98eb3ad5 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 a7782146..94f162bd 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 40295c06..02b8a202 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -1323,6 +1323,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; @@ -1358,6 +1382,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(()) } @@ -1564,6 +1597,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] };