// 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, PathBuf},
};

use cros_alsa::{Card, IntControl, SwitchControl};
use dsm::{CalibData, Error, Result, SpeakerStatus, TempConverter, ZeroPlayer, DSM};

use crate::{Amp, CONF_DIR};
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.
    ///
    /// # 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) -> Result<Self> {
        let config_path = PathBuf::from(CONF_DIR)
            .join(card_name)
            .with_extension("yaml");
        let conf =
            fs::read_to_string(&config_path).map_err(|e| Error::FileIOFailed(config_path, 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);
    }
}
