mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
ASoc: tas2781: Enable RCA-based playback without DSP firmware download
In only loading RCA (Reconfigurable Architecture) binary case, no DSP
program will be working inside tas2563/tas2781, that is dsp-bypass mode,
do not support speaker protection, or audio acoustic algorithms in this
mode.
Fixes: ef3bcde75d
("ASoC: tas2781: Add tas2781 driver")
Signed-off-by: Shenghao Ding <shenghao-ding@ti.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240614133646.910-1-shenghao-ding@ti.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
7109f10ca4
commit
9f774c757e
@ -117,10 +117,17 @@ struct tasdevice_fw {
|
|||||||
struct device *dev;
|
struct device *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum tasdevice_dsp_fw_state {
|
enum tasdevice_fw_state {
|
||||||
TASDEVICE_DSP_FW_NONE = 0,
|
/* Driver in startup mode, not load any firmware. */
|
||||||
TASDEVICE_DSP_FW_PENDING,
|
TASDEVICE_DSP_FW_PENDING,
|
||||||
|
/* DSP firmware in the system, but parsing error. */
|
||||||
TASDEVICE_DSP_FW_FAIL,
|
TASDEVICE_DSP_FW_FAIL,
|
||||||
|
/*
|
||||||
|
* Only RCA (Reconfigurable Architecture) firmware load
|
||||||
|
* successfully.
|
||||||
|
*/
|
||||||
|
TASDEVICE_RCA_FW_OK,
|
||||||
|
/* Both RCA and DSP firmware load successfully. */
|
||||||
TASDEVICE_DSP_FW_ALL_OK,
|
TASDEVICE_DSP_FW_ALL_OK,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2324,14 +2324,21 @@ void tasdevice_tuning_switch(void *context, int state)
|
|||||||
struct tasdevice_fw *tas_fmw = tas_priv->fmw;
|
struct tasdevice_fw *tas_fmw = tas_priv->fmw;
|
||||||
int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
|
int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
|
||||||
|
|
||||||
if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
|
/*
|
||||||
dev_err(tas_priv->dev, "DSP bin file not loaded\n");
|
* Only RCA-based Playback can still work with no dsp program running
|
||||||
|
* inside the chip.
|
||||||
|
*/
|
||||||
|
switch (tas_priv->fw_state) {
|
||||||
|
case TASDEVICE_RCA_FW_OK:
|
||||||
|
case TASDEVICE_DSP_FW_ALL_OK:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == 0) {
|
if (state == 0) {
|
||||||
if (tas_priv->cur_prog < tas_fmw->nr_programs) {
|
if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) {
|
||||||
/*dsp mode or tuning mode*/
|
/* dsp mode or tuning mode */
|
||||||
profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
|
profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
|
||||||
tasdevice_select_tuningprm_cfg(tas_priv,
|
tasdevice_select_tuningprm_cfg(tas_priv,
|
||||||
tas_priv->cur_prog, tas_priv->cur_conf,
|
tas_priv->cur_prog, tas_priv->cur_conf,
|
||||||
@ -2340,9 +2347,10 @@ void tasdevice_tuning_switch(void *context, int state)
|
|||||||
|
|
||||||
tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
|
tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
|
||||||
TASDEVICE_BIN_BLK_PRE_POWER_UP);
|
TASDEVICE_BIN_BLK_PRE_POWER_UP);
|
||||||
} else
|
} else {
|
||||||
tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
|
tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
|
||||||
TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
|
TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch,
|
EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch,
|
||||||
SND_SOC_TAS2781_FMWLIB);
|
SND_SOC_TAS2781_FMWLIB);
|
||||||
|
@ -380,23 +380,37 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
|
|||||||
mutex_lock(&tas_priv->codec_lock);
|
mutex_lock(&tas_priv->codec_lock);
|
||||||
|
|
||||||
ret = tasdevice_rca_parser(tas_priv, fmw);
|
ret = tasdevice_rca_parser(tas_priv, fmw);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
tasdevice_config_info_remove(tas_priv);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
tasdevice_create_control(tas_priv);
|
tasdevice_create_control(tas_priv);
|
||||||
|
|
||||||
tasdevice_dsp_remove(tas_priv);
|
tasdevice_dsp_remove(tas_priv);
|
||||||
tasdevice_calbin_remove(tas_priv);
|
tasdevice_calbin_remove(tas_priv);
|
||||||
tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;
|
/*
|
||||||
|
* The baseline is the RCA-only case, and then the code attempts to
|
||||||
|
* load DSP firmware but in case of failures just keep going, i.e.
|
||||||
|
* failing to load DSP firmware is NOT an error.
|
||||||
|
*/
|
||||||
|
tas_priv->fw_state = TASDEVICE_RCA_FW_OK;
|
||||||
scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin",
|
scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin",
|
||||||
tas_priv->dev_name);
|
tas_priv->dev_name);
|
||||||
ret = tasdevice_dsp_parser(tas_priv);
|
ret = tasdevice_dsp_parser(tas_priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(tas_priv->dev, "dspfw load %s error\n",
|
dev_err(tas_priv->dev, "dspfw load %s error\n",
|
||||||
tas_priv->coef_binaryname);
|
tas_priv->coef_binaryname);
|
||||||
tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tasdevice_dsp_create_ctrls(tas_priv);
|
|
||||||
|
/*
|
||||||
|
* If no dsp-related kcontrol created, the dsp resource will be freed.
|
||||||
|
*/
|
||||||
|
ret = tasdevice_dsp_create_ctrls(tas_priv);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(tas_priv->dev, "dsp controls error\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
|
tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;
|
||||||
|
|
||||||
@ -417,9 +431,8 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
|
|||||||
tasdevice_prmg_load(tas_priv, 0);
|
tasdevice_prmg_load(tas_priv, 0);
|
||||||
tas_priv->cur_prog = 0;
|
tas_priv->cur_prog = 0;
|
||||||
out:
|
out:
|
||||||
if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
|
if (tas_priv->fw_state == TASDEVICE_RCA_FW_OK) {
|
||||||
/*If DSP FW fail, kcontrol won't be created */
|
/* If DSP FW fail, DSP kcontrol won't be created. */
|
||||||
tasdevice_config_info_remove(tas_priv);
|
|
||||||
tasdevice_dsp_remove(tas_priv);
|
tasdevice_dsp_remove(tas_priv);
|
||||||
}
|
}
|
||||||
mutex_unlock(&tas_priv->codec_lock);
|
mutex_unlock(&tas_priv->codec_lock);
|
||||||
@ -466,14 +479,14 @@ static int tasdevice_startup(struct snd_pcm_substream *substream,
|
|||||||
{
|
{
|
||||||
struct snd_soc_component *codec = dai->component;
|
struct snd_soc_component *codec = dai->component;
|
||||||
struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec);
|
struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec);
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (tas_priv->fw_state != TASDEVICE_DSP_FW_ALL_OK) {
|
switch (tas_priv->fw_state) {
|
||||||
dev_err(tas_priv->dev, "DSP bin file not loaded\n");
|
case TASDEVICE_RCA_FW_OK:
|
||||||
ret = -EINVAL;
|
case TASDEVICE_DSP_FW_ALL_OK:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tasdevice_hw_params(struct snd_pcm_substream *substream,
|
static int tasdevice_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
Loading…
Reference in New Issue
Block a user