Skip to content

Commit 1631d33

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 386949c commit 1631d33

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
@@ -73,23 +73,21 @@ static int tas2770_codec_suspend(struct snd_soc_component *component)
7373
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
7474
int ret = 0;
7575

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

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

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

9492
return ret;
9593
}
@@ -99,18 +97,26 @@ static int tas2770_codec_resume(struct snd_soc_component *component)
9997
struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
10098
int ret;
10199

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

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

113-
return regcache_sync(tas2770->regmap);
115+
ret = regcache_sync(tas2770->regmap);
116+
if (ret < 0)
117+
return ret;
118+
119+
return tas2770_update_pwr_ctrl(tas2770);
114120
}
115121
#else
116122
#define tas2770_codec_suspend NULL
@@ -545,11 +551,18 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
545551

546552
tas2770->component = component;
547553

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

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

@@ -569,6 +582,13 @@ static int tas2770_codec_probe(struct snd_soc_component *component)
569582
return 0;
570583
}
571584

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

@@ -581,6 +601,7 @@ static const struct snd_kcontrol_new tas2770_snd_controls[] = {
581601

582602
static const struct snd_soc_component_driver soc_component_driver_tas2770 = {
583603
.probe = tas2770_codec_probe,
604+
.remove = tas2770_codec_remove,
584605
.suspend = tas2770_codec_suspend,
585606
.resume = tas2770_codec_resume,
586607
.controls = tas2770_snd_controls,
@@ -705,6 +726,11 @@ static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
705726
tas2770->v_sense_slot = -1;
706727
}
707728

729+
tas2770->sdz_reg = devm_regulator_get(dev, "SDZ");
730+
if (IS_ERR(tas2770->sdz_reg))
731+
return dev_err_probe(dev, PTR_ERR(tas2770->sdz_reg),
732+
"Failed to get SDZ supply\n");
733+
708734
tas2770->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
709735
if (IS_ERR(tas2770->sdz_gpio)) {
710736
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)