Unverified Commit 9f774c75 authored by Shenghao Ding's avatar Shenghao Ding Committed by Mark Brown
Browse files

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: ef3bcde7 ("ASoC: tas2781: Add tas2781 driver")
Signed-off-by: default avatarShenghao Ding <shenghao-ding@ti.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240614133646.910-1-shenghao-ding@ti.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 7109f10c
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -117,10 +117,17 @@ struct tasdevice_fw {
	struct device *dev;
};

enum tasdevice_dsp_fw_state {
	TASDEVICE_DSP_FW_NONE = 0,
enum tasdevice_fw_state {
	/* Driver in startup mode, not load any firmware. */
	TASDEVICE_DSP_FW_PENDING,
	/* DSP firmware in the system, but parsing error. */
	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,
};

+13 −5
Original line number Diff line number Diff line
@@ -2324,13 +2324,20 @@ void tasdevice_tuning_switch(void *context, int state)
	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
	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;
	}

	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 */
			profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
			tasdevice_select_tuningprm_cfg(tas_priv,
@@ -2340,10 +2347,11 @@ void tasdevice_tuning_switch(void *context, int state)

		tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
			TASDEVICE_BIN_BLK_PRE_POWER_UP);
	} else
	} else {
		tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
			TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
	}
}
EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch,
	SND_SOC_TAS2781_FMWLIB);

+26 −13
Original line number Diff line number Diff line
@@ -380,23 +380,37 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
	mutex_lock(&tas_priv->codec_lock);

	ret = tasdevice_rca_parser(tas_priv, fmw);
	if (ret)
	if (ret) {
		tasdevice_config_info_remove(tas_priv);
		goto out;
	}
	tasdevice_create_control(tas_priv);

	tasdevice_dsp_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",
		tas_priv->dev_name);
	ret = tasdevice_dsp_parser(tas_priv);
	if (ret) {
		dev_err(tas_priv->dev, "dspfw load %s error\n",
			tas_priv->coef_binaryname);
		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
		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;

@@ -417,9 +431,8 @@ static void tasdevice_fw_ready(const struct firmware *fmw,
	tasdevice_prmg_load(tas_priv, 0);
	tas_priv->cur_prog = 0;
out:
	if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
		/*If DSP FW fail, kcontrol won't be created */
		tasdevice_config_info_remove(tas_priv);
	if (tas_priv->fw_state == TASDEVICE_RCA_FW_OK) {
		/* If DSP FW fail, DSP kcontrol won't be created. */
		tasdevice_dsp_remove(tas_priv);
	}
	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 tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec);
	int ret = 0;

	if (tas_priv->fw_state != TASDEVICE_DSP_FW_ALL_OK) {
		dev_err(tas_priv->dev, "DSP bin file not loaded\n");
		ret = -EINVAL;
	switch (tas_priv->fw_state) {
	case TASDEVICE_RCA_FW_OK:
	case TASDEVICE_DSP_FW_ALL_OK:
		return 0;
	default:
		return -EINVAL;
	}

	return ret;
}

static int tasdevice_hw_params(struct snd_pcm_substream *substream,