bd595851e2
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
87 lines
2.7 KiB
Rust
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(®istration).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(())
|
|
}
|
|
}
|