Skip to content

Commit d2962ce

Browse files
committed
freebsd: Use hidraw ioctls to get touchpad firmware version
Signed-off-by: Daniel Schaefer <dhs@frame.work>
1 parent 8f718d1 commit d2962ce

2 files changed

Lines changed: 108 additions & 1 deletion

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,8 @@ Keyboard backlight: 0%
359359
## FreeBSD
360360

361361
```
362-
sudo pkg install hidapi
362+
# Install pre-requisites
363+
sudo pkg install rust hidapi
363364
364365
# Build the library and tool
365366
cargo build --no-default-features --features freebsd

framework_lib/src/touchpad.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,112 @@
11
use hidapi::{HidApi, HidDevice, HidError};
2+
#[cfg(target_os = "freebsd")]
3+
use nix::{ioctl_read, ioctl_read_buf, ioctl_readwrite, ioctl_readwrite_buf, ioctl_write_buf};
4+
#[cfg(target_os = "freebsd")]
5+
use std::fs::OpenOptions;
6+
use std::io::{Read, Write};
7+
#[cfg(target_os = "freebsd")]
8+
use std::os::fd::AsRawFd;
9+
#[cfg(target_os = "freebsd")]
10+
use std::os::unix::fs::OpenOptionsExt;
11+
12+
#[cfg(target_os = "freebsd")]
13+
#[repr(C)]
14+
pub struct HidIocGrInfo {
15+
bustype: u32,
16+
vendor: u16,
17+
product: u16,
18+
}
19+
20+
#[cfg(target_os = "freebsd")]
21+
//ioctl_readwrite!(hidraw_get_report_desc, b'U', 21, HidrawGetReportDesc);
22+
//ioctl_readwrite!(hidraw_get_report, b'U', 23, HidrawGetReport);
23+
//ioctl_write!(hidraw_set_report, b'U', 24, HidrawSetReport);
24+
ioctl_read!(hidiocgrawninfo, b'U', 32, HidIocGrInfo);
25+
//ioctl_readwrite!(hidiocgrawnname, b'U', 33, HidIocGrName);
26+
ioctl_read_buf!(hid_raw_name, b'U', 33, u8);
27+
ioctl_write_buf!(hid_set_feature, b'U', 35, u8);
28+
ioctl_readwrite_buf!(hid_get_feature, b'U', 36, u8);
229

330
pub const PIX_VID: u16 = 0x093A;
431
pub const PIX_REPORT_ID: u8 = 0x43;
532

33+
#[cfg(target_os = "freebsd")]
34+
pub fn print_touchpad_fw_ver() -> Option<()> {
35+
println!("Touchpad");
36+
let path = "/dev/hidraw2";
37+
let mut file = OpenOptions::new()
38+
.read(true)
39+
.write(true)
40+
.custom_flags(libc::O_NONBLOCK)
41+
.open(path)
42+
.unwrap();
43+
44+
let mut desc = HidIocGrInfo {
45+
bustype: 0,
46+
vendor: 0,
47+
product: 0,
48+
};
49+
unsafe {
50+
let fd = file.as_raw_fd();
51+
if let Err(err) = hidiocgrawninfo(fd, &mut desc) {
52+
error!("Failed to access hidraw at {}: {:?}", path, err);
53+
return None;
54+
}
55+
debug!(
56+
"Found {:04X}:{:04X} Bustype: {:04X}",
57+
desc.vendor, desc.product, desc.bustype
58+
);
59+
// TODO: Iterate over all /dev/hidraw* devices and find the right one
60+
// if vid != PIX_VID || (pid != 0x0274 && pid != 0x0239) {
61+
println!(" IC Type: {:04X}", desc.product);
62+
63+
let mut buf = [0u8; 255];
64+
if let Err(err) = hid_raw_name(fd, &mut buf) {
65+
error!("Failed to access hidraw at {}: {:?}", path, err);
66+
return None;
67+
}
68+
let name = std::str::from_utf8(&buf)
69+
.unwrap()
70+
.trim_end_matches(char::from(0));
71+
debug!(" Name: {}", name);
72+
73+
println!(" Firmware Version: v{:04X}", read_ver(fd)?);
74+
75+
read_byte(fd, 0x2b);
76+
}
77+
78+
Some(())
79+
}
80+
81+
fn read_byte(fd: i32, addr: u8) -> Option<u8> {
82+
unsafe {
83+
let mut buf: [u8; 4] = [PIX_REPORT_ID, addr, 0x10, 0];
84+
if let Err(err) = hid_set_feature(fd, &mut buf) {
85+
error!("Failed to hid_set_feature: {:?}", err);
86+
return None;
87+
}
88+
//device.send_feature_report(&[PIX_REPORT_ID, addr, 0x10, 0])?;
89+
90+
let mut buf = [0u8; 4];
91+
buf[0] = PIX_REPORT_ID;
92+
93+
if let Err(err) = hid_get_feature(fd, &mut buf) {
94+
error!("Failed to hid_get_feature: {:?}", err);
95+
return None;
96+
}
97+
Some(buf[3])
98+
}
99+
}
100+
101+
#[cfg(target_os = "freebsd")]
102+
fn read_ver(device: i32) -> Option<u16> {
103+
Some(u16::from_le_bytes([
104+
read_byte(device, 0xb2)?,
105+
read_byte(device, 0xb3)?,
106+
]))
107+
}
108+
109+
#[cfg(not(target_os = "freebsd"))]
6110
fn read_byte(device: &HidDevice, addr: u8) -> Result<u8, HidError> {
7111
device.send_feature_report(&[PIX_REPORT_ID, addr, 0x10, 0])?;
8112

@@ -13,13 +117,15 @@ fn read_byte(device: &HidDevice, addr: u8) -> Result<u8, HidError> {
13117
Ok(buf[3])
14118
}
15119

120+
#[cfg(not(target_os = "freebsd"))]
16121
fn read_ver(device: &HidDevice) -> Result<u16, HidError> {
17122
Ok(u16::from_le_bytes([
18123
read_byte(device, 0xb2)?,
19124
read_byte(device, 0xb3)?,
20125
]))
21126
}
22127

128+
#[cfg(not(target_os = "freebsd"))]
23129
pub fn print_touchpad_fw_ver() -> Result<(), HidError> {
24130
debug!("Looking for touchpad HID device");
25131
match HidApi::new() {

0 commit comments

Comments
 (0)