Add set_off_screen ioctl
This commit is contained in:
79
src/main.rs
Normal file
79
src/main.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use clap::Parser;
|
||||
use eyre::{Context, ensure, eyre};
|
||||
use nix::ioctl_write_ptr;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::Read,
|
||||
os::fd::AsRawFd,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Opt {
|
||||
/// Path to the image-blob.
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
const SCREEN_W: usize = 1404;
|
||||
const SCREEN_H: usize = 1872;
|
||||
|
||||
const BITS_PER_PIXEL: usize = 4;
|
||||
const FILE_SIZE: usize = SCREEN_W * SCREEN_H * BITS_PER_PIXEL / 8;
|
||||
|
||||
// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
|
||||
// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
|
||||
// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
|
||||
// #define DRM_IOCTL_ROCKCHIP_EBC_OFF_SCREEN DRM_IOWR(DRM_COMMAND_BASE + 0x01, struct drm_rockchip_ebc_off_screen)
|
||||
|
||||
#[repr(C)]
|
||||
struct DrmRockchipEbcOffScreen {
|
||||
info1: u64,
|
||||
ptr_screen_content: *const u8,
|
||||
}
|
||||
|
||||
const DRM_IOCTL_BASE: u8 = b'd';
|
||||
const DRM_COMMAND_BASE: u8 = 0x40;
|
||||
const ROCKCHIP_EBC_FILE: &str = "/dev/dri/by-path/platform-fdec0000.ebc-card";
|
||||
|
||||
ioctl_write_ptr!(
|
||||
set_off_screen,
|
||||
DRM_IOCTL_BASE,
|
||||
DRM_COMMAND_BASE + 1,
|
||||
DrmRockchipEbcOffScreen
|
||||
);
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
let opt = Opt::parse();
|
||||
color_eyre::install()?;
|
||||
|
||||
let image =
|
||||
read_file(&opt.path).wrap_err_with(|| eyre!("Failed to read file at {:?}", opt.path))?;
|
||||
|
||||
let set_off_screen_data = DrmRockchipEbcOffScreen {
|
||||
info1: 0, // TODO: what is this?
|
||||
ptr_screen_content: image.as_ptr(),
|
||||
};
|
||||
|
||||
let driver_file = File::options()
|
||||
.write(true)
|
||||
.open(ROCKCHIP_EBC_FILE)
|
||||
.wrap_err_with(|| eyre!("Failed to open rockchip ebc file at {ROCKCHIP_EBC_FILE:?}"))?;
|
||||
|
||||
unsafe { set_off_screen(driver_file.as_raw_fd(), &set_off_screen_data) }
|
||||
.wrap_err("ioctl error")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_file(path: &Path) -> eyre::Result<Vec<u8>> {
|
||||
let mut file = File::open(path)?;
|
||||
let mut buf = vec![0u8; FILE_SIZE];
|
||||
file.read_exact(&mut buf[..])
|
||||
.wrap_err_with(|| eyre!("Expected a raw image file, of exactly {FILE_SIZE} bytes"))?;
|
||||
|
||||
// Try to read a single byte. If n != 0, it means the file was larger than FILE_SIZE
|
||||
let n = file.read(&mut [0u8])?;
|
||||
ensure!(n == 0, "File must be exacly {FILE_SIZE} bytes long");
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
Reference in New Issue
Block a user