aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tas2552.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tas2552.c')
-rw-r--r--sound/soc/codecs/tas2552.c70
1 files changed, 50 insertions, 20 deletions
diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c
index 23b32960ff1d..f039dc825971 100644
--- a/sound/soc/codecs/tas2552.c
+++ b/sound/soc/codecs/tas2552.c
@@ -78,6 +78,44 @@ struct tas2552_data {
78 unsigned int mclk; 78 unsigned int mclk;
79}; 79};
80 80
81/* Input mux controls */
82static const char *tas2552_input_texts[] = {
83 "Digital", "Analog"
84};
85
86static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7,
87 tas2552_input_texts);
88
89static const struct snd_kcontrol_new tas2552_input_mux_control[] = {
90 SOC_DAPM_ENUM("Input selection", tas2552_input_mux_enum)
91};
92
93static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] =
94{
95 SND_SOC_DAPM_INPUT("IN"),
96
97 /* MUX Controls */
98 SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0,
99 tas2552_input_mux_control),
100
101 SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0),
102 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
103 SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0),
104 SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0),
105
106 SND_SOC_DAPM_OUTPUT("OUT")
107};
108
109static const struct snd_soc_dapm_route tas2552_audio_map[] = {
110 {"DAC", NULL, "DAC IN"},
111 {"Input selection", "Digital", "DAC"},
112 {"Input selection", "Analog", "IN"},
113 {"ClassD", NULL, "Input selection"},
114 {"OUT", NULL, "ClassD"},
115 {"ClassD", NULL, "PLL"},
116};
117
118#ifdef CONFIG_PM_RUNTIME
81static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) 119static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
82{ 120{
83 u8 cfg1_reg; 121 u8 cfg1_reg;
@@ -90,6 +128,7 @@ static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown)
90 snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1, 128 snd_soc_update_bits(tas_data->codec, TAS2552_CFG_1,
91 TAS2552_SWS_MASK, cfg1_reg); 129 TAS2552_SWS_MASK, cfg1_reg);
92} 130}
131#endif
93 132
94static int tas2552_hw_params(struct snd_pcm_substream *substream, 133static int tas2552_hw_params(struct snd_pcm_substream *substream,
95 struct snd_pcm_hw_params *params, 134 struct snd_pcm_hw_params *params,
@@ -101,10 +140,6 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
101 int d; 140 int d;
102 u8 p, j; 141 u8 p, j;
103 142
104 /* Turn on Class D amplifier */
105 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN_MASK,
106 TAS2552_CLASSD_EN);
107
108 if (!tas2552->mclk) 143 if (!tas2552->mclk)
109 return -EINVAL; 144 return -EINVAL;
110 145
@@ -147,9 +182,6 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream,
147 182
148 } 183 }
149 184
150 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE,
151 TAS2552_PLL_ENABLE);
152
153 return 0; 185 return 0;
154} 186}
155 187
@@ -269,19 +301,10 @@ static const struct dev_pm_ops tas2552_pm = {
269 NULL) 301 NULL)
270}; 302};
271 303
272static void tas2552_shutdown(struct snd_pcm_substream *substream,
273 struct snd_soc_dai *dai)
274{
275 struct snd_soc_codec *codec = dai->codec;
276
277 snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0);
278}
279
280static struct snd_soc_dai_ops tas2552_speaker_dai_ops = { 304static struct snd_soc_dai_ops tas2552_speaker_dai_ops = {
281 .hw_params = tas2552_hw_params, 305 .hw_params = tas2552_hw_params,
282 .set_sysclk = tas2552_set_dai_sysclk, 306 .set_sysclk = tas2552_set_dai_sysclk,
283 .set_fmt = tas2552_set_dai_fmt, 307 .set_fmt = tas2552_set_dai_fmt,
284 .shutdown = tas2552_shutdown,
285 .digital_mute = tas2552_mute, 308 .digital_mute = tas2552_mute,
286}; 309};
287 310
@@ -294,7 +317,7 @@ static struct snd_soc_dai_driver tas2552_dai[] = {
294 { 317 {
295 .name = "tas2552-amplifier", 318 .name = "tas2552-amplifier",
296 .playback = { 319 .playback = {
297 .stream_name = "Speaker", 320 .stream_name = "Playback",
298 .channels_min = 2, 321 .channels_min = 2,
299 .channels_max = 2, 322 .channels_max = 2,
300 .rates = SNDRV_PCM_RATE_8000_192000, 323 .rates = SNDRV_PCM_RATE_8000_192000,
@@ -312,6 +335,7 @@ static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 24);
312static const struct snd_kcontrol_new tas2552_snd_controls[] = { 335static const struct snd_kcontrol_new tas2552_snd_controls[] = {
313 SOC_SINGLE_TLV("Speaker Driver Playback Volume", 336 SOC_SINGLE_TLV("Speaker Driver Playback Volume",
314 TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv), 337 TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv),
338 SOC_DAPM_SINGLE("Playback AMP", SND_SOC_NOPM, 0, 1, 0),
315}; 339};
316 340
317static const struct reg_default tas2552_init_regs[] = { 341static const struct reg_default tas2552_init_regs[] = {
@@ -321,6 +345,7 @@ static const struct reg_default tas2552_init_regs[] = {
321static int tas2552_codec_probe(struct snd_soc_codec *codec) 345static int tas2552_codec_probe(struct snd_soc_codec *codec)
322{ 346{
323 struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); 347 struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec);
348 struct snd_soc_dapm_context *dapm = &codec->dapm;
324 int ret; 349 int ret;
325 350
326 tas2552->codec = codec; 351 tas2552->codec = codec;
@@ -362,9 +387,14 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec)
362 goto patch_fail; 387 goto patch_fail;
363 } 388 }
364 389
365 snd_soc_write(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN | 390 snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN |
366 TAS2552_BOOST_EN | TAS2552_APT_EN | 391 TAS2552_APT_EN | TAS2552_LIM_EN);
367 TAS2552_LIM_EN); 392
393 snd_soc_dapm_new_controls(dapm, tas2552_dapm_widgets,
394 ARRAY_SIZE(tas2552_dapm_widgets));
395 snd_soc_dapm_add_routes(dapm, tas2552_audio_map,
396 ARRAY_SIZE(tas2552_audio_map));
397
368 return 0; 398 return 0;
369 399
370patch_fail: 400patch_fail: