summaryrefslogtreecommitdiff
path: root/sound_card_init/max98390d/src
diff options
context:
space:
mode:
Diffstat (limited to 'sound_card_init/max98390d/src')
-rw-r--r--sound_card_init/max98390d/src/amp_calibration.rs70
-rw-r--r--sound_card_init/max98390d/src/datastore.rs3
-rw-r--r--sound_card_init/max98390d/src/error.rs11
-rw-r--r--sound_card_init/max98390d/src/lib.rs103
4 files changed, 49 insertions, 138 deletions
diff --git a/sound_card_init/max98390d/src/amp_calibration.rs b/sound_card_init/max98390d/src/amp_calibration.rs
index 35340226..50f4227c 100644
--- a/sound_card_init/max98390d/src/amp_calibration.rs
+++ b/sound_card_init/max98390d/src/amp_calibration.rs
@@ -123,10 +123,24 @@ impl<'a> AmpCalibration<'a> {
};
if !self.validate_temperature(temp_cali) {
- info!("invalid temperature: {}.", temp_cali);
- return match datastore {
- None => Err(Error::InvalidTemperature(temp_cali)),
- Some(d) => self.apply_datastore(d),
+ match datastore {
+ None => return Err(Error::InvalidTemperature(temp_cali)),
+ Some(d) => match d {
+ Datastore::UseVPD => {
+ info!("invalid temperature: {}, use VPD values.", temp_cali);
+ return Ok(());
+ }
+ Datastore::DSM { rdc, ambient_temp } => {
+ info!("invalid temperature: {}, use datastore values.", temp_cali);
+ self.card
+ .control_by_name::<IntControl>(&self.setting.amp.rdc_ctrl)?
+ .set(rdc)?;
+ self.card
+ .control_by_name::<IntControl>(&self.setting.amp.temp_ctrl)?
+ .set(ambient_temp)?;
+ return Ok(());
+ }
+ },
};
}
@@ -135,10 +149,22 @@ impl<'a> AmpCalibration<'a> {
} else if diff < CALI_ERROR_LOWER_LIMIT {
match datastore {
None => Datastore::UseVPD.save(self.card.name(), &self.setting.calib_file)?,
- Some(d) => self.apply_datastore(d)?,
+ Some(d) => match d {
+ Datastore::UseVPD => {
+ info!("rdc diff: {}, use VPD values.", diff);
+ }
+ Datastore::DSM { rdc, ambient_temp } => {
+ info!("rdc diff: {}, use datastore values.", diff);
+ self.card
+ .control_by_name::<IntControl>(&self.setting.amp.rdc_ctrl)?
+ .set(rdc)?;
+ self.card
+ .control_by_name::<IntControl>(&self.setting.amp.temp_ctrl)?
+ .set(ambient_temp)?;
+ }
+ },
}
} else {
- info!("apply boot time calibration values.");
self.card
.control_by_name::<IntControl>(&self.setting.amp.rdc_ctrl)?
.set(rdc_cali)?;
@@ -154,22 +180,6 @@ impl<'a> AmpCalibration<'a> {
Ok(())
}
- fn apply_datastore(&mut self, d: Datastore) -> Result<()> {
- info!("apply datastore values.");
- match d {
- Datastore::UseVPD => Ok(()),
- Datastore::DSM { rdc, ambient_temp } => {
- self.card
- .control_by_name::<IntControl>(&self.setting.amp.rdc_ctrl)?
- .set(rdc)?;
- self.card
- .control_by_name::<IntControl>(&self.setting.amp.temp_ctrl)?
- .set(ambient_temp)?;
- Ok(())
- }
- }
- }
-
fn validate_temperature(&self, temp: i32) -> bool {
temp < self.setting.amp.temp_upper_limit && temp > self.setting.amp.temp_lower_limit
}
@@ -203,7 +213,7 @@ impl<'a> AmpCalibration<'a> {
return Err(Error::StartPlaybackTimeout);
} else {
// Spurious wakes. Decrements the sleep duration by the amount slept.
- timeout -= start_time.elapsed();
+ timeout = timeout - start_time.elapsed();
}
}
}
@@ -302,18 +312,4 @@ impl<'a> AmpCalibration<'a> {
Ok(handle)
}
-
- /// Skips max98390d boot time calibration when the speaker may be hot.
- ///
- /// If datastore exists, applies the stored value and sets volume to high.
- /// If datastore does not exist, sets volume to low.
- pub fn hot_speaker_workflow(&mut self) -> Result<()> {
- if let Ok(sci_calib) = Datastore::from_file(self.card.name(), &self.setting.calib_file) {
- self.apply_datastore(sci_calib)?;
- self.set_volume(VolumeMode::High)?;
- return Ok(());
- }
- info!("no datastore, set volume low");
- self.set_volume(VolumeMode::Low)
- }
}
diff --git a/sound_card_init/max98390d/src/datastore.rs b/sound_card_init/max98390d/src/datastore.rs
index 12ebff73..6e221635 100644
--- a/sound_card_init/max98390d/src/datastore.rs
+++ b/sound_card_init/max98390d/src/datastore.rs
@@ -7,10 +7,11 @@ use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use sys_util::info;
-use utils::DATASTORE_DIR;
use crate::error::{Error, Result};
+const DATASTORE_DIR: &str = "/var/lib/sound_card_init";
+
/// `Datastore`, which stores and reads calibration values in yaml format.
#[derive(Debug, Deserialize, Serialize, Copy, Clone)]
pub enum Datastore {
diff --git a/sound_card_init/max98390d/src/error.rs b/sound_card_init/max98390d/src/error.rs
index 778ff961..572340de 100644
--- a/sound_card_init/max98390d/src/error.rs
+++ b/sound_card_init/max98390d/src/error.rs
@@ -6,7 +6,6 @@ use std::fmt;
use std::io;
use std::num::ParseIntError;
use std::sync::PoisonError;
-use std::time;
use remain::sorted;
@@ -22,10 +21,8 @@ pub enum Error {
CrasClientFailed(libcras::Error),
DeserializationFailed(String, serde_yaml::Error),
FileIOFailed(String, io::Error),
- HotSpeaker,
InternalSpeakerNotFound,
InvalidDatastore,
- InvalidShutDownTime,
InvalidTemperature(i32),
LargeCalibrationDiff(i32, i32),
MissingDSMParam,
@@ -33,10 +30,8 @@ pub enum Error {
NewPlayStreamFailed(libcras::BoxError),
NextPlaybackBufferFailed(libcras::BoxError),
PlaybackFailed(io::Error),
- ReadTimestampFailed(utils::error::Error),
SerializationFailed(serde_yaml::Error),
StartPlaybackTimeout,
- SystemTimeError(time::SystemTimeError),
VPDParseFailed(String, ParseIntError),
WorkerPanics,
}
@@ -72,7 +67,6 @@ impl fmt::Display for Error {
CrasClientFailed(e) => write!(f, "failed to create cras client: {}", e),
DeserializationFailed(file, e) => write!(f, "failed to parse {}: {}", file, e),
FileIOFailed(file, e) => write!(f, "{}: {}", file, e),
- InvalidShutDownTime => write!(f, "invalid shutdown time"),
InternalSpeakerNotFound => write!(f, "internal speaker is not found in cras"),
InvalidTemperature(temp) => write!(
f,
@@ -80,21 +74,18 @@ impl fmt::Display for Error {
temp
),
InvalidDatastore => write!(f, "invalid datastore format"),
- HotSpeaker => write!(f, "skip boot time calibration as the speakers may be hot"),
LargeCalibrationDiff(rdc, temp) => write!(
f,
"calibration difference is too large, rdc: {}, temp: {}",
rdc, temp
),
- MissingDSMParam => write!(f, "missing dsm_param.bin"),
MutexPoisonError => write!(f, "mutex is poisoned"),
+ MissingDSMParam => write!(f, "missing dsm_param.bin"),
NewPlayStreamFailed(e) => write!(f, "{}", e),
NextPlaybackBufferFailed(e) => write!(f, "{}", e),
PlaybackFailed(e) => write!(f, "{}", e),
- ReadTimestampFailed(e) => write!(f, "{}", e),
SerializationFailed(e) => write!(f, "failed to serialize yaml: {}", e),
StartPlaybackTimeout => write!(f, "playback is not started in time"),
- SystemTimeError(e) => write!(f, "{}", e),
VPDParseFailed(file, e) => write!(f, "failed to parse vpd {}: {}", file, e),
WorkerPanics => write!(f, "run_play_zero_worker panics"),
}
diff --git a/sound_card_init/max98390d/src/lib.rs b/sound_card_init/max98390d/src/lib.rs
index 44b1c611..7e445c59 100644
--- a/sound_card_init/max98390d/src/lib.rs
+++ b/sound_card_init/max98390d/src/lib.rs
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! `max98390d` crate implements the required initialization workflows.
-//! It currently supports boot time calibration for max98390d.
+//! It currently supports boot time calibration for amplifiers.
#![deny(missing_docs)]
mod amp_calibration;
mod datastore;
@@ -10,20 +10,15 @@ mod error;
mod settings;
mod vpd;
-use std::fs;
-use std::path::{Path, PathBuf};
-use std::time::{Duration, SystemTime, UNIX_EPOCH};
+use std::path::Path;
use cros_alsa::Card;
use sys_util::error;
-use utils::{run_time, shutdown_time, DATASTORE_DIR};
use crate::amp_calibration::{AmpCalibration, VolumeMode};
use crate::error::{Error, Result};
use crate::settings::DeviceSettings;
-const SPEAKER_COOL_DOWN_TIME: Duration = Duration::from_secs(180);
-
/// Performs max98390d boot time calibration.
///
///
@@ -40,27 +35,20 @@ pub fn run_max98390d(snd_card: &str, conf: &str) -> Result<()> {
let mut card = Card::new(snd_card)?;
if !Path::new(&settings.dsm_param).exists() {
- set_all_volume_low(&mut card, &settings);
- return Err(Error::MissingDSMParam);
- }
-
- // Needs to check whether the speakers are over heated if it is not the first time boot.
- if run_time::exists(snd_card) {
- if let Err(err) = check_speaker_over_heated(snd_card, SPEAKER_COOL_DOWN_TIME) {
- match err {
- Error::HotSpeaker => run_all_hot_speaker_workflow(&mut card, &settings),
- _ => {
- // We cannot assume the speakers are not replaced or not over heated
- // when the shutdown time file is invalid; therefore we can not use the datastore
- // value anymore and we can not trigger boot time calibration.
- del_all_datastore(snd_card, &settings);
- set_all_volume_low(&mut card, &settings);
+ for s in &settings.amp_calibrations {
+ let mut amp_calib = match AmpCalibration::new(&mut card, s.clone()) {
+ Ok(amp) => amp,
+ Err(e) => {
+ error!("{}.", e);
+ continue;
}
};
- return Err(err);
- };
+ if let Err(e) = amp_calib.set_volume(VolumeMode::Low) {
+ error!("failed to set volume to low: {}.", e);
+ }
+ }
+ return Err(Error::MissingDSMParam);
}
-
// If some error occurs during the calibration, the iteration will continue running the
// calibration for the next amp.
let results: Vec<Result<()>> = settings
@@ -86,68 +74,3 @@ pub fn run_max98390d(snd_card: &str, conf: &str) -> Result<()> {
Ok(())
}
-
-fn del_all_datastore(snd_card: &str, settings: &DeviceSettings) {
- for s in &settings.amp_calibrations {
- if let Err(e) = fs::remove_file(
- PathBuf::from(DATASTORE_DIR)
- .join(snd_card)
- .join(&s.calib_file),
- ) {
- error!("failed to remove datastore: {}.", e);
- }
- }
-}
-
-fn run_all_hot_speaker_workflow(card: &mut Card, settings: &DeviceSettings) {
- for s in &settings.amp_calibrations {
- let mut amp_calib = match AmpCalibration::new(card, s.clone()) {
- Ok(amp) => amp,
- Err(e) => {
- error!("{}.", e);
- continue;
- }
- };
- if let Err(e) = amp_calib.hot_speaker_workflow() {
- error!("failed to run hot_speaker_workflow: {}.", e);
- }
- }
-}
-
-fn set_all_volume_low(card: &mut Card, settings: &DeviceSettings) {
- for s in &settings.amp_calibrations {
- let mut amp_calib = match AmpCalibration::new(card, s.clone()) {
- Ok(amp) => amp,
- Err(e) => {
- error!("{}.", e);
- continue;
- }
- };
- if let Err(e) = amp_calib.set_volume(VolumeMode::Low) {
- error!("failed to set volume to low: {}.", e);
- }
- }
-}
-
-// If (Current time - the latest CRAS shutdown time) < cool_down_time, we assume that
-// the speakers may be over heated.
-fn check_speaker_over_heated(snd_card: &str, cool_down_time: Duration) -> Result<()> {
- let last_run = run_time::from_file(snd_card).map_err(Error::ReadTimestampFailed)?;
- let last_shutdown = shutdown_time::from_file().map_err(Error::ReadTimestampFailed)?;
- if last_shutdown < last_run {
- return Err(Error::InvalidShutDownTime);
- }
-
- let now = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map_err(Error::SystemTimeError)?;
-
- let elapsed = now
- .checked_sub(last_shutdown)
- .ok_or(Error::InvalidShutDownTime)?;
-
- if elapsed < cool_down_time {
- return Err(Error::HotSpeaker);
- }
- Ok(())
-}