Skip to content

Commit ce20c1a

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 71bda6f commit ce20c1a

2 files changed

Lines changed: 44 additions & 23 deletions

File tree

sound/soc/codecs/tas2770.c

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

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

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

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

9290
return ret;
9391
}
@@ -97,18 +95,26 @@ static int tas2770_codec_resume(struct snd_soc_component *component)
9795
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
9896
int ret;
9997

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

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

111-
return regcache_sync(tas2770->regmap);
113+
ret = regcache_sync(tas2770->regmap);
114+
if (ret < 0)
115+
return ret;
116+
117+
return tas2770_update_pwr_ctrl(tas2770);
112118
}
113119
#else
114120
#define tas2770_codec_suspend NULL
@@ -543,11 +549,18 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
543549

544550
tas2770->component = component;
545551

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

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

@@ -570,7 +583,9 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
570583
static void tas2770_codec_remove(struct snd_soc_component *component)
571584
{
572585
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
586+
573587
sysfs_remove_groups(&component->dev->kobj, tas2770_sysfs_groups);
588+
regulator_disable(tas2770->sdz_reg);
574589
}
575590

576591
static DECLARE_TLV_DB_SCALE(tas2770_digital_tlv, 1100, 50, 0);
@@ -710,6 +725,11 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
710725
tas2770->v_sense_slot = -1;
711726
}
712727

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+
713733
tas2770->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
714734
if (IS_ERR(tas2770->sdz_gpio)) {
715735
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)