diff options
author | Nuno Sa <nuno.sa@analog.com> | 2024-10-28 16:43:41 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2024-10-29 14:11:09 +0000 |
commit | ba79bca407d3b7e6f5be209d9b3f73f81ee8d460 (patch) | |
tree | 357e0e6777af0e35ac580e02fea0983a099b79a5 | |
parent | 71743cbe28cf1d1f845a30bc9664c3b6a08f0d30 (diff) | |
download | lwn-ba79bca407d3b7e6f5be209d9b3f73f81ee8d460.tar.gz lwn-ba79bca407d3b7e6f5be209d9b3f73f81ee8d460.zip |
ASoC: codecs: adau1373: add powerdown gpio
If the powerdown GPIO is specified, we use it for reset. Otherwise,
fallback to a software reset.
Signed-off-by: Nuno Sa <nuno.sa@analog.com>
Link: https://patch.msgid.link/20241028-adau1373-shutdown-v2-4-647f56bbd182@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/codecs/adau1373.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 9568ff933e12..16b9b2658341 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <linux/gpio/consumer.h> #include <linux/delay.h> #include <linux/pm.h> #include <linux/property.h> @@ -1485,6 +1486,11 @@ static const struct snd_soc_component_driver adau1373_component_driver = { .endianness = 1, }; +static void adau1373_reset(void *reset_gpio) +{ + gpiod_set_value_cansleep(reset_gpio, 1); +} + static int adau1373_parse_fw(struct device *dev, struct adau1373 *adau1373) { int ret, drc_count; @@ -1547,6 +1553,7 @@ static int adau1373_parse_fw(struct device *dev, struct adau1373 *adau1373) static int adau1373_i2c_probe(struct i2c_client *client) { struct adau1373 *adau1373; + struct gpio_desc *gpiod; int ret; adau1373 = devm_kzalloc(&client->dev, sizeof(*adau1373), GFP_KERNEL); @@ -1558,7 +1565,26 @@ static int adau1373_i2c_probe(struct i2c_client *client) if (IS_ERR(adau1373->regmap)) return PTR_ERR(adau1373->regmap); - regmap_write(adau1373->regmap, ADAU1373_SOFT_RESET, 0x00); + /* + * If the powerdown GPIO is specified, we use it for reset. Otherwise + * a software reset is done. + */ + gpiod = devm_gpiod_get_optional(&client->dev, "powerdown", + GPIOD_OUT_HIGH); + if (IS_ERR(gpiod)) + return PTR_ERR(gpiod); + + if (gpiod) { + gpiod_set_value_cansleep(gpiod, 0); + fsleep(10); + + ret = devm_add_action_or_reset(&client->dev, adau1373_reset, + gpiod); + if (ret) + return ret; + } else { + regmap_write(adau1373->regmap, ADAU1373_SOFT_RESET, 0x00); + } dev_set_drvdata(&client->dev, adau1373); |