diff --git a/EXAMPLES.md b/EXAMPLES.md index 8cf74a0d..420d06e8 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -380,6 +380,26 @@ Positions: Pos 4: GenericC ``` +### Checking board ID + +Most inputdeck checking is implemented by Board ID. To read those directly for +debugging low level issues, use the `--boardid` command. +This host command was added recently is not available on every system yet. + +``` +# Example on Framework Laptop 13 +# Touchpad Board ID is only present on Laptop 12 +# dGPU Board IDs are only present on Laptop 16 +> framework_tool --boardid +Board IDs + Mainboard: Ok(Some(6)) + PowerButton: Err(Response(InvalidResponse)) + Touchpad: Ok(Some(7)) + AudioBoard: Ok(Some(7)) + dGPU0: Err(Response(InvalidCommand)) + dGPU1: Err(Response(InvalidCommand)) +``` + ## Check temperatures and fan speed ``` diff --git a/framework_lib/src/chromium_ec/command.rs b/framework_lib/src/chromium_ec/command.rs index 696c1529..07bf4d36 100644 --- a/framework_lib/src/chromium_ec/command.rs +++ b/framework_lib/src/chromium_ec/command.rs @@ -110,6 +110,8 @@ pub enum EcCommands { GetGpuPcie = 0x3E1E, /// Set gpu bay serial and program structure ProgramGpuEeprom = 0x3E1F, + /// Read board ID of specific ADC channel + ReadBoardId = 0x3E26, } pub trait EcRequest { diff --git a/framework_lib/src/chromium_ec/commands.rs b/framework_lib/src/chromium_ec/commands.rs index e5798069..2a22b891 100644 --- a/framework_lib/src/chromium_ec/commands.rs +++ b/framework_lib/src/chromium_ec/commands.rs @@ -1658,3 +1658,39 @@ impl EcRequest for EcRequestSetGpuSerial { EcCommands::ProgramGpuEeprom } } + +#[repr(u8)] +#[derive(Debug, Clone, Copy)] +pub enum BoardIdType { + /// Mainboard - any system + Mainboard = 0, + /// Power button board - Framework 12 + PowerButtonBoard = 1, + /// Touchpad - Framework 12, 13, 16 + Touchpad = 2, + /// Audio Board - Framework 12, 13 + AudioBoard = 3, + /// dGPU board - Framework 16 + DGpu0 = 4, + /// dGPU board - Framework 16 + DGpu1 = 5, +} + +#[repr(C, packed)] +pub struct EcRequestReadBoardId { + /// See BoardIdType + pub board_id_type: u8, +} + +#[repr(C, packed)] +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct EcResponseReadBoardId { + /// Board ID: -1 invalid, 0–14 valid, 15 not present + pub board_id: i8, +} + +impl EcRequest for EcRequestReadBoardId { + fn command_id() -> EcCommands { + EcCommands::ReadBoardId + } +} diff --git a/framework_lib/src/chromium_ec/mod.rs b/framework_lib/src/chromium_ec/mod.rs index 94997bab..4fae5bbc 100644 --- a/framework_lib/src/chromium_ec/mod.rs +++ b/framework_lib/src/chromium_ec/mod.rs @@ -1740,6 +1740,22 @@ impl CrosEc { Ok(()) } + pub fn read_board_id_hc(&self, board_id_type: BoardIdType) -> EcResult> { + let res = EcRequestReadBoardId { + board_id_type: board_id_type as u8, + } + .send_command(self)?; + match res.board_id { + -1 => Err(EcError::DeviceError(format!( + "Failed to read Board ID {:?}", + board_id_type + ))), + 15 => Ok(None), + 0..=14 => Ok(Some(res.board_id as u8)), + n => Err(EcError::DeviceError(format!("Invalid Board ID {}", n))), + } + } + pub fn get_uptime_info(&self) -> EcResult<()> { let res = EcRequestGetUptimeInfo {}.send_command(self)?; let t_since_boot = Duration::from_millis(res.time_since_ec_boot.into()); diff --git a/framework_lib/src/commandline/clap_std.rs b/framework_lib/src/commandline/clap_std.rs index a2727903..3952675e 100644 --- a/framework_lib/src/commandline/clap_std.rs +++ b/framework_lib/src/commandline/clap_std.rs @@ -273,6 +273,10 @@ struct ClapCli { #[arg(long)] test_retimer: bool, + /// Print all board IDs + #[arg(long)] + boardid: bool, + /// Force execution of an unsafe command - may render your hardware unbootable! #[arg(long, short)] force: bool, @@ -472,6 +476,7 @@ pub fn parse(args: &[String]) -> Cli { pd_ports, test: args.test, test_retimer: args.test_retimer, + boardid: args.boardid, dry_run: args.dry_run, force: args.force, // TODO: Set help. Not very important because Clap handles this by itself diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 98de02b5..b7924778 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -35,6 +35,7 @@ use crate::ccgx::device::{FwMode, PdController, PdPort}; use crate::ccgx::hid::{check_ccg_fw_version, find_devices, DP_CARD_PID, HDMI_CARD_PID}; use crate::ccgx::{self, MainPdVersions, PdVersions, SiliconId::*}; use crate::chromium_ec; +use crate::chromium_ec::commands::BoardIdType; use crate::chromium_ec::commands::DeckStateMode; use crate::chromium_ec::commands::FpLedBrightnessLevel; use crate::chromium_ec::commands::RebootEcCmd; @@ -192,6 +193,7 @@ pub struct Cli { pub driver: Option, pub test: bool, pub test_retimer: bool, + pub boardid: bool, pub dry_run: bool, pub force: bool, pub intrusion: bool, @@ -279,6 +281,7 @@ pub fn parse(args: &[String]) -> Cli { driver: cli.driver, test: cli.test, test_retimer: cli.test_retimer, + boardid: cli.boardid, dry_run: cli.dry_run, // force intrusion: cli.intrusion, @@ -1487,6 +1490,8 @@ pub fn run_with_args(args: &Cli, _allupdate: bool) -> i32 { if let Err(err) = selftest_retimer(&ec) { println!(" Failed: {:?}", err); } + } else if args.boardid { + print_board_ids(&ec); } else if args.power { return power::get_and_print_power_info(&ec); } else if args.thermal { @@ -1850,6 +1855,34 @@ fn hash(data: &[u8]) { util::print_buffer(sha512); } +fn print_board_ids(ec: &CrosEc) { + println!("Board IDs"); + println!( + " Mainboard: {:?}", + ec.read_board_id_hc(BoardIdType::Mainboard) + ); + println!( + " PowerButton: {:?}", + ec.read_board_id_hc(BoardIdType::PowerButtonBoard) + ); + println!( + " Touchpad: {:?}", + ec.read_board_id_hc(BoardIdType::Touchpad) + ); + println!( + " AudioBoard: {:?}", + ec.read_board_id_hc(BoardIdType::AudioBoard) + ); + println!( + " dGPU0: {:?}", + ec.read_board_id_hc(BoardIdType::DGpu0) + ); + println!( + " dGPU1: {:?}", + ec.read_board_id_hc(BoardIdType::DGpu1) + ); +} + fn selftest(ec: &CrosEc) -> Option<()> { if let Some(platform) = smbios::get_platform() { println!(" SMBIOS Platform: {:?}", platform); diff --git a/framework_lib/src/commandline/uefi.rs b/framework_lib/src/commandline/uefi.rs index cb2b4c5d..58490c71 100644 --- a/framework_lib/src/commandline/uefi.rs +++ b/framework_lib/src/commandline/uefi.rs @@ -87,6 +87,7 @@ pub fn parse(args: &[String]) -> Cli { pd_ports: None, test: false, test_retimer: false, + boardid: false, dry_run: false, force: false, help: false, @@ -511,6 +512,9 @@ pub fn parse(args: &[String]) -> Cli { } else if arg == "-t" || arg == "--test-retimer" { cli.test_retimer = true; found_an_option = true; + } else if arg == "--boardid" { + cli.boardid = true; + found_an_option = true; } else if arg == "-f" || arg == "--force" { cli.force = true; found_an_option = true;