From cfa43aaa7948be5a701ad4099588cf49d5a02708 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Fri, 23 Feb 2024 15:39:09 +0000 Subject: ALSA: hda: cs35l56: Apply amp calibration from EFI data If there are factory calibration settings in EFI, extract the settings and write them to the firmware calibration controls. Signed-off-by: Richard Fitzgerald Link: https://lore.kernel.org/r/20240223153910.2063698-6-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/pci/hda/Kconfig | 2 ++ sound/pci/hda/cs35l56_hda.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 8e0ff70fb610..ce2132ed6dbb 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -162,6 +162,7 @@ config SND_HDA_SCODEC_CS35L56_I2C select SND_HDA_SCODEC_CS35L56 select SND_HDA_CIRRUS_SCODEC select SND_HDA_CS_DSP_CONTROLS + select SND_SOC_CS_AMP_LIB help Say Y or M here to include CS35L56 amplifier support with I2C control. @@ -177,6 +178,7 @@ config SND_HDA_SCODEC_CS35L56_SPI select SND_HDA_SCODEC_CS35L56 select SND_HDA_CIRRUS_SCODEC select SND_HDA_CS_DSP_CONTROLS + select SND_SOC_CS_AMP_LIB help Say Y or M here to include CS35L56 amplifier support with SPI control. diff --git a/sound/pci/hda/cs35l56_hda.c b/sound/pci/hda/cs35l56_hda.c index 75a14ba54fcd..5ad76d6914c3 100644 --- a/sound/pci/hda/cs35l56_hda.c +++ b/sound/pci/hda/cs35l56_hda.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "cirrus_scodec.h" @@ -547,6 +548,22 @@ static void cs35l56_hda_add_dsp_controls(struct cs35l56_hda *cs35l56) hda_cs_dsp_add_controls(&cs35l56->cs_dsp, &info); } +static void cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56) +{ + int ret; + + if (!cs35l56->base.cal_data_valid || cs35l56->base.secured) + return; + + ret = cs_amp_write_cal_coeffs(&cs35l56->cs_dsp, + &cs35l56_calibration_controls, + &cs35l56->base.cal_data); + if (ret < 0) + dev_warn(cs35l56->base.dev, "Failed to write calibration: %d\n", ret); + else + dev_info(cs35l56->base.dev, "Calibration applied\n"); +} + static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56) { const struct firmware *coeff_firmware = NULL; @@ -618,12 +635,8 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56) if (coeff_filename) dev_dbg(cs35l56->base.dev, "Loaded Coefficients: %s\n", coeff_filename); - if (!firmware_missing) { - ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); - if (ret) - goto err_powered_up; - } else if (wmfw_firmware || coeff_firmware) { - /* If we downloaded firmware, reset the device and wait for it to boot */ + /* If we downloaded firmware, reset the device and wait for it to boot */ + if (firmware_missing && (wmfw_firmware || coeff_firmware)) { cs35l56_system_reset(&cs35l56->base, false); regcache_mark_dirty(cs35l56->base.regmap); ret = cs35l56_wait_for_firmware_boot(&cs35l56->base); @@ -646,6 +659,11 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56) if (ret) dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret); + cs35l56_hda_apply_calibration(cs35l56); + ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); + if (ret) + cs_dsp_stop(&cs35l56->cs_dsp); + err_powered_up: if (!cs35l56->base.fw_patched) cs_dsp_power_down(&cs35l56->cs_dsp); @@ -953,6 +971,8 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int id) goto err; } + cs35l56->base.cal_index = cs35l56->index; + cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp); cs35l56->cs_dsp.client_ops = &cs35l56_hda_client_ops; @@ -990,6 +1010,10 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int id) if (ret) goto err; + ret = cs35l56_get_calibration(&cs35l56->base); + if (ret) + goto err; + ret = cs_dsp_halo_init(&cs35l56->cs_dsp); if (ret) { dev_err_probe(cs35l56->base.dev, ret, "cs_dsp_halo_init failed\n"); @@ -1064,10 +1088,11 @@ const struct dev_pm_ops cs35l56_hda_pm_ops = { EXPORT_SYMBOL_NS_GPL(cs35l56_hda_pm_ops, SND_HDA_SCODEC_CS35L56); MODULE_DESCRIPTION("CS35L56 HDA Driver"); +MODULE_IMPORT_NS(FW_CS_DSP); MODULE_IMPORT_NS(SND_HDA_CIRRUS_SCODEC); MODULE_IMPORT_NS(SND_HDA_CS_DSP_CONTROLS); MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED); +MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); MODULE_AUTHOR("Richard Fitzgerald "); MODULE_AUTHOR("Simon Trimmer "); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(FW_CS_DSP); -- cgit