Skip to content

Commit be49ef9

Browse files
marcanjannau
authored andcommitted
ASoC: tas2770: 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. This also reworks the sleep/resume logic to copy what tas2764 does, which makes more sense. Signed-off-by: Hector Martin <marcan@marcan.st>
1 parent 30cea92 commit be49ef9

2 files changed

Lines changed: 50 additions & 23 deletions

File tree

sound/soc/codecs/tas2770.c

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,21 @@ static int tas2770_codec_suspend(struct snd_soc_component *component)
7272
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
7373
int ret = 0;
7474

75-
regcache_cache_only(tas2770->regmap, true);
76-
regcache_mark_dirty(tas2770->regmap);
75+
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
76+
TAS2770_PWR_CTRL_MASK,
77+
TAS2770_PWR_CTRL_SHUTDOWN);
78+
if (ret < 0)
79+
return ret;
7780

78-
if (tas2770->sdz_gpio) {
81+
if (tas2770->sdz_gpio)
7982
gpiod_set_value_cansleep(tas2770->sdz_gpio, 0);
80-
} else {
81-
ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
82-
TAS2770_PWR_CTRL_MASK,
83-
TAS2770_PWR_CTRL_SHUTDOWN);
84-
if (ret < 0) {
85-
regcache_cache_only(tas2770->regmap, false);
86-
regcache_sync(tas2770->regmap);
87-
return ret;
88-
}
8983

90-
ret = 0;
91-
}
84+
regulator_disable(tas2770->sdz_reg);
85+
86+
regcache_cache_only(tas2770->regmap, true);
87+
regcache_mark_dirty(tas2770->regmap);
88+
89+
usleep_range(6000, 7000);
9290

9391
return ret;
9492
}
@@ -98,18 +96,26 @@ static int tas2770_codec_resume(struct snd_soc_component *component)
9896
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
9997
int ret;
10098

101-
if (tas2770->sdz_gpio) {
102-
gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
103-
usleep_range(1000, 2000);
104-
} else {
105-
ret = tas2770_update_pwr_ctrl(tas2770);
106-
if (ret < 0)
107-
return ret;
99+
ret = regulator_enable(tas2770->sdz_reg);
100+
101+
if (ret) {
102+
dev_err(tas2770->dev, "Failed to enable regulator\n");
103+
return ret;
108104
}
109105

106+
if (tas2770->sdz_gpio)
107+
gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
108+
109+
110+
usleep_range(1000, 2000);
111+
110112
regcache_cache_only(tas2770->regmap, false);
111113

112-
return regcache_sync(tas2770->regmap);
114+
ret = regcache_sync(tas2770->regmap);
115+
if (ret < 0)
116+
return ret;
117+
118+
return tas2770_update_pwr_ctrl(tas2770);
113119
}
114120
#else
115121
#define tas2770_codec_suspend NULL
@@ -544,11 +550,18 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
544550

545551
tas2770->component = component;
546552

553+
ret = regulator_enable(tas2770->sdz_reg);
554+
if (ret != 0) {
555+
dev_err(tas2770->dev, "Failed to enable regulator: %d\n", ret);
556+
return ret;
557+
}
558+
547559
if (tas2770->sdz_gpio) {
548560
gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
549-
usleep_range(1000, 2000);
550561
}
551562

563+
usleep_range(1000, 2000);
564+
552565
tas2770_reset(tas2770);
553566
regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap);
554567

@@ -568,6 +581,13 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
568581
return 0;
569582
}
570583

584+
static void tas2770_codec_remove(struct snd_soc_component *component)
585+
{
586+
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
587+
588+
regulator_disable(tas2770->sdz_reg);
589+
}
590+
571591
static DECLARE_TLV_DB_SCALE(tas2770_digital_tlv, 1100, 50, 0);
572592
static DECLARE_TLV_DB_SCALE(tas2770_playback_volume, -12750, 50, 0);
573593

@@ -580,6 +600,7 @@ static const struct snd_kcontrol_new tas2770_snd_controls[] = {
580600

581601
static const struct snd_soc_component_driver soc_component_driver_tas2770 = {
582602
.probe = tas2770_codec_probe,
603+
.remove = tas2770_codec_remove,
583604
.suspend = tas2770_codec_suspend,
584605
.resume = tas2770_codec_resume,
585606
.controls = tas2770_snd_controls,
@@ -704,6 +725,11 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
704725
tas2770->v_sense_slot = -1;
705726
}
706727

728+
tas2770->sdz_reg = devm_regulator_get(dev, "SDZ");
729+
if (IS_ERR(tas2770->sdz_reg))
730+
return dev_err_probe(dev, PTR_ERR(tas2770->sdz_reg),
731+
"Failed to get SDZ supply\n");
732+
707733
tas2770->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
708734
if (IS_ERR(tas2770->sdz_gpio)) {
709735
if (PTR_ERR(tas2770->sdz_gpio) == -EPROBE_DEFER)

sound/soc/codecs/tas2770.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct tas2770_priv {
134134
struct snd_soc_component *component;
135135
struct gpio_desc *reset_gpio;
136136
struct gpio_desc *sdz_gpio;
137+
struct regulator *sdz_reg;
137138
struct regmap *regmap;
138139
struct device *dev;
139140
int v_sense_slot;

0 commit comments

Comments
 (0)