From 56d9022811f46e7035df345870d85995bc09ca6f Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Sat, 22 Mar 2025 00:11:41 +0800 Subject: [PATCH] touchpad: Show IC type and firmware version Example on Framework 13: ``` > framework_tool --version [...] Touchpad IC Type: 0274 Firmware Version: v0704 ``` Signed-off-by: Daniel Schaefer --- README.md | 1 + framework_lib/src/commandline/mod.rs | 5 +++ framework_lib/src/lib.rs | 2 + framework_lib/src/touchpad.rs | 65 ++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 framework_lib/src/touchpad.rs diff --git a/README.md b/README.md index 1c454543..01d2205e 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ see the [Support Matrices](support-matrices.md). - [x] PD - [x] ME (Only on Linux) - [x] Retimer + - [x] Touchpad (Linux and Windows) - [x] Get Expansion Card Firmware (Not on UEFI so far) - [x] HDMI Expansion Card (`--dp-hdmi-info`) - [x] DisplayPort Expansion Card (`--dp-hdmi-info`) diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 20d77a81..bd5302eb 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -50,6 +50,8 @@ use crate::power; use crate::smbios; use crate::smbios::ConfigDigit0; use crate::smbios::{dmidecode_string_val, get_smbios, is_framework}; +#[cfg(feature = "hidapi")] +use crate::touchpad::print_touchpad_fw_ver; #[cfg(feature = "uefi")] use crate::uefi::enable_page_break; use crate::util; @@ -474,6 +476,9 @@ fn print_versions(ec: &CrosEc) { } #[cfg(feature = "rusb")] let _ignore_err = check_camera_version(); + + #[cfg(feature = "hidapi")] + let _ignore_err = print_touchpad_fw_ver(); } fn print_esrt() { diff --git a/framework_lib/src/lib.rs b/framework_lib/src/lib.rs index a5c4e71d..50fa9b03 100644 --- a/framework_lib/src/lib.rs +++ b/framework_lib/src/lib.rs @@ -16,6 +16,8 @@ extern crate log; pub mod audio_card; #[cfg(feature = "rusb")] pub mod camera; +#[cfg(feature = "hidapi")] +pub mod touchpad; #[cfg(feature = "uefi")] #[macro_use] diff --git a/framework_lib/src/touchpad.rs b/framework_lib/src/touchpad.rs new file mode 100644 index 00000000..fe4be04d --- /dev/null +++ b/framework_lib/src/touchpad.rs @@ -0,0 +1,65 @@ +use hidapi::{HidApi, HidDevice, HidError}; + +pub const PIX_VID: u16 = 0x093A; +pub const PIX_REPORT_ID: u8 = 0x43; + +fn read_byte(device: &HidDevice, addr: u8) -> Result { + device.send_feature_report(&[PIX_REPORT_ID, addr, 0x10, 0])?; + + let mut buf = [0u8; 4]; + buf[0] = PIX_REPORT_ID; + + device.get_feature_report(&mut buf)?; + Ok(buf[3]) +} + +fn read_ver(device: &HidDevice) -> Result { + Ok(u16::from_le_bytes([ + read_byte(device, 0xb2)?, + read_byte(device, 0xb3)?, + ])) +} + +pub fn print_touchpad_fw_ver() -> Result<(), HidError> { + debug!("Looking for touchpad HID device"); + match HidApi::new() { + Ok(api) => { + for dev_info in api.device_list() { + let vid = dev_info.vendor_id(); + let pid = dev_info.product_id(); + let usage_page = dev_info.usage_page(); + + debug!( + " Found {:04X}:{:04X} (Usage Page {:04X})", + vid, pid, usage_page + ); + if vid != PIX_VID || (pid != 0x0274 && pid != 0x0239) { + debug!( + " Skipping VID:PID. Expected {:04X}:{:04X}/{:04X}", + PIX_VID, 0x0274, 0x0239 + ); + continue; + } + if usage_page != 0xFF00 { + debug!(" Skipping usage page. Expected {:04X}", 0xFF00); + continue; + } + + debug!(" Found matching touchpad HID device"); + let device = dev_info.open_device(&api).unwrap(); + + println!("Touchpad"); + println!(" IC Type: {:04X}", pid); + println!(" Firmware Version: v{:04X}", read_ver(&device)?); + // If we found one, there's no need to look for more + return Ok(()); + } + } + Err(e) => { + eprintln!("Failed to open hidapi. Error: {e}"); + return Err(e); + } + }; + + Ok(()) +}