Skip to content

Commit d4b119b

Browse files
marcanjannau
authored andcommitted
ASoC: tas2764: Add SDZ regulator
Multiple amps can be connected to the same SDZ GPIO. Using raw GPIOs for this breaks, as there is no concept of refcounting/sharing. In order to model these platforms, introduce support for an SDZ "regulator". This allows us to represent the SDZ GPIO as a simple regulator-fixed, and then the regulator core takes care of refcounting so that all codecs are only powered down once all the driver instances are in the suspend state. Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent d015971 commit d4b119b

1 file changed

Lines changed: 37 additions & 7 deletions

File tree

sound/soc/codecs/tas2764.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct tas2764_priv {
3434
struct snd_soc_component *component;
3535
struct gpio_desc *reset_gpio;
3636
struct gpio_desc *sdz_gpio;
37+
struct regulator *sdz_reg;
3738
struct regmap *regmap;
3839
struct device *dev;
3940
int irq;
@@ -153,6 +154,8 @@ static int tas2764_codec_suspend(struct snd_soc_component *component)
153154
if (tas2764->sdz_gpio)
154155
gpiod_set_value_cansleep(tas2764->sdz_gpio, 0);
155156

157+
regulator_disable(tas2764->sdz_reg);
158+
156159
regcache_cache_only(tas2764->regmap, true);
157160
regcache_mark_dirty(tas2764->regmap);
158161

@@ -166,19 +169,26 @@ static int tas2764_codec_resume(struct snd_soc_component *component)
166169
struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
167170
int ret;
168171

172+
ret = regulator_enable(tas2764->sdz_reg);
173+
174+
if (ret) {
175+
dev_err(tas2764->dev, "Failed to enable regulator\n");
176+
return ret;
177+
}
178+
169179
if (tas2764->sdz_gpio) {
170180
gpiod_set_value_cansleep(tas2764->sdz_gpio, 1);
171-
usleep_range(1000, 2000);
172181
}
173182

174-
ret = tas2764_update_pwr_ctrl(tas2764);
183+
usleep_range(1000, 2000);
184+
185+
regcache_cache_only(tas2764->regmap, false);
175186

187+
ret = regcache_sync(tas2764->regmap);
176188
if (ret < 0)
177189
return ret;
178190

179-
regcache_cache_only(tas2764->regmap, false);
180-
181-
return regcache_sync(tas2764->regmap);
191+
return tas2764_update_pwr_ctrl(tas2764);
182192
}
183193
#else
184194
#define tas2764_codec_suspend NULL
@@ -211,7 +221,7 @@ static const struct snd_soc_dapm_widget tas2764_dapm_widgets[] = {
211221
SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
212222
SND_SOC_DAPM_OUTPUT("OUT"),
213223
SND_SOC_DAPM_SIGGEN("VMON"),
214-
SND_SOC_DAPM_SIGGEN("IMON")
224+
SND_SOC_DAPM_SIGGEN("IMON"),
215225
};
216226

217227
static const struct snd_soc_dapm_route tas2764_audio_map[] = {
@@ -686,11 +696,18 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
686696

687697
tas2764->component = component;
688698

699+
ret = regulator_enable(tas2764->sdz_reg);
700+
if (ret != 0) {
701+
dev_err(tas2764->dev, "Failed to enable regulator: %d\n", ret);
702+
return ret;
703+
}
704+
689705
if (tas2764->sdz_gpio) {
690706
gpiod_set_value_cansleep(tas2764->sdz_gpio, 1);
691-
usleep_range(1000, 2000);
692707
}
693708

709+
usleep_range(1000, 2000);
710+
694711
tas2764_reset(tas2764);
695712
regmap_reinit_cache(tas2764->regmap, &tas2764_i2c_regmap);
696713

@@ -778,6 +795,13 @@ static int tas2764_codec_probe(struct snd_soc_component *component)
778795
return 0;
779796
}
780797

798+
static void tas2764_codec_remove(struct snd_soc_component *component)
799+
{
800+
struct tas2764_priv *tas2764 = snd_soc_component_get_drvdata(component);
801+
802+
regulator_disable(tas2764->sdz_reg);
803+
}
804+
781805
static DECLARE_TLV_DB_SCALE(tas2764_digital_tlv, 1100, 50, 0);
782806
static DECLARE_TLV_DB_SCALE(tas2764_playback_volume, -10050, 50, 1);
783807

@@ -809,6 +833,7 @@ static const struct snd_kcontrol_new tas2764_snd_controls[] = {
809833

810834
static const struct snd_soc_component_driver soc_component_driver_tas2764 = {
811835
.probe = tas2764_codec_probe,
836+
.remove = tas2764_codec_remove,
812837
.suspend = tas2764_codec_suspend,
813838
.resume = tas2764_codec_resume,
814839
.controls = tas2764_snd_controls,
@@ -878,6 +903,11 @@ static int tas2764_parse_dt(struct device *dev, struct tas2764_priv *tas2764)
878903
{
879904
int ret = 0;
880905

906+
tas2764->sdz_reg = devm_regulator_get(dev, "SDZ");
907+
if (IS_ERR(tas2764->sdz_reg))
908+
return dev_err_probe(dev, PTR_ERR(tas2764->sdz_reg),
909+
"Failed to get SDZ supply\n");
910+
881911
tas2764->reset_gpio = devm_gpiod_get_optional(tas2764->dev, "reset",
882912
GPIOD_OUT_HIGH);
883913
if (IS_ERR(tas2764->reset_gpio)) {

0 commit comments

Comments
 (0)