Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: ef3bcde75d06 ("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>

authored by

Shenghao Ding and committed by
Mark Brown
9f774c75 7109f10c

+48 -20
+9 -2
include/sound/tas2781-dsp.h
··· 117 117 struct device *dev; 118 118 }; 119 119 120 - enum tasdevice_dsp_fw_state { 121 - TASDEVICE_DSP_FW_NONE = 0, 120 + enum tasdevice_fw_state { 121 + /* Driver in startup mode, not load any firmware. */ 122 122 TASDEVICE_DSP_FW_PENDING, 123 + /* DSP firmware in the system, but parsing error. */ 123 124 TASDEVICE_DSP_FW_FAIL, 125 + /* 126 + * Only RCA (Reconfigurable Architecture) firmware load 127 + * successfully. 128 + */ 129 + TASDEVICE_RCA_FW_OK, 130 + /* Both RCA and DSP firmware load successfully. */ 124 131 TASDEVICE_DSP_FW_ALL_OK, 125 132 }; 126 133
+13 -5
sound/soc/codecs/tas2781-fmwlib.c
··· 2324 2324 struct tasdevice_fw *tas_fmw = tas_priv->fmw; 2325 2325 int profile_cfg_id = tas_priv->rcabin.profile_cfg_id; 2326 2326 2327 - if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) { 2328 - dev_err(tas_priv->dev, "DSP bin file not loaded\n"); 2327 + /* 2328 + * Only RCA-based Playback can still work with no dsp program running 2329 + * inside the chip. 2330 + */ 2331 + switch (tas_priv->fw_state) { 2332 + case TASDEVICE_RCA_FW_OK: 2333 + case TASDEVICE_DSP_FW_ALL_OK: 2334 + break; 2335 + default: 2329 2336 return; 2330 2337 } 2331 2338 2332 2339 if (state == 0) { 2333 - if (tas_priv->cur_prog < tas_fmw->nr_programs) { 2334 - /*dsp mode or tuning mode*/ 2340 + if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) { 2341 + /* dsp mode or tuning mode */ 2335 2342 profile_cfg_id = tas_priv->rcabin.profile_cfg_id; 2336 2343 tasdevice_select_tuningprm_cfg(tas_priv, 2337 2344 tas_priv->cur_prog, tas_priv->cur_conf, ··· 2347 2340 2348 2341 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id, 2349 2342 TASDEVICE_BIN_BLK_PRE_POWER_UP); 2350 - } else 2343 + } else { 2351 2344 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id, 2352 2345 TASDEVICE_BIN_BLK_PRE_SHUTDOWN); 2346 + } 2353 2347 } 2354 2348 EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch, 2355 2349 SND_SOC_TAS2781_FMWLIB);
+26 -13
sound/soc/codecs/tas2781-i2c.c
··· 380 380 mutex_lock(&tas_priv->codec_lock); 381 381 382 382 ret = tasdevice_rca_parser(tas_priv, fmw); 383 - if (ret) 383 + if (ret) { 384 + tasdevice_config_info_remove(tas_priv); 384 385 goto out; 386 + } 385 387 tasdevice_create_control(tas_priv); 386 388 387 389 tasdevice_dsp_remove(tas_priv); 388 390 tasdevice_calbin_remove(tas_priv); 389 - tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING; 391 + /* 392 + * The baseline is the RCA-only case, and then the code attempts to 393 + * load DSP firmware but in case of failures just keep going, i.e. 394 + * failing to load DSP firmware is NOT an error. 395 + */ 396 + tas_priv->fw_state = TASDEVICE_RCA_FW_OK; 390 397 scnprintf(tas_priv->coef_binaryname, 64, "%s_coef.bin", 391 398 tas_priv->dev_name); 392 399 ret = tasdevice_dsp_parser(tas_priv); 393 400 if (ret) { 394 401 dev_err(tas_priv->dev, "dspfw load %s error\n", 395 402 tas_priv->coef_binaryname); 396 - tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; 397 403 goto out; 398 404 } 399 - tasdevice_dsp_create_ctrls(tas_priv); 405 + 406 + /* 407 + * If no dsp-related kcontrol created, the dsp resource will be freed. 408 + */ 409 + ret = tasdevice_dsp_create_ctrls(tas_priv); 410 + if (ret) { 411 + dev_err(tas_priv->dev, "dsp controls error\n"); 412 + goto out; 413 + } 400 414 401 415 tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; 402 416 ··· 431 417 tasdevice_prmg_load(tas_priv, 0); 432 418 tas_priv->cur_prog = 0; 433 419 out: 434 - if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) { 435 - /*If DSP FW fail, kcontrol won't be created */ 436 - tasdevice_config_info_remove(tas_priv); 420 + if (tas_priv->fw_state == TASDEVICE_RCA_FW_OK) { 421 + /* If DSP FW fail, DSP kcontrol won't be created. */ 437 422 tasdevice_dsp_remove(tas_priv); 438 423 } 439 424 mutex_unlock(&tas_priv->codec_lock); ··· 479 466 { 480 467 struct snd_soc_component *codec = dai->component; 481 468 struct tasdevice_priv *tas_priv = snd_soc_component_get_drvdata(codec); 482 - int ret = 0; 483 469 484 - if (tas_priv->fw_state != TASDEVICE_DSP_FW_ALL_OK) { 485 - dev_err(tas_priv->dev, "DSP bin file not loaded\n"); 486 - ret = -EINVAL; 470 + switch (tas_priv->fw_state) { 471 + case TASDEVICE_RCA_FW_OK: 472 + case TASDEVICE_DSP_FW_ALL_OK: 473 + return 0; 474 + default: 475 + return -EINVAL; 487 476 } 488 - 489 - return ret; 490 477 } 491 478 492 479 static int tasdevice_hw_params(struct snd_pcm_substream *substream,