diff options
author | Andrew F. Davis <afd@ti.com> | 2017-12-07 09:38:56 -0600 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-12-07 17:47:18 +0000 |
commit | 0ce918c9e070bf4fd17af0d76096ad184815bd79 (patch) | |
tree | 926f8d66bb89f9e35b385db3d67338e34ce9f57c /sound | |
parent | cd15da88c358e9987a3b16bc821c980dd2377776 (diff) |
ASoC: tlv320aic31xx: Reset registers during power up
Add a reset function that toggles the reset line if available or uses
the software reset command otherwise. Use this in power up to ensure the
registers are in a sane state. This is useful when the driver module
is reloaded, or after Kexec, warm-reboots, etc..
Signed-off-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/tlv320aic31xx.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index 655c99db2426..858cb8be445f 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -1055,6 +1055,22 @@ static int aic31xx_regulator_event(struct notifier_block *nb, return 0; } +static int aic31xx_reset(struct aic31xx_priv *aic31xx) +{ + int ret = 0; + + if (aic31xx->gpio_reset) { + gpiod_set_value(aic31xx->gpio_reset, 1); + ndelay(10); /* At least 10ns */ + gpiod_set_value(aic31xx->gpio_reset, 0); + } else { + ret = regmap_write(aic31xx->regmap, AIC31XX_RESET, 1); + } + mdelay(1); /* At least 1ms */ + + return ret; +} + static void aic31xx_clk_on(struct snd_soc_codec *codec) { struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); @@ -1098,11 +1114,13 @@ static int aic31xx_power_on(struct snd_soc_codec *codec) if (ret) return ret; - if (aic31xx->gpio_reset) { - gpiod_set_value(aic31xx->gpio_reset, 0); - udelay(100); - } regcache_cache_only(aic31xx->regmap, false); + + /* Reset device registers for a consistent power-on like state */ + ret = aic31xx_reset(aic31xx); + if (ret < 0) + dev_err(aic31xx->dev, "Could not reset device: %d\n", ret); + ret = regcache_sync(aic31xx->regmap); if (ret) { dev_err(codec->dev, |