From 97c0a00be487b765beff084498ff0031f0fc4e8e Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 5 May 2026 09:33:14 +0800 Subject: [PATCH] Allow reading touchscreen version on Laptop 13 Signed-off-by: Daniel Schaefer --- EXAMPLES.md | 11 ++++- framework_lib/src/commandline/mod.rs | 7 ++- framework_lib/src/touchscreen.rs | 72 ++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/EXAMPLES.md b/EXAMPLES.md index 7b659f77..05ddfb00 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -199,14 +199,23 @@ Laptop Webcam Module (2nd Gen) Firmware Version: 1.1.1 ``` -### Touchscreen (Laptop 12) +### Touchscreen (Laptop 12, Laptop 13) ``` +# Laptop 12 > framework_tool --versions [...] Touchscreen Firmware Version: v7.0.0.5.0.0.0.0 Protocols: USI +[...] + +# Laptop 13 +> framework_tool --versions +[...] + Touchscreen + Firmware Version: v1409 +[...] ``` ### Stylus (Laptop 12) diff --git a/framework_lib/src/commandline/mod.rs b/framework_lib/src/commandline/mod.rs index 3f9618c8..9ffc5d0b 100644 --- a/framework_lib/src/commandline/mod.rs +++ b/framework_lib/src/commandline/mod.rs @@ -805,8 +805,11 @@ fn print_versions(ec: &CrosEc) { let _ignore_err = print_touchpad_fw_ver(); #[cfg(feature = "hidapi")] - if let Some(Platform::Framework12IntelGen13) = smbios::get_platform() { - let _ignore_err = touchscreen::print_fw_ver(); + { + let _ignore_err = touchscreen::print_himax_fw_ver(); + if let Some(Platform::Framework12IntelGen13) = smbios::get_platform() { + let _ignore_err = touchscreen::print_fw_ver(); + } } #[cfg(feature = "hidapi")] print_dp_hdmi_details(false); diff --git a/framework_lib/src/touchscreen.rs b/framework_lib/src/touchscreen.rs index de74c9f9..342684d6 100644 --- a/framework_lib/src/touchscreen.rs +++ b/framework_lib/src/touchscreen.rs @@ -5,6 +5,8 @@ use crate::touchscreen_win; pub const ILI_VID: u16 = 0x222A; pub const ILI_PID: u16 = 0x5539; +pub const HX_VID: u16 = 0x3558; +pub const HX_PID: u16 = 0x14FD; const VENDOR_USAGE_PAGE: u16 = 0xFF00; pub const USI_BITMAP: u8 = 1 << 1; pub const MPP_BITMAP: u8 = 1 << 2; @@ -12,6 +14,12 @@ pub const MPP_BITMAP: u8 = 1 << 2; const REPORT_ID_FIRMWARE: u8 = 0x27; const REPORT_ID_USI_VER: u8 = 0x28; +const HX_REPORT_ID_CFG: u8 = 0x05; +const HX_CFG_BUF_LEN: usize = 256; +const HX_OFF_CID: usize = 52; +const HX_OFF_VID: usize = 130; +const HX_OFF_PID: usize = 132; + struct HidapiTouchScreen { device: HidDevice, } @@ -248,6 +256,10 @@ pub fn print_fw_ver() -> Option<()> { } } + if print_himax_fw_ver().is_some() { + return Some(()); + } + #[cfg(target_os = "windows")] let device = touchscreen_win::NativeWinTouchScreen::open_device(VENDOR_USAGE_PAGE, 0)?; #[cfg(not(target_os = "windows"))] @@ -256,6 +268,66 @@ pub fn print_fw_ver() -> Option<()> { device.check_fw_version() } +pub fn print_himax_fw_ver() -> Option<()> { + let api = match HidApi::new() { + Ok(api) => api, + Err(e) => { + error!("Failed to open hidapi. Error: {e}"); + return None; + } + }; + + let dev_info = api + .device_list() + .find(|d| d.vendor_id() == HX_VID && d.product_id() == HX_PID)?; + debug!( + "Found Himax touchscreen {:04X}:{:04X} at {:?}", + dev_info.vendor_id(), + dev_info.product_id(), + dev_info.path() + ); + + let device = match dev_info.open_device(&api) { + Ok(d) => d, + Err(e) => { + error!("Failed to open Himax touchscreen: {e}"); + return None; + } + }; + + let mut buf = [0u8; HX_CFG_BUF_LEN]; + buf[0] = HX_REPORT_ID_CFG; + let n = match device.get_feature_report(&mut buf) { + Ok(n) => n, + Err(e) => { + error!("Himax get_feature_report(0x05) failed: {e}"); + return None; + } + }; + debug!(" Read {} bytes from Himax Cfg report", n); + + // Data is everything after the leading report-ID byte. + let data = &buf[1..n.max(1)]; + if data.len() < HX_OFF_PID + 2 { + error!( + "Himax Cfg report too short: {} bytes (need {})", + data.len(), + HX_OFF_PID + 2 + ); + return None; + } + let cid = u16::from_be_bytes([data[HX_OFF_CID], data[HX_OFF_CID + 1]]); + let vid = u16::from_be_bytes([data[HX_OFF_VID], data[HX_OFF_VID + 1]]); + let pid = u16::from_be_bytes([data[HX_OFF_PID], data[HX_OFF_PID + 1]]); + + println!("Touchscreen"); + debug!(" Vendor ID: {:04X}", vid); + debug!(" Product ID: {:04X}", pid); + println!(" Firmware Version: v{:04X}", cid); + + Some(()) +} + pub fn enable_touch(enable: bool) -> Option<()> { #[cfg(target_os = "windows")] let device = touchscreen_win::NativeWinTouchScreen::open_device(VENDOR_USAGE_PAGE, 0)?;