summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/cs35l56.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2024-03-11 16:18:47 +0100
committerTakashi Iwai <tiwai@suse.de>2024-03-11 16:18:47 +0100
commitf5d9ddf1214bf878ca69c905c2f410c5b51de99c (patch)
tree3ea7bf6f519a490f72cf5f9023b5c0a6dff0fea0 /sound/soc/codecs/cs35l56.c
parent6719cd5e45111449f4021e08f2e488f17a9b292b (diff)
parent6c023ad32b192dea51a4f842cc6ecf89bb6238c9 (diff)
Merge tag 'asoc-v6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v6.9 This has been quite a small release, there's a lot of driver specific cleanups and minor enhancements but hardly anything on the core and only one new driver. Highlights include: - SoundWire support for AMD ACP 6.3 systems. - Support for reporting version information for AVS firmware. - Support DSPless mode for Intel Soundwire systems. - Support for configuring CS35L56 amplifiers using EFI calibration data. - Log which component is being operated on as part of power management trace events. - Support for Microchip SAM9x7, NXP i.MX95 and Qualcomm WCD939x
Diffstat (limited to 'sound/soc/codecs/cs35l56.c')
-rw-r--r--sound/soc/codecs/cs35l56.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 450a163e66287..8d2f021fb3628 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -23,6 +23,7 @@
#include <linux/soundwire/sdw.h>
#include <linux/types.h>
#include <linux/workqueue.h>
+#include <sound/cs-amp-lib.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -802,16 +803,44 @@ static struct snd_soc_dai_driver cs35l56_dai[] = {
}
};
+static int cs35l56_write_cal(struct cs35l56_private *cs35l56)
+{
+ int ret;
+
+ if (cs35l56->base.secured || !cs35l56->base.cal_data_valid)
+ return -ENODATA;
+
+ ret = wm_adsp_run(&cs35l56->dsp);
+ if (ret)
+ return ret;
+
+ ret = cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp,
+ &cs35l56_calibration_controls,
+ &cs35l56->base.cal_data);
+
+ wm_adsp_stop(&cs35l56->dsp);
+
+ if (ret == 0)
+ dev_info(cs35l56->base.dev, "Calibration applied\n");
+
+ return ret;
+}
+
static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
{
int ret;
/* Use wm_adsp to load and apply the firmware patch and coefficient files */
ret = wm_adsp_power_up(&cs35l56->dsp, true);
- if (ret)
+ if (ret) {
dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
- else
- cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);
+ return;
+ }
+
+ cs35l56_write_cal(cs35l56);
+
+ /* Always REINIT after applying patch or coefficients */
+ cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);
}
static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing)
@@ -874,6 +903,9 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
CS35L56_FIRMWARE_MISSING);
cs35l56->base.fw_patched = true;
+ if (cs35l56_write_cal(cs35l56) == 0)
+ cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);
+
err_unlock:
mutex_unlock(&cs35l56->base.irq_lock);
err:
@@ -1368,6 +1400,7 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
init_completion(&cs35l56->init_completion);
mutex_init(&cs35l56->base.irq_lock);
+ cs35l56->base.cal_index = -1;
cs35l56->speaker_id = -ENOENT;
dev_set_drvdata(cs35l56->base.dev, cs35l56);
@@ -1469,6 +1502,10 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
if (ret)
return ret;
+ ret = cs35l56_get_calibration(&cs35l56->base);
+ if (ret)
+ return ret;
+
if (!cs35l56->base.reset_gpio) {
dev_dbg(cs35l56->base.dev, "No reset gpio: using soft reset\n");
cs35l56->soft_resetting = true;
@@ -1553,6 +1590,7 @@ EXPORT_NS_GPL_DEV_PM_OPS(cs35l56_pm_ops_i2c_spi, SND_SOC_CS35L56_CORE) = {
MODULE_DESCRIPTION("ASoC CS35L56 driver");
MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
+MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB);
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
MODULE_LICENSE("GPL");