[PATCH v2] ASoC: tas2783-sdw: add firmware download status check
Baojun Xu <[email protected]>
| Newsgroups | org.alsa-project.alsa-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-sound |
|---|---|
| Message-ID | <[email protected]> |
Currently, the firmware download is unnecessarily triggered on every system resume from suspend, causing significant wake-up latency. However, this step is redundant if the AMP remains powered on. Furthermore, certain memory pages (addresses > 0xc60000) are skipped even after an AMP reset. Signed-off-by: Baojun Xu <[email protected]> --- v2: - Update register address from 0x07 to 7 and keep the line within the 80-character limit. - Remove stray/unnecessary changes. - Change variable type to unsigned int to comply with API requirements. - Replace usleep_range() with fsleep(). - Set idle_bias_on to 0 to enable low-power mode. - Reactivate the AMP after resume. --- sound/soc/codecs/tas2783-sdw.c | 55 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c index c217da5fccdf..8fc679d460d9 100644 --- a/sound/soc/codecs/tas2783-sdw.c +++ b/sound/soc/codecs/tas2783-sdw.c @@ -97,6 +97,7 @@ struct tas2783_prv { u8 rca_binaryname[64]; u8 dev_name[32]; bool hw_init; + bool first_hw_init; /* wq for firmware download */ wait_queue_head_t fw_wait; bool fw_dl_task_done; @@ -783,14 +784,16 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context) file->version, file->length, file->dest_addr, file->fw_data); - ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral, - file->dest_addr, - file->length, - file->fw_data); - if (ret < 0) { - dev_err(tas_dev->dev, - "FW download failed: %d", ret); - break; + if (!tas_dev->first_hw_init || file->dest_addr < 0xc60000) { + ret = sdw_nwrite_no_pm(tas_dev->sdw_peripheral, + file->dest_addr, + file->length, + file->fw_data); + if (ret < 0) { + dev_err(tas_dev->dev, + "FW download failed: %d", ret); + break; + } } cur_file++; } @@ -801,6 +804,8 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context) ret = -EINVAL; } else { tas2783_update_calibdata(tas_dev); + regmap_write(tas_dev->regmap, TASDEV_REG_SDW(0, 0, 7), 0x22); + tas_dev->first_hw_init = true; } out: @@ -940,7 +945,7 @@ static s32 tas_sdw_hw_params(struct snd_pcm_substream *substream, TAS2783_SDCA_POW_STATE_ON); if (!ret) break; - usleep_range(2000, 2200); + fsleep(2200); } while (retry--); } @@ -1038,7 +1043,7 @@ static const struct snd_soc_component_driver soc_codec_driver_tasdevice = { .num_dapm_widgets = ARRAY_SIZE(tas_dapm_widgets), .dapm_routes = tas_audio_map, .num_dapm_routes = ARRAY_SIZE(tas_audio_map), - .idle_bias_on = 1, + .idle_bias_on = 0, .endianness = 1, }; @@ -1171,25 +1176,29 @@ static s32 tas_fw_load(struct tas2783_prv *tas_dev, struct sdw_slave *slave) static s32 tas_io_init(struct device *dev, struct sdw_slave *slave) { struct tas2783_prv *tas_dev = dev_get_drvdata(dev); + unsigned int val; s32 ret; if (tas_dev->hw_init) return 0; - tas_dev->fw_dl_success = false; + regmap_read(tas_dev->regmap, TASDEV_REG_SDW(0, 0, 7), &val); + /* Check if the AMP is in reset status. */ + if (val == 0x20) { + tas_dev->fw_dl_success = false; - ret = regmap_write(tas_dev->regmap, TAS2783_SW_RESET, 0x1); - if (ret) { - dev_err(dev, "sw reset failed, err=%d", ret); - return ret; - } - usleep_range(2000, 2200); + ret = regmap_write(tas_dev->regmap, TAS2783_SW_RESET, 0x1); + if (ret) { + dev_err(dev, "sw reset failed, err=%d", ret); + return ret; + } + fsleep(2200); - tas_dev->fw_use_fallback = false; - ret = tas_fw_load(tas_dev, slave); - if (!ret && tas_dev->fw_use_fallback) + tas_dev->fw_use_fallback = false; ret = tas_fw_load(tas_dev, slave); - + if (!ret && tas_dev->fw_use_fallback) + ret = tas_fw_load(tas_dev, slave); + } if (!ret) { if (tas_dev->sa_func_data) ret = sdca_regmap_write_init(dev, tas_dev->regmap, @@ -1197,7 +1206,8 @@ static s32 tas_io_init(struct device *dev, struct sdw_slave *slave) else ret = regmap_multi_reg_write(tas_dev->regmap, tas2783_init_seq, ARRAY_SIZE(tas2783_init_seq)); - + /* Re-active AMP after resume. */ + regmap_write(tas_dev->regmap, TASDEV_REG_SDW(0, 0, 2), 0); if (ret) dev_err(tas_dev->dev, "init writes failed, err=%d", ret); @@ -1357,6 +1367,7 @@ static s32 tas_sdw_probe(struct sdw_slave *peripheral, tas_dev->dev = dev; tas_dev->sdw_peripheral = peripheral; tas_dev->hw_init = false; + tas_dev->first_hw_init = false; mutex_init(&tas_dev->calib_lock); mutex_init(&tas_dev->pde_lock); -- 2.25.1