diff --git a/sound/soc/tegra-alt/include/tegra210_i2s_alt.h b/sound/soc/tegra-alt/include/tegra210_i2s_alt.h index 16b98cac..e3b0de7b 100644 --- a/sound/soc/tegra-alt/include/tegra210_i2s_alt.h +++ b/sound/soc/tegra-alt/include/tegra210_i2s_alt.h @@ -209,7 +209,6 @@ struct tegra210_i2s { bool loopback; unsigned int format; unsigned int rx_fifo_th; /* should be programmed interms of frames */ - void __iomem *base_addr; }; #endif diff --git a/sound/soc/tegra-alt/tegra210_admaif_alt.c b/sound/soc/tegra-alt/tegra210_admaif_alt.c index bf49cd63..28210884 100644 --- a/sound/soc/tegra-alt/tegra210_admaif_alt.c +++ b/sound/soc/tegra-alt/tegra210_admaif_alt.c @@ -16,10 +16,8 @@ * along with this program. If not, see . */ -#include #include #include -#include #include #include #include @@ -431,8 +429,8 @@ static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction) regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable); /* wait until ADMAIF TX/RX status is disabled */ - ret = readl_poll_timeout_atomic(REG_IOVA(status_reg), val, - !(val & enable), 10, 10000); + ret = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val, + !(val & enable), 10, 10000); /* Timeout may be hit if sink gets closed/blocked ahead of source */ if (ret < 0) @@ -443,9 +441,9 @@ static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction) regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET); /* wait till SW reset is complete */ - ret = readl_poll_timeout_atomic(REG_IOVA(reset_reg), val, - !(val & SW_RESET_MASK & SW_RESET), - 10, 10000); + ret = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val, + !(val & SW_RESET_MASK & SW_RESET), + 10, 10000); if (ret < 0) { dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n", dai->id + 1, dir_name); diff --git a/sound/soc/tegra-alt/tegra210_adx_alt.c b/sound/soc/tegra-alt/tegra210_adx_alt.c index 324d6adb..1f96fe33 100644 --- a/sound/soc/tegra-alt/tegra210_adx_alt.c +++ b/sound/soc/tegra-alt/tegra210_adx_alt.c @@ -16,7 +16,6 @@ * along with this program. If not, see . */ -#include #include #include #include @@ -155,68 +154,47 @@ static void tegra210_adx_update_map_ram(struct tegra210_adx *adx) tegra210_adx_write_map_ram(adx, i, adx->map[i]); } -static int tegra210_adx_sw_reset(struct tegra210_adx *adx, - int timeout) -{ - unsigned int val; - int wait = timeout; - - regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET, - TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK, - TEGRA210_ADX_SOFT_RESET_SOFT_EN); - - do { - regmap_read(adx->regmap, TEGRA210_ADX_SOFT_RESET, &val); - wait--; - if (!wait) - return -EINVAL; - } while (val & 0x00000001); - - regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET, - TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK, - TEGRA210_ADX_SOFT_RESET_SOFT_DEFAULT); - - return 0; -} - -static int tegra210_adx_get_status(struct tegra210_adx *adx) -{ - unsigned int val; - - regmap_read(adx->regmap, TEGRA210_ADX_STATUS, &val); - val = (val & 0x00000001); - - return val; -} - static int tegra210_adx_stop(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct device *dev = codec->dev; struct tegra210_adx *adx = dev_get_drvdata(dev); - int dcnt = 10, ret = 0; + unsigned int val; + int ret; - /* wait until ADX status is disabled */ - while (tegra210_adx_get_status(adx) && dcnt--) - udelay(100); - - /* HW needs sw reset to make sure previous transaction be clean */ - ret = tegra210_adx_sw_reset(adx, 0xffff); - if (ret) { - dev_err(dev, "Failed at ADX%d sw reset\n", dev->id); + /* ensure if ADX status is disabled */ + ret = regmap_read_poll_timeout_atomic(adx->regmap, TEGRA210_ADX_STATUS, + val, !(val & 0x1), 10, 10000); + if (ret < 0) { + dev_err(dev, "failed to stop ADX, err = %d\n", ret); return ret; } - return (dcnt < 0) ? -ETIMEDOUT : 0; + /* SW reset */ + regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET, + TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK, + TEGRA210_ADX_SOFT_RESET_SOFT_EN); + + ret = regmap_read_poll_timeout(adx->regmap, TEGRA210_ADX_SOFT_RESET, + val, !(val & 0x1), 10, 10000); + if (ret < 0) { + dev_err(dev, "failed to reset ADX, err = %d\n", ret); + return ret; + } + + regmap_update_bits(adx->regmap, TEGRA210_ADX_SOFT_RESET, + TEGRA210_ADX_SOFT_RESET_SOFT_RESET_MASK, + TEGRA210_ADX_SOFT_RESET_SOFT_DEFAULT); + + return 0; } -static unsigned int __maybe_unused tegra210_adx_read_map_ram( - struct tegra210_adx *adx, - unsigned int addr) +static unsigned int __maybe_unused + tegra210_adx_read_map_ram(struct tegra210_adx *adx, unsigned int addr) { - unsigned int val, wait; - wait = 0xffff; + unsigned int val; + int ret; regmap_write(adx->regmap, TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL, (addr << TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RAM_ADDR_SHIFT)); @@ -228,12 +206,11 @@ static unsigned int __maybe_unused tegra210_adx_read_map_ram( val &= ~(TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL_RW_WRITE); regmap_write(adx->regmap, TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL, val); - do { - regmap_read(adx->regmap, TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL, &val); - wait--; - if (!wait) - return -EINVAL; - } while (val & 0x80000000); + ret = regmap_read_poll_timeout(adx->regmap, + TEGRA210_ADX_AHUBRAMCTL_ADX_CTRL, + val, !(val & 0x80000000), 10, 10000); + if (ret < 0) + return ret; regmap_read(adx->regmap, TEGRA210_ADX_AHUBRAMCTL_ADX_DATA, &val); diff --git a/sound/soc/tegra-alt/tegra210_afc_alt.c b/sound/soc/tegra-alt/tegra210_afc_alt.c index 77ddfbb2..acaffc88 100644 --- a/sound/soc/tegra-alt/tegra210_afc_alt.c +++ b/sound/soc/tegra-alt/tegra210_afc_alt.c @@ -1,7 +1,7 @@ /* * tegra210_afc_alt.c - Tegra210 AFC driver * - * Copyright (c) 2014-2019 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2020 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -15,7 +15,6 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include #include #include #include diff --git a/sound/soc/tegra-alt/tegra210_amx_alt.c b/sound/soc/tegra-alt/tegra210_amx_alt.c index 1078dbb9..ad4829b6 100644 --- a/sound/soc/tegra-alt/tegra210_amx_alt.c +++ b/sound/soc/tegra-alt/tegra210_amx_alt.c @@ -16,7 +16,6 @@ * along with this program. If not, see . */ -#include #include #include #include @@ -179,60 +178,40 @@ static void tegra210_amx_update_map_ram(struct tegra210_amx *amx) tegra210_amx_write_map_ram(amx, i, amx->map[i]); } -static int tegra210_amx_sw_reset(struct tegra210_amx *amx, - int timeout) -{ - unsigned int val; - int wait = timeout; - - regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET, - TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK, - TEGRA210_AMX_SOFT_RESET_SOFT_EN); - - do { - regmap_read(amx->regmap, TEGRA210_AMX_SOFT_RESET, &val); - wait--; - if (!wait) - return -EINVAL; - } while (val & 0x00000001); - - regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET, - TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK, - TEGRA210_AMX_SOFT_RESET_SOFT_DEFAULT); - - return 0; -} - -static int tegra210_amx_get_status(struct tegra210_amx *amx) -{ - unsigned int val; - - regmap_read(amx->regmap, TEGRA210_AMX_STATUS, &val); - val = (val & 0x00000001); - - return val; -} - static int tegra210_amx_stop(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct device *dev = codec->dev; struct tegra210_amx *amx = dev_get_drvdata(dev); - int dcnt = 10, ret = 0; + unsigned int val; + int ret; - /* wait until AMX status is disabled */ - while (tegra210_amx_get_status(amx) && dcnt--) - udelay(100); - - /* HW needs sw reset to make sure previous transaction be clean */ - ret = tegra210_amx_sw_reset(amx, 0xffff); - if (ret) { - dev_err(dev, "Failed at AMX%d sw reset\n", dev->id); + /* Ensure if AMX is disabled */ + ret = regmap_read_poll_timeout(amx->regmap, TEGRA210_AMX_STATUS, val, + !(val & 0x1), 10, 10000); + if (ret < 0) { + dev_err(dev, "failed to stop AMX, err = %d\n", ret); return ret; } - return (dcnt < 0) ? -ETIMEDOUT : 0; + /* SW reset */ + regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET, + TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK, + TEGRA210_AMX_SOFT_RESET_SOFT_EN); + + ret = regmap_read_poll_timeout(amx->regmap, TEGRA210_AMX_SOFT_RESET, + val, !(val & 0x1), 10, 10000); + if (ret < 0) { + dev_err(dev, "failed to reset AMX, err = %d\n", ret); + return ret; + } + + regmap_update_bits(amx->regmap, TEGRA210_AMX_SOFT_RESET, + TEGRA210_AMX_SOFT_RESET_SOFT_RESET_MASK, + TEGRA210_AMX_SOFT_RESET_SOFT_DEFAULT); + + return 0; } static int tegra210_amx_runtime_suspend(struct device *dev) @@ -245,12 +224,11 @@ static int tegra210_amx_runtime_suspend(struct device *dev) return 0; } -static unsigned int __maybe_unused tegra210_amx_read_map_ram( - struct tegra210_amx *amx, - unsigned int addr) +static unsigned int __maybe_unused + tegra210_amx_read_map_ram(struct tegra210_amx *amx, unsigned int addr) { - unsigned int val, wait; - wait = 0xffff; + unsigned int val; + int ret; regmap_write(amx->regmap, TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL, (addr << TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RAM_ADDR_SHIFT)); @@ -262,13 +240,11 @@ static unsigned int __maybe_unused tegra210_amx_read_map_ram( val &= ~(TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL_RW_WRITE); regmap_write(amx->regmap, TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL, val); - do { - regmap_read(amx->regmap, - TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL, &val); - wait--; - if (!wait) - return -EINVAL; - } while (val & 0x80000000); + ret = regmap_read_poll_timeout(amx->regmap, + TEGRA210_AMX_AHUBRAMCTL_AMX_CTRL, + val, !(val & 0x80000000), 10, 10000); + if (ret < 0) + return ret; regmap_read(amx->regmap, TEGRA210_AMX_AHUBRAMCTL_AMX_DATA, &val); diff --git a/sound/soc/tegra-alt/tegra210_i2s_alt.c b/sound/soc/tegra-alt/tegra210_i2s_alt.c index 0e3ea0c4..31a8effe 100644 --- a/sound/soc/tegra-alt/tegra210_i2s_alt.c +++ b/sound/soc/tegra-alt/tegra210_i2s_alt.c @@ -16,11 +16,9 @@ * along with this program. If not, see . */ -#include #include #include #include -#include #include #include #include @@ -33,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -43,8 +40,6 @@ #define DRV_NAME "tegra210-i2s" -#define REG_IOVA(reg) (i2s->base_addr + (reg)) - static const struct reg_default tegra210_i2s_reg_defaults[] = { { TEGRA210_I2S_AXBAR_RX_INT_MASK, 0x00000003}, { TEGRA210_I2S_AXBAR_RX_CIF_CTRL, 0x00007700}, @@ -144,9 +139,9 @@ static int tegra210_i2s_sw_reset(struct snd_soc_codec *codec, bool is_playback) /* SW reset */ regmap_update_bits(i2s->regmap, reset_reg, reset_mask, reset_en); - ret = readl_poll_timeout_atomic(REG_IOVA(reset_reg), val, - !(val & reset_mask & reset_en), - 10, 10000); + ret = regmap_read_poll_timeout(i2s->regmap, reset_reg, val, + !(val & reset_mask & reset_en), + 10, 10000); if (ret < 0) { dev_err(dev, "timeout: failed to reset I2S for %s\n", is_playback ? "playback" : "capture"); @@ -185,7 +180,7 @@ static int tegra210_i2s_init(struct snd_soc_dapm_widget *w, } /* ensure I2S is in disabled state before new session */ - ret = readl_poll_timeout_atomic(REG_IOVA(status_reg), val, + ret = regmap_read_poll_timeout(i2s->regmap, status_reg, val, !(val & TEGRA210_I2S_EN_MASK & TEGRA210_I2S_EN), 10, 10000); if (ret < 0) { @@ -1100,8 +1095,6 @@ static int tegra210_i2s_platform_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs); - i2s->base_addr = regs; - i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tegra210_i2s_regmap_config); if (IS_ERR(i2s->regmap)) { diff --git a/sound/soc/tegra-alt/tegra210_mixer_alt.c b/sound/soc/tegra-alt/tegra210_mixer_alt.c index 893ba8b2..6974c7aa 100644 --- a/sound/soc/tegra-alt/tegra210_mixer_alt.c +++ b/sound/soc/tegra-alt/tegra210_mixer_alt.c @@ -95,20 +95,18 @@ static int tegra210_mixer_runtime_resume(struct device *dev) } static int tegra210_mixer_write_ram(struct tegra210_mixer *mixer, - unsigned int addr, - unsigned int val) + unsigned int addr, + unsigned int coef) { - unsigned int reg, value, wait = 0xffff; + unsigned int reg, val; + int ret; /* check if busy */ - do { - regmap_read(mixer->regmap, - TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL, &value); - wait--; - if (!wait) - return -EINVAL; - } while (value & 0x80000000); - value = 0; + ret = regmap_read_poll_timeout(mixer->regmap, + TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL, + val, !(val & 0x80000000), 10, 10000); + if (ret < 0) + return ret; reg = (addr << TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT) & TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_RAM_ADDR_MASK; @@ -117,9 +115,11 @@ static int tegra210_mixer_write_ram(struct tegra210_mixer *mixer, reg |= TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL_SEQ_ACCESS_EN; regmap_write(mixer->regmap, - TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL, reg); + TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_CTRL, + reg); regmap_write(mixer->regmap, - TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_DATA, val); + TEGRA210_MIXER_AHUBRAMCTL_GAIN_CONFIG_RAM_DATA, + coef); return 0; } diff --git a/sound/soc/tegra-alt/tegra210_mvc_alt.c b/sound/soc/tegra-alt/tegra210_mvc_alt.c index 8c3404a7..05d89065 100644 --- a/sound/soc/tegra-alt/tegra210_mvc_alt.c +++ b/sound/soc/tegra-alt/tegra210_mvc_alt.c @@ -28,7 +28,6 @@ #include #include #include -#include #include "tegra210_xbar_alt.h" #include "tegra210_mvc_alt.h" @@ -75,51 +74,27 @@ static int tegra210_mvc_runtime_resume(struct device *dev) return 0; } -static int tegra210_mvc_soft_reset(struct tegra210_mvc *mvc) -{ - int value; - int dcnt = 10; - /* issue soft reset */ - regmap_write(mvc->regmap, TEGRA210_MVC_SOFT_RESET, 1); - /* wait for soft reset bit to clear */ - do { - udelay(10); - regmap_read(mvc->regmap, TEGRA210_MVC_SOFT_RESET, &value); - dcnt--; - if (dcnt < 0) - return -EINVAL; - } while (value); - - return 0; -} - static int tegra210_mvc_write_ram(struct tegra210_mvc *mvc, - unsigned int addr, - unsigned int val) + unsigned int addr, unsigned int coef) { - unsigned int reg, value, wait = 0xffff; + unsigned int reg, val; + int ret; - /* check if busy */ - do { - regmap_read(mvc->regmap, - TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL, - &value); - wait--; - if (!wait) - return -EINVAL; - } while (value & 0x80000000); - value = 0; + ret = regmap_read_poll_timeout(mvc->regmap, + TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL, + val, !(val & 0x80000000), 10, 10000); + if (ret < 0) + return ret; reg = (addr << TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_SHIFT) & - TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_MASK; + TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RAM_ADDR_MASK; reg |= TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_ADDR_INIT_EN; reg |= TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_RW_WRITE; reg |= TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL_SEQ_ACCESS_EN; - regmap_write(mvc->regmap, - TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL, reg); - regmap_write(mvc->regmap, - TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_DATA, val); + regmap_write(mvc->regmap, TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_CTRL, reg); + regmap_write(mvc->regmap, TEGRA210_MVC_AHUBRAMCTL_CONFIG_RAM_DATA, + coef); return 0; } @@ -161,21 +136,18 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec); unsigned int reg = mc->reg; - unsigned int value, wait = 0xffff; + unsigned int value; int ret = 0; s32 val; pm_runtime_get_sync(codec->dev); - /* check if VOLUME_SWITCH is triggered*/ - do { - regmap_read(mvc->regmap, - TEGRA210_MVC_SWITCH, &value); - wait--; - if (!wait) { - ret = -EINVAL; - goto end; - } - } while (value & TEGRA210_MVC_VOLUME_SWITCH_MASK); + + /* check if VOLUME_SWITCH is triggered */ + ret = regmap_read_poll_timeout(mvc->regmap, TEGRA210_MVC_SWITCH, + value, !(value & TEGRA210_MVC_VOLUME_SWITCH_MASK), + 10, 10000); + if (ret < 0) + goto end; if (reg == TEGRA210_MVC_TARGET_VOL) { /* Volume control read from mixer ctl is with */ @@ -357,11 +329,15 @@ static int tegra210_mvc_hw_params(struct snd_pcm_substream *substream, { struct device *dev = dai->dev; struct tegra210_mvc *mvc = snd_soc_dai_get_drvdata(dai); - int i, ret; + int i, ret, val; - ret = tegra210_mvc_soft_reset(mvc); + /* SW reset */ + regmap_write(mvc->regmap, TEGRA210_MVC_SOFT_RESET, 1); + + ret = regmap_read_poll_timeout(mvc->regmap, TEGRA210_MVC_SOFT_RESET, + val, !val, 10, 10000); if (ret < 0) { - dev_err(dev, "SOFT_RESET error: %d\n", ret); + dev_err(dev, "SW reset failed, err = %d\n", ret); return ret; } @@ -396,8 +372,14 @@ static int tegra210_mvc_hw_params(struct snd_pcm_substream *substream, regmap_write(mvc->regmap, TEGRA210_MVC_TARGET_VOL, mvc->volume); /* program the poly coefficients */ - for (i = 0; i < 9; i++) - tegra210_mvc_write_ram(mvc, i, mvc->poly_coeff[i]); + for (i = 0; i < 9; i++) { + ret = tegra210_mvc_write_ram(mvc, i, mvc->poly_coeff[i]); + if (ret < 0) { + dev_err(dai->dev, "failed to write coefs, err = %d\n", + ret); + return ret; + } + } /* program poly_n1, poly_n2, duration */ regmap_write(mvc->regmap, TEGRA210_MVC_POLY_N1, mvc->poly_n1); diff --git a/sound/soc/tegra-alt/tegra210_sfc_alt.c b/sound/soc/tegra-alt/tegra210_sfc_alt.c index ce007233..d5a9c164 100644 --- a/sound/soc/tegra-alt/tegra210_sfc_alt.c +++ b/sound/soc/tegra-alt/tegra210_sfc_alt.c @@ -28,7 +28,6 @@ #include #include #include -#include #include "tegra210_xbar_alt.h" #include "tegra210_sfc_alt.h" @@ -3015,20 +3014,19 @@ static int tegra210_sfc_set_audio_cif(struct tegra210_sfc *sfc, static int tegra210_sfc_soft_reset(struct tegra210_sfc *sfc) { u32 val; - int cnt = 10; - int ret = 0; + int ret; - regmap_update_bits(sfc->regmap, - TEGRA210_SFC_SOFT_RESET, - TEGRA210_SFC_SOFT_RESET_EN, - 1); - do { - udelay(100); - regmap_read(sfc->regmap, TEGRA210_SFC_SOFT_RESET, &val); - } while ((val & TEGRA210_SFC_SOFT_RESET_EN) && cnt--); - if (!cnt) - ret = -ETIMEDOUT; - return ret; + /* SW reset */ + regmap_update_bits(sfc->regmap, TEGRA210_SFC_SOFT_RESET, + TEGRA210_SFC_SOFT_RESET_EN, 1); + + ret = regmap_read_poll_timeout(sfc->regmap, TEGRA210_SFC_SOFT_RESET, + val, !(val & TEGRA210_SFC_SOFT_RESET_EN), + 10, 10000); + if (ret < 0) + return ret; + + return 0; } static int tegra210_sfc_in_hw_params(struct snd_pcm_substream *substream, @@ -3045,8 +3043,10 @@ static int tegra210_sfc_in_hw_params(struct snd_pcm_substream *substream, 0); ret = tegra210_sfc_soft_reset(sfc); - if (ret) { - dev_err(dev, "SOFT_RESET error: %d\n", ret); + if (ret < 0) { + dev_err(dev, "failed to reset SFC in %s, err = %d\n", + __func__, ret); + return ret; } @@ -3200,27 +3200,28 @@ static int tegra210_sfc_init_put(struct snd_kcontrol *kcontrol, if (is_enabled) { u32 val; - int cnt = 100; regmap_write(sfc->regmap, TEGRA210_SFC_ENABLE, 0); - regmap_read(sfc->regmap, TEGRA210_SFC_STATUS, &val); - while ((val & 1) && cnt--) { - udelay(100); - regmap_read(sfc->regmap, TEGRA210_SFC_STATUS, &val); + ret = regmap_read_poll_timeout(sfc->regmap, + TEGRA210_SFC_STATUS, val, + !(val & 0x1), 10, 10000); + if (ret < 0) { + dev_err(codec->dev, + "failed to disable SFC, err = %d\n", ret); + return ret; } - if (!cnt) - dev_warn(codec->dev, "SFC disable timeout\n"); - regmap_update_bits(sfc->regmap, TEGRA210_SFC_COEF_RAM, TEGRA210_SFC_COEF_RAM_COEF_RAM_EN, 0); ret = tegra210_sfc_soft_reset(sfc); - if (ret) { - dev_err(codec->dev, "SOFT_RESET error: %d\n", ret); + if (ret < 0) { + dev_err(codec->dev, + "failed to reset SFC in %s, err = %d\n", + __func__, ret); goto exit; }