| From 50a626b925ec05765790e0f0fc30a5e4de91b4aa Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 14 Apr 2020 20:11:40 +0200 |
| Subject: ASoC: sgtl5000: Fix VAG power-on handling |
| |
| From: Sebastian Reichel <sebastian.reichel@collabora.com> |
| |
| [ Upstream commit aa7812737f2877e192d57626cbe8825cc7cf6de9 ] |
| |
| As mentioned slightly out of patch context in the code, there |
| is no reset routine for the chip. On boards where the chip is |
| supplied by a fixed regulator, it might not even be resetted |
| during (e.g. watchdog) reboot and can be in any state. |
| |
| If the device is probed with VAG enabled, the driver's probe |
| routine will generate a loud pop sound when ANA_POWER is |
| being programmed. Avoid this by properly disabling just the |
| VAG bit and waiting the required power down time. |
| |
| Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> |
| Reviewed-by: Fabio Estevam <festivem@gmail.com> |
| Link: https://lore.kernel.org/r/20200414181140.145825-1-sebastian.reichel@collabora.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/soc/codecs/sgtl5000.c | 34 ++++++++++++++++++++++++++++++++++ |
| sound/soc/codecs/sgtl5000.h | 1 + |
| 2 files changed, 35 insertions(+) |
| |
| diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c |
| index 896412d11a31c..7c0a06b487f74 100644 |
| --- a/sound/soc/codecs/sgtl5000.c |
| +++ b/sound/soc/codecs/sgtl5000.c |
| @@ -1633,6 +1633,40 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, |
| dev_err(&client->dev, |
| "Error %d initializing CHIP_CLK_CTRL\n", ret); |
| |
| + /* Mute everything to avoid pop from the following power-up */ |
| + ret = regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_CTRL, |
| + SGTL5000_CHIP_ANA_CTRL_DEFAULT); |
| + if (ret) { |
| + dev_err(&client->dev, |
| + "Error %d muting outputs via CHIP_ANA_CTRL\n", ret); |
| + goto disable_clk; |
| + } |
| + |
| + /* |
| + * If VAG is powered-on (e.g. from previous boot), it would be disabled |
| + * by the write to ANA_POWER in later steps of the probe code. This |
| + * may create a loud pop even with all outputs muted. The proper way |
| + * to circumvent this is disabling the bit first and waiting the proper |
| + * cool-down time. |
| + */ |
| + ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, &value); |
| + if (ret) { |
| + dev_err(&client->dev, "Failed to read ANA_POWER: %d\n", ret); |
| + goto disable_clk; |
| + } |
| + if (value & SGTL5000_VAG_POWERUP) { |
| + ret = regmap_update_bits(sgtl5000->regmap, |
| + SGTL5000_CHIP_ANA_POWER, |
| + SGTL5000_VAG_POWERUP, |
| + 0); |
| + if (ret) { |
| + dev_err(&client->dev, "Error %d disabling VAG\n", ret); |
| + goto disable_clk; |
| + } |
| + |
| + msleep(SGTL5000_VAG_POWERDOWN_DELAY); |
| + } |
| + |
| /* Follow section 2.2.1.1 of AN3663 */ |
| ana_pwr = SGTL5000_ANA_POWER_DEFAULT; |
| if (sgtl5000->num_supplies <= VDDD) { |
| diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h |
| index 18cae08bbd3a6..066517e352a70 100644 |
| --- a/sound/soc/codecs/sgtl5000.h |
| +++ b/sound/soc/codecs/sgtl5000.h |
| @@ -233,6 +233,7 @@ |
| /* |
| * SGTL5000_CHIP_ANA_CTRL |
| */ |
| +#define SGTL5000_CHIP_ANA_CTRL_DEFAULT 0x0133 |
| #define SGTL5000_LINE_OUT_MUTE 0x0100 |
| #define SGTL5000_HP_SEL_MASK 0x0040 |
| #define SGTL5000_HP_SEL_SHIFT 6 |
| -- |
| 2.20.1 |
| |