Skip to content

Commit 5b7ac43

Browse files
committed
Add host command to control retimer status
Not normally used, only during firmware update and compliance testing. Adding it for debug purposes only. Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 97b0708 commit 5b7ac43

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

framework_lib/src/chromium_ec/command.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ pub enum EcCommands {
7272
ChassisOpenCheck = 0x3E0F,
7373
/// Get information about historical chassis open/close (intrusion) information
7474
ChassisIntrusion = 0x3E09,
75+
/// Control and check retimer modes (firmware update and compliance)
76+
RetimerControl = 0x3E0A,
7577

7678
/// Not used by this library
7779
AcpiNotify = 0xE10,

framework_lib/src/chromium_ec/commands.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,39 @@ impl EcRequest<EcResponseChassisIntrusionControl> for EcRequestChassisIntrusionC
10221022
}
10231023
}
10241024

1025+
#[repr(u8)]
1026+
pub enum RetimerControlMode {
1027+
/// AMD and Intel
1028+
EntryFwUpdateMode = 0x01,
1029+
/// AMD and Intel
1030+
ExitFwUpdateMode = 0x02,
1031+
/// Intel only
1032+
EnableComplianceMode = 0x04,
1033+
/// Intel only
1034+
DisableComplianceMode = 0x08,
1035+
/// Check if in FwUpdateMode
1036+
CheckStatus = 0x80,
1037+
}
1038+
1039+
#[repr(C, packed)]
1040+
pub struct EcRequestRetimerControl {
1041+
/// 0 (right) or 1 (left)
1042+
pub controller: u8,
1043+
/// See RetimerControlMode
1044+
pub mode: u8,
1045+
}
1046+
1047+
#[repr(C, packed)]
1048+
pub struct EcResponseRetimerControlStatus {
1049+
pub status: u8,
1050+
}
1051+
1052+
impl EcRequest<EcResponseRetimerControlStatus> for EcRequestRetimerControl {
1053+
fn command_id() -> EcCommands {
1054+
EcCommands::RetimerControl
1055+
}
1056+
}
1057+
10251058
#[repr(C, packed)]
10261059
pub struct EcRequestReadPdVersionV0 {}
10271060

framework_lib/src/chromium_ec/mod.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,67 @@ impl CrosEc {
547547
})
548548
}
549549

550+
/// Check if the retimer is in firmware update mode
551+
///
552+
/// This is normally false. Update mode is used to enable the retimer power even when no device
553+
/// is attached.
554+
pub fn retimer_in_fwupd_mode(&self, retimer: u8) -> EcResult<bool> {
555+
let status = EcRequestRetimerControl {
556+
controller: retimer,
557+
mode: RetimerControlMode::CheckStatus as u8,
558+
}
559+
.send_command(self)?;
560+
561+
Ok(status.status == 0x01)
562+
}
563+
564+
/// Enable or disable retimer update mode
565+
///
566+
/// Check for success and returns Err if not successful
567+
pub fn retimer_enable_fwupd(&self, retimer: u8, enable: bool) -> EcResult<()> {
568+
if self.retimer_in_fwupd_mode(retimer)? == enable {
569+
info!("Retimer update mode already: {:?}", enable);
570+
return Ok(());
571+
}
572+
EcRequestRetimerControl {
573+
controller: retimer,
574+
mode: if enable {
575+
RetimerControlMode::EntryFwUpdateMode as u8
576+
} else {
577+
RetimerControlMode::ExitFwUpdateMode as u8
578+
},
579+
}
580+
.send_command(self)?;
581+
582+
// Wait half a second to let it enter the new mode
583+
os_specific::sleep(500_000);
584+
585+
if self.retimer_in_fwupd_mode(retimer).unwrap() != enable {
586+
error!("Failed to set retimer update mode to: {}", enable);
587+
return Err(EcError::DeviceError(format!(
588+
"Failed to set retimer update mode to: {}",
589+
enable
590+
)));
591+
}
592+
Ok(())
593+
}
594+
595+
/// Enable or disable retimer Thunderbolt compliance mode (Intel only)
596+
///
597+
/// Cannot check for success
598+
pub fn retimer_enable_compliance(&self, retimer: u8, enable: bool) -> EcResult<()> {
599+
EcRequestRetimerControl {
600+
controller: retimer,
601+
mode: if enable {
602+
RetimerControlMode::EnableComplianceMode as u8
603+
} else {
604+
RetimerControlMode::DisableComplianceMode as u8
605+
},
606+
}
607+
.send_command(self)?;
608+
Ok(())
609+
}
610+
550611
pub fn get_input_deck_status(&self) -> EcResult<InputDeckStatus> {
551612
let status = EcRequestDeckState {
552613
mode: DeckStateMode::ReadOnly,

0 commit comments

Comments
 (0)