Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7f16ea9 authored by Adam Thomson's avatar Adam Thomson Committed by Mark Brown
Browse files

ASoC: da7219: Reset codec gracefully, if still active



Currently the reset code in i2c_probe only resets the AAD part of
the device and not the entire codec. This patch updates the driver
to resolve this and ensures that if the codec is still active from
a previous boot then the audio paths are powered down prior to
reset.

Signed-off-by: default avatarAdam Thomson <Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 8339f0b6
Loading
Loading
Loading
Loading
+27 −3
Original line number Original line Diff line number Diff line
@@ -1925,7 +1925,8 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
			    const struct i2c_device_id *id)
{
{
	struct da7219_priv *da7219;
	struct da7219_priv *da7219;
	int ret;
	unsigned int system_active, system_status;
	int i, ret;


	da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv),
	da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv),
			      GFP_KERNEL);
			      GFP_KERNEL);
@@ -1941,14 +1942,37 @@ static int da7219_i2c_probe(struct i2c_client *i2c,
		return ret;
		return ret;
	}
	}


	/* Software reset codec. */
	regcache_cache_bypass(da7219->regmap, true);

	/* Disable audio paths if still active from previous start */
	regmap_read(da7219->regmap, DA7219_SYSTEM_ACTIVE, &system_active);
	if (system_active) {
		regmap_write(da7219->regmap, DA7219_GAIN_RAMP_CTRL,
			     DA7219_GAIN_RAMP_RATE_NOMINAL);
		regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_INPUT, 0x00);
		regmap_write(da7219->regmap, DA7219_SYSTEM_MODES_OUTPUT, 0x01);

		for (i = 0; i < DA7219_SYS_STAT_CHECK_RETRIES; ++i) {
			regmap_read(da7219->regmap, DA7219_SYSTEM_STATUS,
				    &system_status);
			if (!system_status)
				break;

			msleep(DA7219_SYS_STAT_CHECK_DELAY);
		}
	}

	/* Soft reset codec */
	regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
	regmap_write_bits(da7219->regmap, DA7219_ACCDET_CONFIG_1,
			  DA7219_ACCDET_EN_MASK, 0);
			  DA7219_ACCDET_EN_MASK, 0);
	regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
	regmap_write_bits(da7219->regmap, DA7219_CIF_CTRL,
			  DA7219_CIF_REG_SOFT_RESET_MASK, 0);
			  DA7219_CIF_REG_SOFT_RESET_MASK,
			  DA7219_CIF_REG_SOFT_RESET_MASK);
	regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE,
	regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE,
			  DA7219_SYSTEM_ACTIVE_MASK, 0);
			  DA7219_SYSTEM_ACTIVE_MASK, 0);


	regcache_cache_bypass(da7219->regmap, false);

	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7219,
				     &da7219_dai, 1);
				     &da7219_dai, 1);
	if (ret < 0) {
	if (ret < 0) {
+5 −0
Original line number Original line Diff line number Diff line
@@ -578,6 +578,7 @@
#define DA7219_GAIN_RAMP_RATE_SHIFT	0
#define DA7219_GAIN_RAMP_RATE_SHIFT	0
#define DA7219_GAIN_RAMP_RATE_MASK	(0x3 << 0)
#define DA7219_GAIN_RAMP_RATE_MASK	(0x3 << 0)
#define DA7219_GAIN_RAMP_RATE_X8	(0x0 << 0)
#define DA7219_GAIN_RAMP_RATE_X8	(0x0 << 0)
#define DA7219_GAIN_RAMP_RATE_NOMINAL	(0x1 << 0)
#define DA7219_GAIN_RAMP_RATE_MAX	4
#define DA7219_GAIN_RAMP_RATE_MAX	4


/* DA7219_PC_COUNT = 0x94 */
/* DA7219_PC_COUNT = 0x94 */
@@ -772,6 +773,10 @@
/* SRM */
/* SRM */
#define DA7219_SRM_CHECK_RETRIES	8
#define DA7219_SRM_CHECK_RETRIES	8


/* System Controller */
#define DA7219_SYS_STAT_CHECK_RETRIES	6
#define DA7219_SYS_STAT_CHECK_DELAY	50

enum da7219_clk_src {
enum da7219_clk_src {
	DA7219_CLKSRC_MCLK = 0,
	DA7219_CLKSRC_MCLK = 0,
	DA7219_CLKSRC_MCLK_SQR,
	DA7219_CLKSRC_MCLK_SQR,