summaryrefslogtreecommitdiff
path: root/sound_card_init/amp
diff options
context:
space:
mode:
authorAndrew Walbran <qwandor@google.com>2021-08-03 14:20:19 +0000
committerAndrew Walbran <qwandor@google.com>2021-08-03 14:20:19 +0000
commit8dce65084f73d40bb081312769a24b4bd533f667 (patch)
treee2118ad5dbee0370c6ab114bb3974cd9f09a2251 /sound_card_init/amp
parentbcf1f249f11b6865cff3f0d3f0ae5801e67e0e7e (diff)
downloadadhd-android-s-v2-beta-3.tar.gz
This repository will be removed from the manifest change, but Treehugger seems unable to test the manifest change, so this change first removes all files so we can test that instead. Bug: 190503456 Test: m crosvm Change-Id: I133ef3bd8b39035a68113c4da8fe4c637a40daac
Diffstat (limited to 'sound_card_init/amp')
-rw-r--r--sound_card_init/amp/Cargo.lock254
-rw-r--r--sound_card_init/amp/Cargo.toml16
-rw-r--r--sound_card_init/amp/src/lib.rs58
-rw-r--r--sound_card_init/amp/src/max98373d/dsm_param.rs211
-rw-r--r--sound_card_init/amp/src/max98373d/mod.rs274
-rw-r--r--sound_card_init/amp/src/max98373d/settings.rs41
-rw-r--r--sound_card_init/amp/src/max98390d/mod.rs213
-rw-r--r--sound_card_init/amp/src/max98390d/settings.rs51
8 files changed, 0 insertions, 1118 deletions
diff --git a/sound_card_init/amp/Cargo.lock b/sound_card_init/amp/Cargo.lock
deleted file mode 100644
index 679e60cd..00000000
--- a/sound_card_init/amp/Cargo.lock
+++ /dev/null
@@ -1,254 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "alsa-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644d308f5822c2b39fba5a6d850f74c208bf73c61d1d2dfad62505d6960e4977"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "amp"
-version = "0.1.0"
-dependencies = [
- "cros_alsa",
- "dsm",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sof_sys",
- "sys_util",
-]
-
-[[package]]
-name = "android_log-sys"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e"
-
-[[package]]
-name = "assertions"
-version = "0.1.0"
-
-[[package]]
-name = "audio_streams"
-version = "0.1.0"
-dependencies = [
- "sync",
- "sys_util",
-]
-
-[[package]]
-name = "cras-sys"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "data_model",
-]
-
-[[package]]
-name = "cros_alsa"
-version = "0.1.0"
-dependencies = [
- "alsa-sys",
- "cros_alsa_derive",
- "libc",
- "remain",
-]
-
-[[package]]
-name = "cros_alsa_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "data_model"
-version = "0.1.0"
-dependencies = [
- "assertions",
- "libc",
-]
-
-[[package]]
-name = "dsm"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cros_alsa",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sys_util",
-]
-
-[[package]]
-name = "dtoa"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
-
-[[package]]
-name = "libc"
-version = "0.2.84"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff"
-
-[[package]]
-name = "libcras"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cras-sys",
- "data_model",
- "libc",
- "sys_util",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
-
-[[package]]
-name = "poll_token_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "remain"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.123"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.123"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_yaml"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "971be8f6e4d4a47163b405a3df70d14359186f9ab0f3a3ec37df144ca1ce089f"
-dependencies = [
- "dtoa",
- "linked-hash-map",
- "serde",
- "yaml-rust",
-]
-
-[[package]]
-name = "sof_sys"
-version = "0.1.0"
-
-[[package]]
-name = "syn"
-version = "1.0.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "sync"
-version = "0.1.0"
-
-[[package]]
-name = "sys_util"
-version = "0.1.0"
-dependencies = [
- "android_log-sys",
- "data_model",
- "libc",
- "poll_token_derive",
- "sync",
- "syscall_defines",
- "tempfile",
-]
-
-[[package]]
-name = "syscall_defines"
-version = "0.1.0"
-
-[[package]]
-name = "tempfile"
-version = "3.0.7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
-
-[[package]]
-name = "yaml-rust"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
-dependencies = [
- "linked-hash-map",
-]
diff --git a/sound_card_init/amp/Cargo.toml b/sound_card_init/amp/Cargo.toml
deleted file mode 100644
index 62e63db7..00000000
--- a/sound_card_init/amp/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "amp"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-description = "The boot time calibration logic for smart amp"
-
-[dependencies]
-cros_alsa = "*"
-libcras = "*"
-dsm = { path = "../dsm" }
-remain = "0.2.1"
-serde = { version = "1.0", features = ["derive"]}
-serde_yaml = "0.8.11"
-sof_sys = "*"
-sys_util = "*"
diff --git a/sound_card_init/amp/src/lib.rs b/sound_card_init/amp/src/lib.rs
deleted file mode 100644
index 7114233d..00000000
--- a/sound_card_init/amp/src/lib.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2021 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `amp` crate provides `Amp` trait for amplifier initializations and `AmpBuilder`
-//! to create `Amp` objects.
-#![deny(missing_docs)]
-
-mod max98373d;
-mod max98390d;
-use std::path::PathBuf;
-
-use dsm::Error;
-
-use max98373d::Max98373;
-use max98390d::Max98390;
-
-type Result<T> = std::result::Result<T, Error>;
-const CONF_DIR: &str = "/etc/sound_card_init";
-
-/// It creates `Amp` object based on the sound card name.
-pub struct AmpBuilder<'a> {
- sound_card_id: &'a str,
- config_path: PathBuf,
-}
-
-impl<'a> AmpBuilder<'a> {
- /// Creates an `AmpBuilder`.
- /// # Arguments
- ///
- /// * `card_name` - card name.
- /// * `conf_file` - config file name.
- pub fn new(sound_card_id: &'a str, conf_file: &'a str) -> Self {
- let config_path = PathBuf::from(CONF_DIR).join(conf_file);
- AmpBuilder {
- sound_card_id,
- config_path,
- }
- }
-
- /// Creates an `Amp` based on the sound card name.
- pub fn build(&self) -> Result<Box<dyn Amp>> {
- match self.sound_card_id {
- "sofcmlmax98390d" => {
- Ok(Box::new(Max98390::new(self.sound_card_id, &self.config_path)?) as Box<dyn Amp>)
- }
- "sofrt5682" => {
- Ok(Box::new(Max98373::new(self.sound_card_id, &self.config_path)?) as Box<dyn Amp>)
- }
- _ => Err(Error::UnsupportedSoundCard(self.sound_card_id.to_owned())),
- }
- }
-}
-
-/// It defines the required functions of amplifier objects.
-pub trait Amp {
- /// The amplifier boot time calibration flow.
- fn boot_time_calibration(&mut self) -> Result<()>;
-}
diff --git a/sound_card_init/amp/src/max98373d/dsm_param.rs b/sound_card_init/amp/src/max98373d/dsm_param.rs
deleted file mode 100644
index d9257522..00000000
--- a/sound_card_init/amp/src/max98373d/dsm_param.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::mem;
-
-use cros_alsa::{Card, TLV};
-use sof_sys::sof_abi_hdr;
-
-use dsm::{self, Error, Result};
-
-/// Amp volume mode enumeration used by set_volume().
-#[derive(Copy, Clone, PartialEq)]
-pub enum VolumeMode {
- /// Low mode protects the speaker by limiting its output volume if the
- /// calibration has not been completed successfully.
- Low = 0x1009B9CF,
- /// High mode removes the speaker output volume limitation after
- /// having successfully completed the calibration.
- High = 0x20000000,
-}
-
-#[derive(Copy, Clone)]
-/// Calibration mode enumeration.
-pub enum CalibMode {
- ON = 0x4,
- OFF = 0x1,
-}
-
-#[derive(Copy, Clone)]
-/// Smart pilot signal mode mode enumeration.
-pub enum SPTMode {
- ON = 0x1,
- OFF = 0x0,
-}
-
-#[derive(Copy, Clone)]
-/// DSM Parem field enumeration.
-enum DsmAPI {
- ParamCount = 0x0,
- CalibMode = 0x1,
- MakeupGain = 0x5,
- DsmRdc = 0x6,
- DsmAmbientTemp = 0x8,
- AdaptiveRdc = 0x12,
- SPTMode = 0x68,
-}
-
-#[derive(Debug)]
-/// It implements functions to access the `DSMParam` fields.
-pub struct DSMParam {
- param_count: usize,
- num_channels: usize,
- tlv: TLV,
-}
-
-impl DSMParam {
- const DWORD_PER_PARAM: usize = 2;
- const VALUE_OFFSET: usize = 1;
- const SOF_HEADER_SIZE: usize = mem::size_of::<sof_abi_hdr>() / mem::size_of::<i32>();
-
- /// Creates an `DSMParam`.
- /// # Arguments
- ///
- /// * `card` - `&Card`.
- /// * `num_channels` - number of channels.
- /// * `ctl_name` - the mixer control name to access the DSM param.
- ///
- /// # Results
- ///
- /// * `DSMParam` - It is initialized by the content of the given byte control .
- ///
- /// # Errors
- ///
- /// * If `Card` creation from sound card name fails.
- pub fn new(card: &mut Card, num_channels: usize, ctl_name: &str) -> Result<Self> {
- let tlv = card.control_tlv_by_name(ctl_name)?.load()?;
- Self::try_from_tlv(tlv, num_channels)
- }
-
- /// Sets DSMParam to the given calibration mode.
- pub fn set_calibration_mode(&mut self, mode: CalibMode) {
- for channel in 0..self.num_channels {
- self.set(channel, DsmAPI::CalibMode, mode as i32);
- }
- }
-
- /// Sets DSMParam to the given smart pilot signal mode.
- pub fn set_spt_mode(&mut self, mode: SPTMode) {
- for channel in 0..self.num_channels {
- self.set(channel, DsmAPI::SPTMode, mode as i32);
- }
- }
-
- /// Sets DSMParam to the given VolumeMode.
- pub fn set_volume_mode(&mut self, mode: VolumeMode) {
- for channel in 0..self.num_channels {
- self.set(channel, DsmAPI::MakeupGain, mode as i32);
- }
- }
-
- /// Reads the calibrated rdc from DSMParam.
- pub fn get_adaptive_rdc(&self) -> Vec<i32> {
- self.get(DsmAPI::AdaptiveRdc)
- }
-
- /// Sets DSMParam to the given the calibrated rdc.
- pub fn set_rdc(&mut self, ch: usize, rdc: i32) {
- self.set(ch, DsmAPI::DsmRdc, rdc);
- }
-
- /// Sets DSMParam to the given calibrated temp.
- pub fn set_ambient_temp(&mut self, ch: usize, temp: i32) {
- self.set(ch, DsmAPI::DsmAmbientTemp, temp);
- }
-
- /// Sets the `id` field to the given `val`.
- fn set(&mut self, channel: usize, id: DsmAPI, val: i32) {
- let pos = Self::value_pos(self.param_count, channel, id);
- self.tlv[pos] = val as u32;
- }
-
- /// Gets the val from the `id` field from all the channels.
- fn get(&self, id: DsmAPI) -> Vec<i32> {
- (0..self.num_channels)
- .map(|channel| {
- let pos = Self::value_pos(self.param_count, channel, id);
- self.tlv[pos] as i32
- })
- .collect()
- }
-
- fn try_from_tlv(tlv: TLV, num_channels: usize) -> Result<Self> {
- let param_count_pos = Self::value_pos(0, 0, DsmAPI::ParamCount);
-
- if tlv.len() < param_count_pos {
- return Err(Error::InvalidDSMParam);
- }
-
- let param_count = tlv[param_count_pos] as usize;
-
- if tlv.len() != Self::SOF_HEADER_SIZE + param_count * num_channels * Self::DWORD_PER_PARAM {
- return Err(Error::InvalidDSMParam);
- }
-
- Ok(Self {
- param_count,
- num_channels,
- tlv,
- })
- }
-
- #[inline]
- fn value_pos(param_count: usize, channel: usize, id: DsmAPI) -> usize {
- Self::SOF_HEADER_SIZE
- + (channel * param_count + id as usize) * Self::DWORD_PER_PARAM
- + Self::VALUE_OFFSET
- }
-}
-
-impl Into<TLV> for DSMParam {
- fn into(self) -> TLV {
- self.tlv
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- const PARAM_COUNT: usize = 138;
- const CHANNEL_COUNT: usize = 2;
-
- #[test]
- fn test_dsmparam_try_from_tlv_ok() {
- let mut data = vec![
- 0u32;
- DSMParam::SOF_HEADER_SIZE
- + CHANNEL_COUNT * PARAM_COUNT * DSMParam::DWORD_PER_PARAM
- ];
- data[DSMParam::value_pos(PARAM_COUNT, 0, DsmAPI::ParamCount)] = PARAM_COUNT as u32;
- data[DSMParam::value_pos(PARAM_COUNT, 1, DsmAPI::ParamCount)] = PARAM_COUNT as u32;
-
- let tlv = TLV::new(0, data);
- assert!(DSMParam::try_from_tlv(tlv, CHANNEL_COUNT).is_ok());
- }
-
- #[test]
- fn test_dsmparam_try_from_invalid_len() {
- let data = vec![0u32; DSMParam::SOF_HEADER_SIZE];
-
- let tlv = TLV::new(0, data);
- assert_eq!(
- DSMParam::try_from_tlv(tlv, CHANNEL_COUNT).unwrap_err(),
- Error::InvalidDSMParam
- );
- }
-
- #[test]
- fn test_dsmparam_try_from_param_count() {
- let data = vec![
- 0u32;
- DSMParam::SOF_HEADER_SIZE
- + CHANNEL_COUNT * PARAM_COUNT * DSMParam::DWORD_PER_PARAM
- ];
-
- let tlv = TLV::new(0, data);
- assert_eq!(
- DSMParam::try_from_tlv(tlv, CHANNEL_COUNT).unwrap_err(),
- Error::InvalidDSMParam
- );
- }
-}
diff --git a/sound_card_init/amp/src/max98373d/mod.rs b/sound_card_init/amp/src/max98373d/mod.rs
deleted file mode 100644
index 1ee29ceb..00000000
--- a/sound_card_init/amp/src/max98373d/mod.rs
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `max98373d` module implements the required initialization workflows for sound
-//! cards that use max98373d smart amp.
-//! It currently supports boot time calibration for max98373d.
-#![deny(missing_docs)]
-mod dsm_param;
-mod settings;
-
-use std::path::Path;
-use std::time::Duration;
-use std::{fs, thread};
-
-use cros_alsa::{Card, IntControl};
-use dsm::{CalibData, Error, Result, SpeakerStatus, ZeroPlayer, DSM};
-use sys_util::info;
-
-use crate::Amp;
-use dsm_param::*;
-use settings::{AmpCalibSettings, DeviceSettings};
-
-/// It implements the amplifier boot time calibration flow.
-pub struct Max98373 {
- card: Card,
- setting: AmpCalibSettings,
-}
-
-impl Amp for Max98373 {
- /// Performs max98373d boot time calibration.
- ///
- /// # Errors
- ///
- /// If any amplifiers fail to complete the calibration.
- fn boot_time_calibration(&mut self) -> Result<()> {
- if !Path::new(&self.setting.dsm_param).exists() {
- return Err(Error::MissingDSMParam);
- }
-
- let num_channels = self.setting.num_channels();
- let dsm = DSM::new(
- &self.card.name(),
- num_channels,
- Self::rdc_to_ohm,
- Self::TEMP_UPPER_LIMIT_CELSIUS,
- Self::TEMP_LOWER_LIMIT_CELSIUS,
- );
- self.set_volume(VolumeMode::Low)?;
-
- let calib = if !self.setting.boot_time_calibration_enabled {
- info!("skip boot time calibration and use vpd values");
- // Needs Rdc updates to be done after internal speaker is ready otherwise
- // it would be overwritten by the DSM blob update.
- dsm.wait_for_speakers_ready()?;
- dsm.get_all_vpd_calibration_value()?
- } else {
- match dsm.check_speaker_over_heated_workflow()? {
- SpeakerStatus::Hot(previous_calib) => previous_calib,
- SpeakerStatus::Cold => {
- let all_temp = self.get_ambient_temp()?;
- let all_rdc = self.do_rdc_calibration()?;
- all_rdc
- .iter()
- .zip(all_temp)
- .enumerate()
- .map(|(ch, (&rdc, temp))| {
- dsm.decide_calibration_value_workflow(ch, CalibData { rdc, temp })
- })
- .collect::<Result<Vec<_>>>()?
- }
- }
- };
- self.apply_calibration_value(&calib)?;
- self.set_volume(VolumeMode::High)?;
- Ok(())
- }
-}
-
-impl Max98373 {
- const TEMP_CALIB_WARM_UP_TIME: Duration = Duration::from_millis(10);
- const RDC_CALIB_WARM_UP_TIME: Duration = Duration::from_millis(500);
- const RDC_CALIB_INTERVAL: Duration = Duration::from_millis(200);
- const CALIB_REPEAT_TIMES: usize = 5;
-
- const TEMP_UPPER_LIMIT_CELSIUS: f32 = 40.0;
- const TEMP_LOWER_LIMIT_CELSIUS: f32 = 0.0;
-
- /// Creates an `Max98373`.
- /// # Arguments
- ///
- /// * `card_name` - card_name.
- /// * `config_path` - config file path.
- ///
- /// # Results
- ///
- /// * `Max98373` - It implements the Max98373 functions of boot time calibration.
- ///
- /// # Errors
- ///
- /// * If `Card` creation from sound card name fails.
- pub fn new(card_name: &str, config_path: &Path) -> Result<Self> {
- let conf = fs::read_to_string(config_path)
- .map_err(|e| Error::FileIOFailed(config_path.to_path_buf(), e))?;
- let settings = DeviceSettings::from_yaml_str(&conf)?;
- Ok(Self {
- card: Card::new(card_name)?,
- setting: settings.amp_calibrations,
- })
- }
-
- /// Triggers the amplifier calibration and reads the calibrated rdc.
- /// To get accurate calibration results, the main thread calibrates the amplifier while
- /// the `zero_player` starts another thread to play zeros to the speakers.
- fn do_rdc_calibration(&mut self) -> Result<Vec<i32>> {
- let mut zero_player: ZeroPlayer = Default::default();
- zero_player.start(Self::RDC_CALIB_WARM_UP_TIME)?;
- // Playback of zeros is started for Self::RDC_CALIB_WARM_UP_TIME, and the main thread
- // can start the calibration.
- self.set_spt_mode(SPTMode::OFF)?;
- self.set_calibration_mode(CalibMode::ON)?;
- // Playback of zeros is started, and the main thread can start the calibration.
- let mut avg_rdc = vec![0; self.setting.num_channels()];
- for _ in 0..Self::CALIB_REPEAT_TIMES {
- let rdc = self.get_adaptive_rdc()?;
- for i in 0..self.setting.num_channels() {
- avg_rdc[i] += rdc[i];
- }
- thread::sleep(Self::RDC_CALIB_INTERVAL);
- }
- self.set_spt_mode(SPTMode::ON)?;
- self.set_calibration_mode(CalibMode::OFF)?;
- zero_player.stop()?;
-
- avg_rdc = avg_rdc
- .iter()
- .map(|val| val / Self::CALIB_REPEAT_TIMES as i32)
- .collect();
- Ok(avg_rdc)
- }
-
- /// Sets the card volume control to the given VolumeMode.
- fn set_volume(&mut self, mode: VolumeMode) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
-
- dsm_param.set_volume_mode(mode);
-
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Applies the calibration value to the amp.
- fn apply_calibration_value(&mut self, calib: &[CalibData]) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- for ch in 0..self.setting.num_channels() {
- dsm_param.set_rdc(ch, calib[ch].rdc);
- dsm_param.set_ambient_temp(ch, Self::celsius_to_dsm_unit(calib[ch].temp));
- }
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Rdc (ohm) = [ID:0x12] * 3.66 / 2^27
- #[inline]
- fn rdc_to_ohm(x: i32) -> f32 {
- (3.66 * x as f32) / (1 << 27) as f32
- }
-
- /// Returns the ambient temperature in celsius degree.
- fn get_ambient_temp(&mut self) -> Result<Vec<f32>> {
- let mut zero_player: ZeroPlayer = Default::default();
- zero_player.start(Self::TEMP_CALIB_WARM_UP_TIME)?;
- let mut temps = Vec::new();
- for x in 0..self.setting.num_channels() as usize {
- let temp = self
- .card
- .control_by_name::<IntControl>(&self.setting.temp_ctrl[x])?
- .get()?;
- let celsius = Self::measured_temp_to_celsius(temp);
- temps.push(celsius);
- }
- zero_player.stop()?;
-
- Ok(temps)
- }
-
- /// Converts the measured ambient temperature to celsius unit.
- #[inline]
- fn measured_temp_to_celsius(temp: i32) -> f32 {
- // Measured Temperature (°C) = ([Mixer Val] * 1.28) - 29
- (temp as f32 * 1.28) - 29.0
- }
-
- /// Converts the ambient temperature from celsius to the DsmSetAPI::DsmAmbientTemp unit.
- #[inline]
- fn celsius_to_dsm_unit(celsius: f32) -> i32 {
- // Temperature (℃) = [ID:0x12] / 2^19
- (celsius * (1 << 19) as f32) as i32
- }
-
- /// Sets the amp to the given smart pilot signal mode.
- fn set_spt_mode(&mut self, mode: SPTMode) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- dsm_param.set_spt_mode(mode);
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Sets the amp to the given the calibration mode.
- fn set_calibration_mode(&mut self, mode: CalibMode) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- dsm_param.set_calibration_mode(mode);
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Reads the calibrated rdc.
- /// Must be called when the calibration mode in on.
- fn get_adaptive_rdc(&mut self) -> Result<Vec<i32>> {
- let dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- Ok(dsm_param.get_adaptive_rdc())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn celsius_to_dsm_unit() {
- assert_eq!(Max98373::celsius_to_dsm_unit(37.0), 0x01280000);
- assert_eq!(Max98373::celsius_to_dsm_unit(50.0), 0x01900000);
- }
-
- #[test]
- fn rdc_to_ohm() {
- assert_eq!(Max98373::rdc_to_ohm(0x05cea0c7), 2.656767);
- }
-
- #[test]
- fn measured_temp_to_celsius() {
- assert_eq!(Max98373::measured_temp_to_celsius(56), 42.68);
- }
-}
diff --git a/sound_card_init/amp/src/max98373d/settings.rs b/sound_card_init/amp/src/max98373d/settings.rs
deleted file mode 100644
index 1d6e64e5..00000000
--- a/sound_card_init/amp/src/max98373d/settings.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::string::String;
-
-use dsm::{self, Error, Result};
-use serde::Deserialize;
-/// `DeviceSettings` includes the settings of max98373. It currently includes:
-/// * the settings of amplifier calibration.
-/// * the path of dsm_param.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct DeviceSettings {
- pub amp_calibrations: AmpCalibSettings,
-}
-
-/// `AmpCalibSettings` includes the settings needed for amplifier calibration.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct AmpCalibSettings {
- pub dsm_param_read_ctrl: String,
- pub dsm_param_write_ctrl: String,
- pub temp_ctrl: Vec<String>,
- // Path of the dsm_param.bin file.
- pub dsm_param: String,
- pub boot_time_calibration_enabled: bool,
-}
-
-impl AmpCalibSettings {
- /// Returns the number of channels.
- pub fn num_channels(&self) -> usize {
- self.temp_ctrl.len()
- }
-}
-
-impl DeviceSettings {
- /// Creates a `DeviceSettings` from a yaml str.
- pub fn from_yaml_str(conf: &str) -> Result<DeviceSettings> {
- let settings: DeviceSettings = serde_yaml::from_str(conf)
- .map_err(|e| Error::DeserializationFailed("DeviceSettings".to_owned(), e))?;
- Ok(settings)
- }
-}
diff --git a/sound_card_init/amp/src/max98390d/mod.rs b/sound_card_init/amp/src/max98390d/mod.rs
deleted file mode 100644
index 601165ec..00000000
--- a/sound_card_init/amp/src/max98390d/mod.rs
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `max98390d` module implements the required initialization workflows for sound
-//! cards that use max98390d smart amp.
-//! It currently supports boot time calibration for max98390d.
-#![deny(missing_docs)]
-mod settings;
-
-use std::time::Duration;
-use std::{fs, path::Path};
-
-use cros_alsa::{Card, IntControl, SwitchControl};
-use dsm::{CalibData, Error, Result, SpeakerStatus, TempConverter, ZeroPlayer, DSM};
-
-use crate::Amp;
-use settings::{AmpCalibSettings, DeviceSettings};
-
-/// Amp volume mode emulation used by set_volume().
-#[derive(PartialEq, Clone, Copy)]
-enum VolumeMode {
- /// Low mode protects the speaker by limiting its output volume if the
- /// calibration has not been completed successfully.
- Low = 138,
- /// High mode removes the speaker output volume limitation after
- /// having successfully completed the calibration.
- High = 148,
-}
-
-/// It implements the Max98390 functions of boot time calibration.
-#[derive(Debug)]
-pub struct Max98390 {
- card: Card,
- setting: AmpCalibSettings,
-}
-
-impl Amp for Max98390 {
- /// Performs max98390d boot time calibration.
- ///
- /// # Errors
- ///
- /// If the amplifier fails to complete the calibration.
- fn boot_time_calibration(&mut self) -> Result<()> {
- if !Path::new(&self.setting.dsm_param).exists() {
- return Err(Error::MissingDSMParam);
- }
-
- let mut dsm = DSM::new(
- &self.card.name(),
- self.setting.num_channels(),
- Self::rdc_to_ohm,
- Self::TEMP_UPPER_LIMIT_CELSIUS,
- Self::TEMP_LOWER_LIMIT_CELSIUS,
- );
- dsm.set_temp_converter(TempConverter::new(
- Self::dsm_unit_to_celsius,
- Self::celsius_to_dsm_unit,
- ));
-
- self.set_volume(VolumeMode::Low)?;
- let calib = match dsm.check_speaker_over_heated_workflow()? {
- SpeakerStatus::Hot(previous_calib) => previous_calib,
- SpeakerStatus::Cold => self
- .do_calibration()?
- .iter()
- .enumerate()
- .map(|(ch, calib_data)| dsm.decide_calibration_value_workflow(ch, *calib_data))
- .collect::<Result<Vec<_>>>()?,
- };
- self.apply_calibration_value(calib)?;
- self.set_volume(VolumeMode::High)?;
- Ok(())
- }
-}
-
-impl Max98390 {
- const TEMP_UPPER_LIMIT_CELSIUS: f32 = 40.0;
- const TEMP_LOWER_LIMIT_CELSIUS: f32 = 0.0;
- const RDC_CALIB_WARM_UP_TIME: Duration = Duration::from_millis(300);
-
- /// Creates an `Max98390`.
- /// # Arguments
- ///
- /// * `card_name` - card name.
- /// * `config_path` - config file path.
- ///
- /// # Results
- ///
- /// * `Max98390` - It implements the Max98390 functions of boot time calibration.
- ///
- /// # Errors
- ///
- /// * If `Card` creation from sound card name fails.
- pub fn new(card_name: &str, config_path: &Path) -> Result<Self> {
- let conf = fs::read_to_string(config_path)
- .map_err(|e| Error::FileIOFailed(config_path.to_path_buf(), e))?;
- let settings = DeviceSettings::from_yaml_str(&conf)?;
- Ok(Self {
- card: Card::new(card_name)?,
- setting: settings.amp_calibrations,
- })
- }
-
- /// Sets the card volume control to given VolumeMode.
- fn set_volume(&mut self, mode: VolumeMode) -> Result<()> {
- for control in &self.setting.controls {
- self.card
- .control_by_name::<IntControl>(&control.volume_ctrl)?
- .set(mode as i32)?;
- }
- Ok(())
- }
-
- /// Applies the calibration value to the amp.
- fn apply_calibration_value(&mut self, calib: Vec<CalibData>) -> Result<()> {
- for (ch, &CalibData { rdc, temp }) in calib.iter().enumerate() {
- self.card
- .control_by_name::<IntControl>(&self.setting.controls[ch].rdc_ctrl)?
- .set(rdc)?;
- self.card
- .control_by_name::<IntControl>(&self.setting.controls[ch].temp_ctrl)?
- .set(Self::celsius_to_dsm_unit(temp))?;
- }
- Ok(())
- }
-
- /// Triggers the amplifier calibration and reads the calibrated rdc and ambient_temp value
- /// from the mixer control.
- /// To get accurate calibration results, the main thread calibrates the amplifier while
- /// the `zero_player` starts another thread to play zeros to the speakers.
- fn do_calibration(&mut self) -> Result<Vec<CalibData>> {
- let mut zero_player: ZeroPlayer = Default::default();
- zero_player.start(Self::RDC_CALIB_WARM_UP_TIME)?;
- // Playback of zeros is started for Self::RDC_CALIB_WARM_UP_TIME, and the main thread
- // can start the calibration.
- let setting = &self.setting;
- let card = &mut self.card;
- let calib = setting
- .controls
- .iter()
- .map(|control| {
- card.control_by_name::<SwitchControl>(&control.calib_ctrl)?
- .on()?;
- let rdc = card
- .control_by_name::<IntControl>(&control.rdc_ctrl)?
- .get()?;
- let temp = card
- .control_by_name::<IntControl>(&control.temp_ctrl)?
- .get()?;
- card.control_by_name::<SwitchControl>(&control.calib_ctrl)?
- .off()?;
- Ok(CalibData {
- rdc,
- temp: Self::dsm_unit_to_celsius(temp),
- })
- })
- .collect::<Result<Vec<CalibData>>>()?;
- zero_player.stop()?;
- Ok(calib)
- }
-
- /// Converts the ambient temperature from celsius to the DSM unit.
- #[inline]
- fn celsius_to_dsm_unit(celsius: f32) -> i32 {
- (celsius * ((1 << 12) as f32) / 100.0) as i32
- }
-
- /// Converts the ambient temperature from DSM unit to celsius.
- #[inline]
- fn dsm_unit_to_celsius(temp: i32) -> f32 {
- temp as f32 * 100.0 / (1 << 12) as f32
- }
-
- /// Converts the calibrated value to real DC resistance in ohm unit.
- #[inline]
- fn rdc_to_ohm(x: i32) -> f32 {
- 3.66 * (1 << 20) as f32 / x as f32
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn celsius_to_dsm_unit() {
- assert_eq!(
- Max98390::celsius_to_dsm_unit(Max98390::TEMP_UPPER_LIMIT_CELSIUS),
- 1638
- );
- assert_eq!(
- Max98390::celsius_to_dsm_unit(Max98390::TEMP_LOWER_LIMIT_CELSIUS),
- 0
- );
- }
-
- #[test]
- fn dsm_unit_to_celsius() {
- assert_eq!(
- Max98390::dsm_unit_to_celsius(1638).round(),
- Max98390::TEMP_UPPER_LIMIT_CELSIUS
- );
- assert_eq!(
- Max98390::dsm_unit_to_celsius(0),
- Max98390::TEMP_LOWER_LIMIT_CELSIUS
- );
- }
-
- #[test]
- fn rdc_to_ohm() {
- assert_eq!(Max98390::rdc_to_ohm(1123160), 3.416956);
- assert_eq!(Max98390::rdc_to_ohm(1157049), 3.3168762);
- }
-}
diff --git a/sound_card_init/amp/src/max98390d/settings.rs b/sound_card_init/amp/src/max98390d/settings.rs
deleted file mode 100644
index 316f25be..00000000
--- a/sound_card_init/amp/src/max98390d/settings.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::string::String;
-
-use dsm::{self, Error, Result};
-use serde::Deserialize;
-
-/// `DeviceSettings` includes the settings of max98390. It currently includes:
-/// * the settings of amplifier calibration.
-/// * the path of dsm_param.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct DeviceSettings {
- pub amp_calibrations: AmpCalibSettings,
-}
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct AmpCalibCtrl {
- // Mixer control to get/set rdc value.
- pub rdc_ctrl: String,
- // Mixer control to get/set ambient temperature value.
- pub temp_ctrl: String,
- // Mixer control to trigger calibration.
- pub calib_ctrl: String,
- // Mixer control to adjust volume.
- pub volume_ctrl: String,
-}
-
-/// `AmpCalibSettings` includes the settings needed for amplifier calibration.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct AmpCalibSettings {
- // Mixer control to get/set rdc value.
- pub controls: Vec<AmpCalibCtrl>,
- // Path of the dsm_param.bin file.
- pub dsm_param: String,
-}
-
-impl AmpCalibSettings {
- /// Returns the number of channels.
- pub fn num_channels(&self) -> usize {
- self.controls.len()
- }
-}
-
-impl DeviceSettings {
- /// Creates a `DeviceSettings` from a yaml str.
- pub fn from_yaml_str(conf: &str) -> Result<DeviceSettings> {
- let settings: DeviceSettings = serde_yaml::from_str(conf)
- .map_err(|e| Error::DeserializationFailed("DeviceSettings".to_owned(), e))?;
- Ok(settings)
- }
-}