From: Emil-Juhl Date: Tue, 13 Jan 2026 10:58:49 +0000 (+0100) Subject: ASoC: tlv320adcx140: add avdd and iovdd supply X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57be1f67401005e33e8c88db6707b4482b509589;p=thirdparty%2Fkernel%2Flinux.git ASoC: tlv320adcx140: add avdd and iovdd supply The datasheet, under "10 Power Supply Recommendations" section, specifies that both the AVDD and IOVDD supplies must be up and stable for at least 100us before the SHDNZ can be released. After that, the chip is ready to receive commands after another 2ms. Currently the driver doesn't contain any options to bind AVDD and IOVDD supplies to the tlv320adcx140. This commit adds bindings for AVDD and IOVDD supplies which the driver will enable when used. Signed-off-by: Emil-Juhl Signed-off-by: Sascha Hauer Link: https://patch.msgid.link/20260113-sound-soc-codecs-tvl320adcx140-v4-6-8f7ecec525c8@pengutronix.de Signed-off-by: Mark Brown --- diff --git a/sound/soc/codecs/tlv320adcx140.c b/sound/soc/codecs/tlv320adcx140.c index 444c0e80f0907..a7200e149e5f4 100644 --- a/sound/soc/codecs/tlv320adcx140.c +++ b/sound/soc/codecs/tlv320adcx140.c @@ -22,8 +22,16 @@ #include "tlv320adcx140.h" +static const char *const adcx140_supply_names[] = { + "avdd", + "iovdd", +}; + +#define ADCX140_NUM_SUPPLIES ARRAY_SIZE(adcx140_supply_names) + struct adcx140_priv { struct regulator *supply_areg; + struct regulator_bulk_data supplies[ADCX140_NUM_SUPPLIES]; struct gpio_desc *gpio_reset; struct regmap *regmap; struct device *dev; @@ -1104,6 +1112,8 @@ out: static int adcx140_pwr_off(struct adcx140_priv *adcx140) { + int ret; + regcache_cache_only(adcx140->regmap, true); regcache_mark_dirty(adcx140->regmap); @@ -1117,6 +1127,14 @@ static int adcx140_pwr_off(struct adcx140_priv *adcx140) */ usleep_range(30000, 100000); + /* Power off the regulators, `avdd` and `iovdd` */ + ret = regulator_bulk_disable(ARRAY_SIZE(adcx140->supplies), + adcx140->supplies); + if (ret) { + dev_err(adcx140->dev, "Failed to disable supplies: %d\n", ret); + return ret; + } + return 0; } @@ -1124,6 +1142,14 @@ static int adcx140_pwr_on(struct adcx140_priv *adcx140) { int ret; + /* Power on the regulators, `avdd` and `iovdd` */ + ret = regulator_bulk_enable(ARRAY_SIZE(adcx140->supplies), + adcx140->supplies); + if (ret) { + dev_err(adcx140->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + /* De-assert the reset GPIO */ gpiod_set_value_cansleep(adcx140->gpio_reset, 1); @@ -1234,6 +1260,16 @@ static int adcx140_i2c_probe(struct i2c_client *i2c) adcx140->phase_calib_on = false; adcx140->dev = &i2c->dev; + for (int i = 0; i < ADCX140_NUM_SUPPLIES; i++) + adcx140->supplies[i].supply = adcx140_supply_names[i]; + + ret = devm_regulator_bulk_get(&i2c->dev, ADCX140_NUM_SUPPLIES, + adcx140->supplies); + if (ret) { + dev_err_probe(&i2c->dev, ret, "Failed to request supplies\n"); + return ret; + } + adcx140->gpio_reset = devm_gpiod_get_optional(adcx140->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(adcx140->gpio_reset))