[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240512025040.1276-2-shenghao-ding@ti.com>
Date: Sun, 12 May 2024 10:50:38 +0800
From: Shenghao Ding <shenghao-ding@...com>
To: <broonie@...nel.org>
CC: <andriy.shevchenko@...ux.intel.com>, <lgirdwood@...il.com>,
<perex@...ex.cz>, <pierre-louis.bossart@...ux.intel.com>,
<13916275206@....com>, <alsa-devel@...a-project.org>,
<linux-kernel@...r.kernel.org>, <liam.r.girdwood@...el.com>,
<bard.liao@...el.com>, <yung-chuan.liao@...ux.intel.com>,
<kevin-lu@...com>, <cameron.berkenpas@...il.com>, <tiwai@...e.de>,
<baojun.xu@...com>, <soyer@....hu>, <Baojun.Xu@....com>,
Shenghao Ding <shenghao-ding@...com>
Subject: [PATCH v5 2/3] ASoC: tas2781: Fix wrong loading calibrated data sequence
Calibrated data will be set to default after loading DSP config params,
which will cause speaker protection work abnormally. Reload calibrated
data after loading DSP config params.
Fixes: ef3bcde75d06 ("ASoc: tas2781: Add tas2781 driver")
Signed-off-by: Shenghao Ding <shenghao-ding@...com>
---
v5:
- No change.
v4:
- Use the the culprit of the bug itself as the fixes tag.
- Better variant for tasdev_load_calibrated_data in order to much easier
to read and understand and maintain, as it makes harder to squeeze the
code.
- Fix the indentation and move operator to the previous line.
v3:
- Remove redundant return in tasdev_load_calibrated_data
- Put the second function parameter into the previous line for
tasdev_load_calibrated_data
- | Reported-by: kernel test robot <lkp@...el.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202405021200.YHInjV43-lkp@intel.com/
v2:
- In the Subject, fixed --> Fix
- In tas2781-fmwlib.c, tasdevice-fmw.c ---> tas2781-fmwlib.c
- dsp --> DSP
- Remove unneeded parentheses for & (dereference) operator
- Add Fixes tag
v1:
- Download calibrated data after loading the new DSP config params
- call tasdevice_prmg_load instead of tasdevice_prmg_calibdata_load, it
is unnecessary to load calibrated data after loading DSP program. Load
it after loading DSP config params each time.
- Remove tasdevice_prmg_calibdata_load, because it is unnecessary to load
calibrated data after loading DSP program.
---
sound/soc/codecs/tas2781-fmwlib.c | 103 ++++++++----------------------
1 file changed, 27 insertions(+), 76 deletions(-)
diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c
index a6be81adcb83..265a8ca25cbb 100644
--- a/sound/soc/codecs/tas2781-fmwlib.c
+++ b/sound/soc/codecs/tas2781-fmwlib.c
@@ -2151,6 +2151,24 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv,
return ret;
}
+static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
+{
+ struct tasdevice_calibration *cal;
+ struct tasdevice_fw *cal_fmw;
+
+ cal_fmw = priv->tasdevice[i].cali_data_fmw;
+
+ /* No calibrated data for current devices, playback will go ahead. */
+ if (!cal_fmw)
+ return;
+
+ cal = cal_fmw->calibrations;
+ if (cal)
+ return;
+
+ load_calib_data(priv, &cal->dev_data);
+}
+
int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
int cfg_no, int rca_conf_no)
{
@@ -2210,21 +2228,9 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
for (i = 0; i < tas_priv->ndev; i++) {
if (tas_priv->tasdevice[i].is_loaderr == true)
continue;
- else if (tas_priv->tasdevice[i].is_loaderr == false
- && tas_priv->tasdevice[i].is_loading == true) {
- struct tasdevice_fw *cal_fmw =
- tas_priv->tasdevice[i].cali_data_fmw;
-
- if (cal_fmw) {
- struct tasdevice_calibration
- *cal = cal_fmw->calibrations;
-
- if (cal)
- load_calib_data(tas_priv,
- &(cal->dev_data));
- }
+ if (tas_priv->tasdevice[i].is_loaderr == false &&
+ tas_priv->tasdevice[i].is_loading == true)
tas_priv->tasdevice[i].cur_prog = prm_no;
- }
}
}
@@ -2245,11 +2251,15 @@ int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
tasdevice_load_data(tas_priv, &(conf->dev_data));
for (i = 0; i < tas_priv->ndev; i++) {
if (tas_priv->tasdevice[i].is_loaderr == true) {
- status |= 1 << (i + 4);
+ status |= BIT(i + 4);
continue;
- } else if (tas_priv->tasdevice[i].is_loaderr == false
- && tas_priv->tasdevice[i].is_loading == true)
+ }
+
+ if (tas_priv->tasdevice[i].is_loaderr == false &&
+ tas_priv->tasdevice[i].is_loading == true) {
+ tasdev_load_calibrated_data(tas_priv, i);
tas_priv->tasdevice[i].cur_conf = cfg_no;
+ }
}
} else
dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n",
@@ -2308,65 +2318,6 @@ int tasdevice_prmg_load(void *context, int prm_no)
}
EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, SND_SOC_TAS2781_FMWLIB);
-int tasdevice_prmg_calibdata_load(void *context, int prm_no)
-{
- struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
- struct tasdevice_fw *tas_fmw = tas_priv->fmw;
- struct tasdevice_prog *program;
- int prog_status = 0;
- int i;
-
- if (!tas_fmw) {
- dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
- goto out;
- }
-
- if (prm_no >= tas_fmw->nr_programs) {
- dev_err(tas_priv->dev,
- "%s: prm(%d) is not in range of Programs %u\n",
- __func__, prm_no, tas_fmw->nr_programs);
- goto out;
- }
-
- for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
- if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
- tas_priv->tasdevice[i].cur_conf = -1;
- tas_priv->tasdevice[i].is_loading = true;
- prog_status++;
- }
- tas_priv->tasdevice[i].is_loaderr = false;
- }
-
- if (prog_status) {
- program = &(tas_fmw->programs[prm_no]);
- tasdevice_load_data(tas_priv, &(program->dev_data));
- for (i = 0; i < tas_priv->ndev; i++) {
- if (tas_priv->tasdevice[i].is_loaderr == true)
- continue;
- else if (tas_priv->tasdevice[i].is_loaderr == false
- && tas_priv->tasdevice[i].is_loading == true) {
- struct tasdevice_fw *cal_fmw =
- tas_priv->tasdevice[i].cali_data_fmw;
-
- if (cal_fmw) {
- struct tasdevice_calibration *cal =
- cal_fmw->calibrations;
-
- if (cal)
- load_calib_data(tas_priv,
- &(cal->dev_data));
- }
- tas_priv->tasdevice[i].cur_prog = prm_no;
- }
- }
- }
-
-out:
- return prog_status;
-}
-EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_calibdata_load,
- SND_SOC_TAS2781_FMWLIB);
-
void tasdevice_tuning_switch(void *context, int state)
{
struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
--
2.34.1
Powered by blists - more mailing lists