This commit is contained in:
NGnius (Graham) 2024-05-07 20:22:23 -04:00
parent 10e1f8f44b
commit 56605fac67
4 changed files with 40 additions and 7 deletions

View file

@ -2,7 +2,7 @@ workspace = { members = ["ecplorer"] }
[package] [package]
name = "smokepatio" name = "smokepatio"
version = "0.1.0" version = "0.2.0"
edition = "2021" edition = "2021"
description = "Low-level hardware interfaces for Valve's Steam Deck" description = "Low-level hardware interfaces for Valve's Steam Deck"
authors = ["NGnius (Graham) <ngniusness@gmail.com>"] authors = ["NGnius (Graham) <ngniusness@gmail.com>"]

View file

@ -6,6 +6,8 @@ pub trait SetValue<S, RV = u8> {
pub trait ControllerSet<S, RV = u8>: embedded_io::ErrorType { pub trait ControllerSet<S, RV = u8>: embedded_io::ErrorType {
fn set<V: SetValue<S, RV>>(&mut self, value: V) -> Result<(), Self::Error>; fn set<V: SetValue<S, RV>>(&mut self, value: V) -> Result<(), Self::Error>;
fn set_many<V: SetValue<S, RV>>(&mut self, _values: &[V]) -> Result<usize, Self::Error> { Ok(0) }
} }
pub trait GetValue<S, RV = u8> { pub trait GetValue<S, RV = u8> {
@ -16,6 +18,8 @@ pub trait GetValue<S, RV = u8> {
pub trait ControllerGet<S, RV = u8>: embedded_io::ErrorType { pub trait ControllerGet<S, RV = u8>: embedded_io::ErrorType {
fn get<V: GetValue<S, RV>>(&mut self) -> Result<V, Self::Error>; fn get<V: GetValue<S, RV>>(&mut self) -> Result<V, Self::Error>;
fn get_many<V: GetValue<S, RV>>(&mut self, _buffer: &[V]) -> Result<usize, Self::Error> { Ok(0) }
} }
/// Size of values to write and read from ports. /// Size of values to write and read from ports.
@ -35,6 +39,10 @@ const MAX_WAIT_CHECKS: u16 = 0x07ff;
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
const MAX_WAIT_CHECKS: u16 = 0x7fff; const MAX_WAIT_CHECKS: u16 = 0x7fff;
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/12_ACPI_Embedded_Controller_Interface_Specification/embedded-controller-command-set.html
const WRITE_CMD: u8 = 0x81;
const READ_CMD: u8 = 0x80;
#[derive(Debug)] #[derive(Debug)]
pub struct EmbeddedController { pub struct EmbeddedController {
data_address: u16, data_address: u16,
@ -44,7 +52,7 @@ pub struct EmbeddedController {
} }
impl EmbeddedController { impl EmbeddedController {
pub fn new(data_addr: u16, cmd_addr: u16) -> Self { pub const fn new(data_addr: u16, cmd_addr: u16) -> Self {
Self { Self {
data_address: data_addr, data_address: data_addr,
cmd_address: cmd_addr, cmd_address: cmd_addr,
@ -53,9 +61,9 @@ impl EmbeddedController {
} }
} }
fn request_if_not_already(&mut self) { fn request_write_if_not_already(&mut self) {
if self.cmd_requested == 0 { if self.cmd_requested == 0 {
super::ports::outb(self.cmd_address, 0x81); super::ports::outb(self.cmd_address, WRITE_CMD);
self.cmd_requested = 1; self.cmd_requested = 1;
} else { } else {
self.cmd_requested += 1; self.cmd_requested += 1;
@ -70,6 +78,15 @@ impl EmbeddedController {
} }
} }
fn request_read_if_not_already(&mut self) {
if self.cmd_requested == 0 {
super::ports::outb(self.cmd_address, READ_CMD);
self.cmd_requested = 1;
} else {
self.cmd_requested += 1;
}
}
fn wait_for_read_ready(&mut self) { fn wait_for_read_ready(&mut self) {
use embedded_io::ReadReady; use embedded_io::ReadReady;
while !self.read_ready().unwrap() { while !self.read_ready().unwrap() {
@ -85,6 +102,13 @@ impl EmbeddedController {
self.write(&[value]).unwrap(); self.write(&[value]).unwrap();
} }
pub fn set_many(&mut self, setting: u16, values: &[u8]) {
use embedded_io::Write;
self.write(&[setting as u8]).unwrap();
self.cmd_requested = 1; // don't re-request, but still wait
self.write(values).unwrap();
}
pub fn get(&mut self, setting: u16) -> u8 { pub fn get(&mut self, setting: u16) -> u8 {
use embedded_io::{Read, Write}; use embedded_io::{Read, Write};
self.write(&[setting as u8]).unwrap(); self.write(&[setting as u8]).unwrap();
@ -94,6 +118,13 @@ impl EmbeddedController {
buf[0] buf[0]
} }
pub fn get_many(&mut self, setting: u16, buffer: &mut [u8]) -> usize {
use embedded_io::{Read, Write};
self.write(&[setting as u8]).unwrap();
self.cmd_requested = 1; // don't re-request, but still wait
self.read(buffer).unwrap()
}
pub fn set_value_size(&mut self, size: ValueSize) { pub fn set_value_size(&mut self, size: ValueSize) {
self.rw_size = size; self.rw_size = size;
} }
@ -150,7 +181,7 @@ impl embedded_io::Write for EmbeddedController {
impl embedded_io::WriteReady for EmbeddedController { impl embedded_io::WriteReady for EmbeddedController {
fn write_ready(&mut self) -> Result<bool, Self::Error> { fn write_ready(&mut self) -> Result<bool, Self::Error> {
self.request_if_not_already(); self.request_write_if_not_already();
let ready = let ready =
super::ports::inb(self.cmd_address) & 2 == 0 || self.cmd_requested == MAX_WAIT_CHECKS; super::ports::inb(self.cmd_address) & 2 == 0 || self.cmd_requested == MAX_WAIT_CHECKS;
if ready { if ready {
@ -199,7 +230,7 @@ impl embedded_io::Read for EmbeddedController {
impl embedded_io::ReadReady for EmbeddedController { impl embedded_io::ReadReady for EmbeddedController {
fn read_ready(&mut self) -> Result<bool, Self::Error> { fn read_ready(&mut self) -> Result<bool, Self::Error> {
self.request_if_not_already(); self.request_read_if_not_already();
let ready = let ready =
super::ports::inb(self.cmd_address) & 1 != 0 || self.cmd_requested == MAX_WAIT_CHECKS; super::ports::inb(self.cmd_address) & 1 != 0 || self.cmd_requested == MAX_WAIT_CHECKS;
if ready { if ready {

View file

@ -90,6 +90,8 @@ impl SetValue<Setting> for BreathingColour {
pub enum StaticColour { pub enum StaticColour {
/// No colour (overrides other set colours) /// No colour (overrides other set colours)
Off = 0x00, Off = 0x00,
/// No colour (overrides other set colours)
Disabled = 0x80,
/// White LED enable /// White LED enable
White = 0x81, White = 0x81,
/// Red LED enable /// Red LED enable

View file

@ -7,7 +7,7 @@ pub mod raw_io;
pub struct UnnamedPowerEC(super::EmbeddedController); pub struct UnnamedPowerEC(super::EmbeddedController);
impl UnnamedPowerEC { impl UnnamedPowerEC {
pub fn new() -> Self { pub const fn new() -> Self {
Self(super::EmbeddedController::new(0x68, 0x6c)) Self(super::EmbeddedController::new(0x68, 0x6c))
} }