Skip to content

Commit ccfc531

Browse files
mwillard-izobroonie
authored andcommitted
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: Mike Willard <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 4146575 commit ccfc531

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

sound/soc/codecs/cs4270.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ struct cs4270_private {
137137

138138
/* power domain regulators */
139139
struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
140+
141+
/* reset gpio */
142+
struct gpio_desc *reset_gpio;
140143
};
141144

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

654+
/**
655+
* cs4270_i2c_remove - deinitialize the I2C interface of the CS4270
656+
* @i2c_client: the I2C client object
657+
*
658+
* This function puts the chip into low power mode when the i2c device
659+
* is removed.
660+
*/
661+
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
662+
{
663+
struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
664+
665+
gpiod_set_value_cansleep(cs4270->reset_gpio, 0);
666+
667+
return 0;
668+
}
669+
651670
/**
652671
* cs4270_i2c_probe - initialize the I2C interface of the CS4270
653672
* @i2c_client: the I2C client object
@@ -660,7 +679,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
660679
const struct i2c_device_id *id)
661680
{
662681
struct cs4270_private *cs4270;
663-
struct gpio_desc *reset_gpiod;
664682
unsigned int val;
665683
int ret, i;
666684

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

682-
reset_gpiod = devm_gpiod_get_optional(&i2c_client->dev, "reset",
683-
GPIOD_OUT_HIGH);
684-
if (PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
685-
return -EPROBE_DEFER;
700+
/* reset the device */
701+
cs4270->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, "reset",
702+
GPIOD_OUT_LOW);
703+
if (IS_ERR(cs4270->reset_gpio)) {
704+
dev_dbg(&i2c_client->dev, "Error getting CS4270 reset GPIO\n");
705+
return PTR_ERR(cs4270->reset_gpio);
706+
}
707+
708+
if (cs4270->reset_gpio) {
709+
dev_dbg(&i2c_client->dev, "Found reset GPIO\n");
710+
gpiod_set_value_cansleep(cs4270->reset_gpio, 1);
711+
}
712+
713+
/* Sleep 500ns before i2c communications */
714+
ndelay(500);
686715

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

740770
module_i2c_driver(cs4270_i2c_driver);

0 commit comments

Comments
 (0)