diff options
Diffstat (limited to 'sound_card_init/max98390d/src/lib.rs')
-rw-r--r-- | sound_card_init/max98390d/src/lib.rs | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/sound_card_init/max98390d/src/lib.rs b/sound_card_init/max98390d/src/lib.rs deleted file mode 100644 index 44b1c611..00000000 --- a/sound_card_init/max98390d/src/lib.rs +++ /dev/null @@ -1,153 +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` crate implements the required initialization workflows. -//! It currently supports boot time calibration for max98390d. -#![deny(missing_docs)] -mod amp_calibration; -mod datastore; -mod error; -mod settings; -mod vpd; - -use std::fs; -use std::path::{Path, PathBuf}; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -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. -/// -/// -/// # Arguments -/// -/// * `snd_card` - The sound card name, ex: sofcmlmax98390d. -/// * `conf` - The `DeviceSettings` in yaml format. -/// -/// # Errors -/// -/// If any amplifiers fail to complete the calibration. -pub fn run_max98390d(snd_card: &str, conf: &str) -> Result<()> { - let settings = DeviceSettings::from_yaml_str(conf)?; - 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); - } - }; - return Err(err); - }; - } - - // If some error occurs during the calibration, the iteration will continue running the - // calibration for the next amp. - let results: Vec<Result<()>> = settings - .amp_calibrations - .into_iter() - .map(|s| { - let mut amp_calib = AmpCalibration::new(&mut card, s)?; - amp_calib.set_volume(VolumeMode::Low)?; - amp_calib.run()?; - amp_calib.set_volume(VolumeMode::High)?; - Ok(()) - }) - .filter_map(|res| res.err()) - .map(|e| { - error!("calibration error: {}. volume remains low.", e); - Err(e) - }) - .collect(); - - if !results.is_empty() { - return Err(Error::CalibrationFailed); - } - - 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(()) -} |