v0.2.0
This commit is contained in:
parent
10e1f8f44b
commit
56605fac67
4 changed files with 40 additions and 7 deletions
|
@ -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>"]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue