From cbb0449d433a36f0d22045f9324bc214bb8639d2 Mon Sep 17 00:00:00 2001 From: Milan Zamazal Date: Sat, 5 Aug 2023 17:38:31 +0200 Subject: [PATCH] scmi: Refactor unit handling Make unit handling better SCMI compliant. Let's distinguish between scalar sensors and axis sensors and report the units in the appropriate SCMI commands. Also, let's change the unit type to u8 to correspond to the number of unit bits in SCMI. Signed-off-by: Milan Zamazal --- crates/scmi/src/devices/common.rs | 29 ++++++++++++++++++++++------- crates/scmi/src/devices/fake.rs | 6 +++--- crates/scmi/src/scmi.rs | 12 +++++++++--- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/crates/scmi/src/devices/common.rs b/crates/scmi/src/devices/common.rs index b93fa85..ac3a80a 100644 --- a/crates/scmi/src/devices/common.rs +++ b/crates/scmi/src/devices/common.rs @@ -10,9 +10,9 @@ use log::debug; use thiserror::Error as ThisError; use crate::scmi::{ - DeviceResult, MessageId, MessageValue, MessageValues, ProtocolId, ScmiDevice, ScmiDeviceError, - MAX_SIMPLE_STRING_LENGTH, SENSOR_AXIS_DESCRIPTION_GET, SENSOR_CONFIG_GET, SENSOR_CONFIG_SET, - SENSOR_CONTINUOUS_UPDATE_NOTIFY, SENSOR_DESCRIPTION_GET, SENSOR_PROTOCOL_ID, + self, DeviceResult, MessageId, MessageValue, MessageValues, ProtocolId, ScmiDevice, + ScmiDeviceError, MAX_SIMPLE_STRING_LENGTH, SENSOR_AXIS_DESCRIPTION_GET, SENSOR_CONFIG_GET, + SENSOR_CONFIG_SET, SENSOR_CONTINUOUS_UPDATE_NOTIFY, SENSOR_DESCRIPTION_GET, SENSOR_PROTOCOL_ID, SENSOR_READING_GET, }; @@ -204,13 +204,22 @@ pub trait SensorT: Send { } fn number_of_axes(&self) -> u32 { - 1 + 0 + } + + fn format_unit(&self, axis: u32) -> u32 { + (self.unit_exponent(axis) as u32 & 0x1F) << 11 | u32::from(self.unit()) } fn description_get(&self) -> DeviceResult { // Continuous update required by Linux SCMI IIO driver let low = 1 << 30; - let high = self.number_of_axes() << 16 | 1 << 8; + let n_axes = self.number_of_axes(); + let high = if n_axes > 0 { + n_axes << 16 | 1 << 8 + } else { + self.format_unit(0) + }; let name = self.sensor().name.clone(); let values: MessageValues = vec![ // attributes low @@ -223,7 +232,13 @@ pub trait SensorT: Send { Ok(values) } - fn axis_unit(&self) -> u32; + fn unit(&self) -> u8 { + scmi::SENSOR_UNIT_UNSPECIFIED + } + + fn unit_exponent(&self, _axis: u32) -> i8 { + 0 + } fn axis_name_prefix(&self) -> String { "axis".to_owned() @@ -242,7 +257,7 @@ pub trait SensorT: Send { let mut values = vec![]; values.push(MessageValue::Unsigned(axis)); // axis id values.push(MessageValue::Unsigned(0)); // attributes low - values.push(MessageValue::Unsigned(self.axis_unit())); // attributes high + values.push(MessageValue::Unsigned(self.format_unit(axis))); // attributes high // Name in the recommended format, 16 bytes: let prefix = self.axis_name_prefix(); diff --git a/crates/scmi/src/devices/fake.rs b/crates/scmi/src/devices/fake.rs index cc47d63..5cde468 100644 --- a/crates/scmi/src/devices/fake.rs +++ b/crates/scmi/src/devices/fake.rs @@ -3,7 +3,7 @@ // Fake sensor -use crate::scmi::{DeviceResult, MessageValue, SENSOR_UNIT_METERS_PER_SECOND_SQUARED}; +use crate::scmi::{self, DeviceResult, MessageValue}; use super::common::{DeviceProperties, MaybeDevice, Sensor, SensorDevice, SensorT}; @@ -25,11 +25,11 @@ impl SensorT for FakeSensor { 3 } - fn axis_unit(&self) -> u32 { + fn unit(&self) -> u8 { // The sensor type is "Meters per second squared", since this is the // only, together with "Radians per second", what Google Linux IIO // supports (accelerometers and gyroscopes only). - SENSOR_UNIT_METERS_PER_SECOND_SQUARED + scmi::SENSOR_UNIT_METERS_PER_SECOND_SQUARED } fn axis_name_prefix(&self) -> String { diff --git a/crates/scmi/src/scmi.rs b/crates/scmi/src/scmi.rs index 616e4cd..82185b6 100644 --- a/crates/scmi/src/scmi.rs +++ b/crates/scmi/src/scmi.rs @@ -216,7 +216,8 @@ pub const SENSOR_CONFIG_GET: MessageId = 0x9; pub const SENSOR_CONFIG_SET: MessageId = 0xA; pub const SENSOR_CONTINUOUS_UPDATE_NOTIFY: MessageId = 0xB; -pub const SENSOR_UNIT_METERS_PER_SECOND_SQUARED: u32 = 89; +pub const SENSOR_UNIT_UNSPECIFIED: u8 = 1; +pub const SENSOR_UNIT_METERS_PER_SECOND_SQUARED: u8 = 89; enum ParameterType { _SignedInt32, @@ -309,7 +310,12 @@ impl HandlerMap { BASE_DISCOVER_VENDOR, "base/discover_vendor", vec![], - |_, _| -> Response { Response::from(MessageValue::String("rust-vmm".to_string(), 16)) }, + |_, _| -> Response { + Response::from(MessageValue::String( + "rust-vmm".to_string(), + MAX_SIMPLE_STRING_LENGTH, + )) + }, ); self.bind( BASE_PROTOCOL_ID, @@ -1144,7 +1150,7 @@ mod tests { let mut description = vec![ MessageValue::Unsigned(i), MessageValue::Unsigned(0), - MessageValue::Unsigned(SENSOR_UNIT_METERS_PER_SECOND_SQUARED), + MessageValue::Unsigned(u32::from(SENSOR_UNIT_METERS_PER_SECOND_SQUARED)), MessageValue::String(name, MAX_SIMPLE_STRING_LENGTH), ]; result.append(&mut description);