Skip to content

Commit 6d2de5a

Browse files
Helen Koikebroonie
authored andcommitted
ASoC: tpa6130a2: Add DAPM support
Add DAPM support and updated rx51 accordingly. As a consequence: - the exported function tpa6130a2_stereo_enable is not needed anymore - the mutex is dealt in the DAPM - the power state is tracked by the DAPM Signed-off-by: Lars-Peter Clausen <[email protected]> [koike: port for upstream] Signed-off-by: Helen Koike <[email protected]> Tested-by: Sebastian Reichel <[email protected]> Reviewed-by: Sebastian Reichel <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent e01d700 commit 6d2de5a

File tree

3 files changed

+89
-130
lines changed

3 files changed

+89
-130
lines changed

sound/soc/codecs/tpa6130a2.c

Lines changed: 77 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -41,79 +41,74 @@ enum tpa_model {
4141
TPA6140A2,
4242
};
4343

44-
static struct i2c_client *tpa6130a2_client;
45-
4644
/* This struct is used to save the context */
4745
struct tpa6130a2_data {
48-
struct mutex mutex;
46+
struct device *dev;
4947
struct regmap *regmap;
5048
struct regulator *supply;
5149
int power_gpio;
52-
u8 power_state:1;
5350
enum tpa_model id;
5451
};
5552

56-
static int tpa6130a2_power(u8 power)
53+
static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
5754
{
58-
struct tpa6130a2_data *data;
59-
int ret = 0;
60-
61-
if (WARN_ON(!tpa6130a2_client))
62-
return -EINVAL;
63-
data = i2c_get_clientdata(tpa6130a2_client);
64-
65-
mutex_lock(&data->mutex);
66-
if (power == data->power_state)
67-
goto exit;
55+
int ret;
6856

69-
if (power) {
57+
if (enable) {
7058
ret = regulator_enable(data->supply);
7159
if (ret != 0) {
72-
dev_err(&tpa6130a2_client->dev,
60+
dev_err(data->dev,
7361
"Failed to enable supply: %d\n", ret);
74-
goto exit;
62+
return ret;
7563
}
7664
/* Power on */
7765
if (data->power_gpio >= 0)
7866
gpio_set_value(data->power_gpio, 1);
79-
80-
data->power_state = 1;
81-
ret = regcache_sync(data->regmap);
82-
if (ret < 0) {
83-
dev_err(&tpa6130a2_client->dev,
84-
"Failed to initialize chip\n");
85-
if (data->power_gpio >= 0)
86-
gpio_set_value(data->power_gpio, 0);
87-
regulator_disable(data->supply);
88-
data->power_state = 0;
89-
goto exit;
90-
}
9167
} else {
92-
/* set SWS */
93-
regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
94-
TPA6130A2_SWS, TPA6130A2_SWS);
95-
9668
/* Power off */
9769
if (data->power_gpio >= 0)
9870
gpio_set_value(data->power_gpio, 0);
9971

10072
ret = regulator_disable(data->supply);
10173
if (ret != 0) {
102-
dev_err(&tpa6130a2_client->dev,
74+
dev_err(data->dev,
10375
"Failed to disable supply: %d\n", ret);
104-
goto exit;
76+
return ret;
10577
}
10678

107-
data->power_state = 0;
10879
/* device regs does not match the cache state anymore */
10980
regcache_mark_dirty(data->regmap);
11081
}
11182

112-
exit:
113-
mutex_unlock(&data->mutex);
11483
return ret;
11584
}
11685

86+
static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
87+
struct snd_kcontrol *kctrl, int event)
88+
{
89+
struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
90+
struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
91+
int ret;
92+
93+
/* before widget power up */
94+
if (SND_SOC_DAPM_EVENT_ON(event)) {
95+
/* Turn on the chip */
96+
tpa6130a2_power(data, true);
97+
/* Sync the registers */
98+
ret = regcache_sync(data->regmap);
99+
if (ret < 0) {
100+
dev_err(c->dev, "Failed to initialize chip\n");
101+
tpa6130a2_power(data, false);
102+
return ret;
103+
}
104+
/* after widget power down */
105+
} else {
106+
tpa6130a2_power(data, false);
107+
}
108+
109+
return 0;
110+
}
111+
117112
/*
118113
* TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
119114
* down in gain.
@@ -149,57 +144,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
149144
tpa6140_tlv),
150145
};
151146

152-
/*
153-
* Enable or disable channel (left or right)
154-
* The bit number for mute and amplifier are the same per channel:
155-
* bit 6: Right channel
156-
* bit 7: Left channel
157-
* in both registers.
158-
*/
159-
static void tpa6130a2_channel_enable(u8 channel, int enable)
160-
{
161-
struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
162-
163-
if (enable) {
164-
/* Enable channel */
165-
/* Enable amplifier */
166-
regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
167-
channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
168-
169-
/* Unmute channel */
170-
regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
171-
channel, 0);
172-
} else {
173-
/* Disable channel */
174-
/* Mute channel */
175-
regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
176-
channel, channel);
177-
178-
/* Disable amplifier */
179-
regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
180-
channel, 0);
181-
}
182-
}
183-
184-
int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
185-
{
186-
int ret = 0;
187-
if (enable) {
188-
ret = tpa6130a2_power(1);
189-
if (ret < 0)
190-
return ret;
191-
tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
192-
1);
193-
} else {
194-
tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
195-
0);
196-
ret = tpa6130a2_power(0);
197-
}
198-
199-
return ret;
200-
}
201-
EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
202-
203147
static int tpa6130a2_component_probe(struct snd_soc_component *component)
204148
{
205149
struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
@@ -212,9 +156,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
212156
tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
213157
}
214158

159+
static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
160+
SND_SOC_DAPM_INPUT("LEFTIN"),
161+
SND_SOC_DAPM_INPUT("RIGHTIN"),
162+
SND_SOC_DAPM_OUTPUT("HPLEFT"),
163+
SND_SOC_DAPM_OUTPUT("HPRIGHT"),
164+
165+
SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
166+
TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
167+
SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
168+
TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
169+
SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
170+
TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
171+
SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
172+
TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
173+
174+
SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
175+
TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
176+
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
177+
};
178+
179+
static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
180+
{ "Left PGA", NULL, "LEFTIN" },
181+
{ "Right PGA", NULL, "RIGHTIN" },
182+
183+
{ "Left Mute", NULL, "Left PGA" },
184+
{ "Right Mute", NULL, "Right PGA" },
185+
186+
{ "HPLEFT", NULL, "Left Mute" },
187+
{ "HPRIGHT", NULL, "Right Mute" },
188+
189+
{ "Left PGA", NULL, "Power" },
190+
{ "Right PGA", NULL, "Power" },
191+
};
192+
215193
struct snd_soc_component_driver tpa6130a2_component_driver = {
216194
.name = "tpa6130a2",
217195
.probe = tpa6130a2_component_probe,
196+
.dapm_widgets = tpa6130a2_dapm_widgets,
197+
.num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
198+
.dapm_routes = tpa6130a2_dapm_routes,
199+
.num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
218200
};
219201

220202
static const struct reg_default tpa6130a2_reg_defaults[] = {
@@ -248,6 +230,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
248230
if (!data)
249231
return -ENOMEM;
250232

233+
data->dev = dev;
234+
251235
data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
252236
if (IS_ERR(data->regmap))
253237
return PTR_ERR(data->regmap);
@@ -262,14 +246,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
262246
return -ENODEV;
263247
}
264248

265-
tpa6130a2_client = client;
266-
267-
i2c_set_clientdata(tpa6130a2_client, data);
249+
i2c_set_clientdata(client, data);
268250

269251
data->id = id->driver_data;
270252

271-
mutex_init(&data->mutex);
272-
273253
if (data->power_gpio >= 0) {
274254
ret = devm_gpio_request(dev, data->power_gpio,
275255
"tpa6130a2 enable");
@@ -300,7 +280,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
300280
goto err_gpio;
301281
}
302282

303-
ret = tpa6130a2_power(1);
283+
ret = tpa6130a2_power(data, true);
304284
if (ret != 0)
305285
goto err_gpio;
306286

@@ -312,27 +292,17 @@ static int tpa6130a2_probe(struct i2c_client *client,
312292
dev_warn(dev, "UNTESTED version detected (%d)\n", version);
313293

314294
/* Disable the chip */
315-
ret = tpa6130a2_power(0);
295+
ret = tpa6130a2_power(data, false);
316296
if (ret != 0)
317297
goto err_gpio;
318298

319299
return devm_snd_soc_register_component(&client->dev,
320300
&tpa6130a2_component_driver, NULL, 0);
321301

322302
err_gpio:
323-
tpa6130a2_client = NULL;
324-
325303
return ret;
326304
}
327305

328-
static int tpa6130a2_remove(struct i2c_client *client)
329-
{
330-
tpa6130a2_power(0);
331-
tpa6130a2_client = NULL;
332-
333-
return 0;
334-
}
335-
336306
static const struct i2c_device_id tpa6130a2_id[] = {
337307
{ "tpa6130a2", TPA6130A2 },
338308
{ "tpa6140a2", TPA6140A2 },
@@ -355,7 +325,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
355325
.of_match_table = of_match_ptr(tpa6130a2_of_match),
356326
},
357327
.probe = tpa6130a2_probe,
358-
.remove = tpa6130a2_remove,
359328
.id_table = tpa6130a2_id,
360329
};
361330

sound/soc/codecs/tpa6130a2.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,18 @@
3232

3333
/* Register bits */
3434
/* TPA6130A2_REG_CONTROL (0x01) */
35-
#define TPA6130A2_SWS (0x01 << 0)
35+
#define TPA6130A2_SWS_SHIFT 0
36+
#define TPA6130A2_SWS (0x01 << TPA6130A2_SWS_SHIFT)
3637
#define TPA6130A2_TERMAL (0x01 << 1)
3738
#define TPA6130A2_MODE(x) (x << 4)
3839
#define TPA6130A2_MODE_STEREO (0x00)
3940
#define TPA6130A2_MODE_DUAL_MONO (0x01)
4041
#define TPA6130A2_MODE_BRIDGE (0x02)
4142
#define TPA6130A2_MODE_MASK (0x03)
42-
#define TPA6130A2_HP_EN_R (0x01 << 6)
43-
#define TPA6130A2_HP_EN_L (0x01 << 7)
43+
#define TPA6130A2_HP_EN_R_SHIFT 6
44+
#define TPA6130A2_HP_EN_R (0x01 << TPA6130A2_HP_EN_R_SHIFT)
45+
#define TPA6130A2_HP_EN_L_SHIFT 7
46+
#define TPA6130A2_HP_EN_L (0x01 << TPA6130A2_HP_EN_L_SHIFT)
4447

4548
/* TPA6130A2_REG_VOL_MUTE (0x02) */
4649
#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
@@ -54,6 +57,4 @@
5457
/* TPA6130A2_REG_VERSION (0x04) */
5558
#define TPA6130A2_VERSION_MASK (0x0f)
5659

57-
extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
58-
5960
#endif /* __TPA6130A2_H__ */

sound/soc/omap/rx51.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include <sound/pcm.h>
3434
#include <sound/soc.h>
3535
#include <linux/platform_data/asoc-ti-mcbsp.h>
36-
#include "../codecs/tpa6130a2.h"
3736

3837
#include <asm/mach-types.h>
3938

@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
164163
return 0;
165164
}
166165

167-
static int rx51_hp_event(struct snd_soc_dapm_widget *w,
168-
struct snd_kcontrol *k, int event)
169-
{
170-
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
171-
172-
if (SND_SOC_DAPM_EVENT_ON(event))
173-
tpa6130a2_stereo_enable(codec, 1);
174-
else
175-
tpa6130a2_stereo_enable(codec, 0);
176-
177-
return 0;
178-
}
179-
180166
static int rx51_get_input(struct snd_kcontrol *kcontrol,
181167
struct snd_ctl_elem_value *ucontrol)
182168
{
@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
235221
static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
236222
SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
237223
SND_SOC_DAPM_MIC("DMic", NULL),
238-
SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
224+
SND_SOC_DAPM_HP("Headphone Jack", NULL),
239225
SND_SOC_DAPM_MIC("HS Mic", NULL),
240226
SND_SOC_DAPM_LINE("FM Transmitter", NULL),
241227
SND_SOC_DAPM_SPK("Earphone", NULL),
@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
246232
{"Ext Spk", NULL, "HPROUT"},
247233
{"Ext Spk", NULL, "HPLCOM"},
248234
{"Ext Spk", NULL, "HPRCOM"},
249-
{"Headphone Jack", NULL, "LLOUT"},
250-
{"Headphone Jack", NULL, "RLOUT"},
251235
{"FM Transmitter", NULL, "LLOUT"},
252236
{"FM Transmitter", NULL, "RLOUT"},
253237

238+
{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
239+
{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
240+
{"TPA6130A2 LEFTIN", NULL, "LLOUT"},
241+
{"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
242+
254243
{"DMic Rate 64", NULL, "DMic"},
255244
{"DMic", NULL, "Mic Bias"},
256245

0 commit comments

Comments
 (0)