Files
RedBear-OS/drivers/input/intel-thc-hidd/src/quicki2c.rs
T
Red Bear OS bd595851e2 base: apply Red Bear patches on latest upstream/main
251 files: init, acpid, ipcd, netcfg, ihdgd, virtio-gpud, scheme-utils,
inputd, block driver, ptyd, ramfs, randd, initfs bootstrap, path deps,
version +rb0.3.1, author attribution
2026-07-11 11:39:24 +03:00

87 lines
2.7 KiB
Rust

use std::fs::OpenOptions;
use std::io::Write;
use anyhow::{Context, Result};
use i2c_interface::{I2cAdapterRegistration, I2cTransferSegment};
use crate::thc::ThcController;
const QUICKI2C_OPCODE_WRITE: u32 = 0x1;
const QUICKI2C_OPCODE_READ: u32 = 0x2;
pub struct QuickI2cTransport {
controller: ThcController,
slave_address: u16,
}
impl QuickI2cTransport {
pub fn new(controller: ThcController, slave_address: u16) -> Self {
Self {
controller,
slave_address,
}
}
pub fn prime_controller(&self) {
self.controller.initialize_quicki2c_mode();
}
pub fn emulate_transfer(&self, segments: &[I2cTransferSegment]) {
for segment in segments {
match &segment.op {
i2c_interface::I2cTransferOp::Write(data) => {
self.controller.program_subip_transaction(
QUICKI2C_OPCODE_WRITE,
segment.address,
data.len(),
);
for (index, chunk) in data.chunks(4).enumerate() {
let mut word = [0_u8; 4];
word[..chunk.len()].copy_from_slice(chunk);
self.controller
.write_subip_data(index * 4, u32::from_le_bytes(word));
}
}
i2c_interface::I2cTransferOp::Read(len) => {
self.controller.program_subip_transaction(
QUICKI2C_OPCODE_READ,
segment.address,
*len,
);
let _ = self.controller.read_subip_data(0);
}
}
}
}
pub fn status(&self) -> u32 {
self.controller.status()
}
pub fn register_with_i2cd(
&self,
acpi_companion: Option<&str>,
override_address: Option<u16>,
) -> Result<()> {
let registration = I2cAdapterRegistration {
name: "intel-thc-quicki2c".to_string(),
description: format!(
"Intel THC QuickI2C adapter for slave {:04x}",
self.slave_address
),
acpi_companion: acpi_companion.map(str::to_owned),
slave_address_override: override_address,
};
let payload =
ron::to_string(&registration).context("failed to serialize i2cd registration")?;
let mut file = OpenOptions::new()
.write(true)
.open("/scheme/i2c/register")
.context("failed to open /scheme/i2c/register")?;
file.write_all(payload.as_bytes())
.context("failed to write i2cd adapter registration")?;
Ok(())
}
}