diff --git a/Cargo.toml b/Cargo.toml index d9d5db2..5010776 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ workspace = { members = ["ecplorer"] } [package] name = "smokepatio" -version = "0.1.0" +version = "0.2.0" edition = "2021" description = "Low-level hardware interfaces for Valve's Steam Deck" authors = ["NGnius (Graham) "] diff --git a/src/ec/controller.rs b/src/ec/controller.rs index 1a33bd4..e3f9037 100644 --- a/src/ec/controller.rs +++ b/src/ec/controller.rs @@ -6,6 +6,8 @@ pub trait SetValue { pub trait ControllerSet: embedded_io::ErrorType { fn set>(&mut self, value: V) -> Result<(), Self::Error>; + + fn set_many>(&mut self, _values: &[V]) -> Result { Ok(0) } } pub trait GetValue { @@ -16,6 +18,8 @@ pub trait GetValue { pub trait ControllerGet: embedded_io::ErrorType { fn get>(&mut self) -> Result; + + fn get_many>(&mut self, _buffer: &[V]) -> Result { Ok(0) } } /// Size of values to write and read from ports. @@ -35,6 +39,10 @@ const MAX_WAIT_CHECKS: u16 = 0x07ff; #[cfg(not(feature = "std"))] 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)] pub struct EmbeddedController { data_address: u16, @@ -44,7 +52,7 @@ pub struct 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 { data_address: data_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 { - super::ports::outb(self.cmd_address, 0x81); + super::ports::outb(self.cmd_address, WRITE_CMD); self.cmd_requested = 1; } else { 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) { use embedded_io::ReadReady; while !self.read_ready().unwrap() { @@ -85,6 +102,13 @@ impl EmbeddedController { 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 { use embedded_io::{Read, Write}; self.write(&[setting as u8]).unwrap(); @@ -94,6 +118,13 @@ impl EmbeddedController { 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) { self.rw_size = size; } @@ -150,7 +181,7 @@ impl embedded_io::Write for EmbeddedController { impl embedded_io::WriteReady for EmbeddedController { fn write_ready(&mut self) -> Result { - self.request_if_not_already(); + self.request_write_if_not_already(); let ready = super::ports::inb(self.cmd_address) & 2 == 0 || self.cmd_requested == MAX_WAIT_CHECKS; if ready { @@ -199,7 +230,7 @@ impl embedded_io::Read for EmbeddedController { impl embedded_io::ReadReady for EmbeddedController { fn read_ready(&mut self) -> Result { - self.request_if_not_already(); + self.request_read_if_not_already(); let ready = super::ports::inb(self.cmd_address) & 1 != 0 || self.cmd_requested == MAX_WAIT_CHECKS; if ready { diff --git a/src/ec/unnamed_power/addresses.rs b/src/ec/unnamed_power/addresses.rs index cf9b835..a128db1 100644 --- a/src/ec/unnamed_power/addresses.rs +++ b/src/ec/unnamed_power/addresses.rs @@ -90,6 +90,8 @@ impl SetValue for BreathingColour { pub enum StaticColour { /// No colour (overrides other set colours) Off = 0x00, + /// No colour (overrides other set colours) + Disabled = 0x80, /// White LED enable White = 0x81, /// Red LED enable diff --git a/src/ec/unnamed_power/mod.rs b/src/ec/unnamed_power/mod.rs index 9629785..80c3965 100644 --- a/src/ec/unnamed_power/mod.rs +++ b/src/ec/unnamed_power/mod.rs @@ -7,7 +7,7 @@ pub mod raw_io; pub struct UnnamedPowerEC(super::EmbeddedController); impl UnnamedPowerEC { - pub fn new() -> Self { + pub const fn new() -> Self { Self(super::EmbeddedController::new(0x68, 0x6c)) }