Unverified Commit ccfc5316 authored by Mike Willard's avatar Mike Willard Committed by Mark Brown
Browse files

ASoC: cs4270: pull reset GPIO low then high



Pull the RST line low then high when initializing the driver,
in order to force a reset of the chip.
Previously, the line was not pulled low, which could result in
the chip registers not resetting to their default values on boot.

Signed-off-by: default avatarMike Willard <mwillard@izotope.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20200401205454.79792-1-mwillard@izotope.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4146575e
Loading
Loading
Loading
Loading
+35 −5
Original line number Diff line number Diff line
@@ -137,6 +137,9 @@ struct cs4270_private {

	/* power domain regulators */
	struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];

	/* reset gpio */
	struct gpio_desc *reset_gpio;
};

static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = {
@@ -648,6 +651,22 @@ static const struct regmap_config cs4270_regmap = {
	.volatile_reg =		cs4270_reg_is_volatile,
};

/**
 * cs4270_i2c_remove - deinitialize the I2C interface of the CS4270
 * @i2c_client: the I2C client object
 *
 * This function puts the chip into low power mode when the i2c device
 * is removed.
 */
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
{
	struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);

	gpiod_set_value_cansleep(cs4270->reset_gpio, 0);

	return 0;
}

/**
 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
 * @i2c_client: the I2C client object
@@ -660,7 +679,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
	const struct i2c_device_id *id)
{
	struct cs4270_private *cs4270;
	struct gpio_desc *reset_gpiod;
	unsigned int val;
	int ret, i;

@@ -679,10 +697,21 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
	if (ret < 0)
		return ret;

	reset_gpiod = devm_gpiod_get_optional(&i2c_client->dev, "reset",
					      GPIOD_OUT_HIGH);
	if (PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
		return -EPROBE_DEFER;
	/* reset the device */
	cs4270->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, "reset",
						     GPIOD_OUT_LOW);
	if (IS_ERR(cs4270->reset_gpio)) {
		dev_dbg(&i2c_client->dev, "Error getting CS4270 reset GPIO\n");
		return PTR_ERR(cs4270->reset_gpio);
	}

	if (cs4270->reset_gpio) {
		dev_dbg(&i2c_client->dev, "Found reset GPIO\n");
		gpiod_set_value_cansleep(cs4270->reset_gpio, 1);
	}

	/* Sleep 500ns before i2c communications */
	ndelay(500);

	cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
	if (IS_ERR(cs4270->regmap))
@@ -735,6 +764,7 @@ static struct i2c_driver cs4270_i2c_driver = {
	},
	.id_table = cs4270_id,
	.probe = cs4270_i2c_probe,
	.remove = cs4270_i2c_remove,
};

module_i2c_driver(cs4270_i2c_driver);