xref: /linux/sound/soc/samsung/tm2_wm5110.c (revision 32786fdc9506aeba98278c1844d4bfb766863832)
1 /*
2  * Copyright (C) 2015 - 2016 Samsung Electronics Co., Ltd.
3  *
4  * Authors: Inha Song <ideal.song@samsung.com>
5  *          Sylwester Nawrocki <s.nawrocki@samsung.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/gpio.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 
20 #include "i2s.h"
21 #include "../codecs/wm5110.h"
22 
23 /*
24  * The source clock is XCLKOUT with its mux set to the external fixed rate
25  * oscillator (XXTI).
26  */
27 #define MCLK_RATE	24000000U
28 
29 #define TM2_DAI_AIF1	0
30 #define TM2_DAI_AIF2	1
31 
32 struct tm2_machine_priv {
33 	struct snd_soc_codec *codec;
34 	unsigned int sysclk_rate;
35 	struct gpio_desc *gpio_mic_bias;
36 };
37 
38 static int tm2_start_sysclk(struct snd_soc_card *card)
39 {
40 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
41 	struct snd_soc_codec *codec = priv->codec;
42 	int ret;
43 
44 	ret = snd_soc_codec_set_pll(codec, WM5110_FLL1_REFCLK,
45 				    ARIZONA_FLL_SRC_MCLK1,
46 				    MCLK_RATE,
47 				    priv->sysclk_rate);
48 	if (ret < 0) {
49 		dev_err(codec->dev, "Failed to set FLL1 source: %d\n", ret);
50 		return ret;
51 	}
52 
53 	ret = snd_soc_codec_set_pll(codec, WM5110_FLL1,
54 				    ARIZONA_FLL_SRC_MCLK1,
55 				    MCLK_RATE,
56 				    priv->sysclk_rate);
57 	if (ret < 0) {
58 		dev_err(codec->dev, "Failed to start FLL1: %d\n", ret);
59 		return ret;
60 	}
61 
62 	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
63 				       ARIZONA_CLK_SRC_FLL1,
64 				       priv->sysclk_rate,
65 				       SND_SOC_CLOCK_IN);
66 	if (ret < 0) {
67 		dev_err(codec->dev, "Failed to set SYSCLK source: %d\n", ret);
68 		return ret;
69 	}
70 
71 	return 0;
72 }
73 
74 static int tm2_stop_sysclk(struct snd_soc_card *card)
75 {
76 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
77 	struct snd_soc_codec *codec = priv->codec;
78 	int ret;
79 
80 	ret = snd_soc_codec_set_pll(codec, WM5110_FLL1, 0, 0, 0);
81 	if (ret < 0) {
82 		dev_err(codec->dev, "Failed to stop FLL1: %d\n", ret);
83 		return ret;
84 	}
85 
86 	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
87 				       ARIZONA_CLK_SRC_FLL1, 0, 0);
88 	if (ret < 0) {
89 		dev_err(codec->dev, "Failed to stop SYSCLK: %d\n", ret);
90 		return ret;
91 	}
92 
93 	return 0;
94 }
95 
96 static int tm2_aif1_hw_params(struct snd_pcm_substream *substream,
97 				struct snd_pcm_hw_params *params)
98 {
99 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
100 	struct snd_soc_codec *codec = rtd->codec;
101 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(rtd->card);
102 
103 	switch (params_rate(params)) {
104 	case 4000:
105 	case 8000:
106 	case 12000:
107 	case 16000:
108 	case 24000:
109 	case 32000:
110 	case 48000:
111 	case 96000:
112 	case 192000:
113 		/* Highest possible SYSCLK frequency: 147.456MHz */
114 		priv->sysclk_rate = 147456000U;
115 		break;
116 	case 11025:
117 	case 22050:
118 	case 44100:
119 	case 88200:
120 	case 176400:
121 		/* Highest possible SYSCLK frequency: 135.4752 MHz */
122 		priv->sysclk_rate = 135475200U;
123 		break;
124 	default:
125 		dev_err(codec->dev, "Not supported sample rate: %d\n",
126 			params_rate(params));
127 		return -EINVAL;
128 	}
129 
130 	return tm2_start_sysclk(rtd->card);
131 }
132 
133 static struct snd_soc_ops tm2_aif1_ops = {
134 	.hw_params = tm2_aif1_hw_params,
135 };
136 
137 static int tm2_aif2_hw_params(struct snd_pcm_substream *substream,
138 				struct snd_pcm_hw_params *params)
139 {
140 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
141 	struct snd_soc_codec *codec = rtd->codec;
142 	unsigned int asyncclk_rate;
143 	int ret;
144 
145 	switch (params_rate(params)) {
146 	case 8000:
147 	case 12000:
148 	case 16000:
149 		/* Highest possible ASYNCCLK frequency: 49.152MHz */
150 		asyncclk_rate = 49152000U;
151 		break;
152 	case 11025:
153 		/* Highest possible ASYNCCLK frequency: 45.1584 MHz */
154 		asyncclk_rate = 45158400U;
155 		break;
156 	default:
157 		dev_err(codec->dev, "Not supported sample rate: %d\n",
158 			params_rate(params));
159 		return -EINVAL;
160 	}
161 
162 	ret = snd_soc_codec_set_pll(codec, WM5110_FLL2_REFCLK,
163 				    ARIZONA_FLL_SRC_MCLK1,
164 				    MCLK_RATE,
165 				    asyncclk_rate);
166 	if (ret < 0) {
167 		dev_err(codec->dev, "Failed to set FLL2 source: %d\n", ret);
168 		return ret;
169 	}
170 
171 	ret = snd_soc_codec_set_pll(codec, WM5110_FLL2,
172 				    ARIZONA_FLL_SRC_MCLK1,
173 				    MCLK_RATE,
174 				    asyncclk_rate);
175 	if (ret < 0) {
176 		dev_err(codec->dev, "Failed to start FLL2: %d\n", ret);
177 		return ret;
178 	}
179 
180 	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
181 				       ARIZONA_CLK_SRC_FLL2,
182 				       asyncclk_rate,
183 				       SND_SOC_CLOCK_IN);
184 	if (ret < 0) {
185 		dev_err(codec->dev, "Failed to set ASYNCCLK source: %d\n", ret);
186 		return ret;
187 	}
188 
189 	return 0;
190 }
191 
192 static int tm2_aif2_hw_free(struct snd_pcm_substream *substream)
193 {
194 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
195 	struct snd_soc_codec *codec = rtd->codec;
196 	int ret;
197 
198 	/* disable FLL2 */
199 	ret = snd_soc_codec_set_pll(codec, WM5110_FLL2, ARIZONA_FLL_SRC_MCLK1,
200 				    0, 0);
201 	if (ret < 0)
202 		dev_err(codec->dev, "Failed to stop FLL2: %d\n", ret);
203 
204 	return ret;
205 }
206 
207 static struct snd_soc_ops tm2_aif2_ops = {
208 	.hw_params = tm2_aif2_hw_params,
209 	.hw_free = tm2_aif2_hw_free,
210 };
211 
212 static int tm2_mic_bias(struct snd_soc_dapm_widget *w,
213 				struct snd_kcontrol *kcontrol, int event)
214 {
215 	struct snd_soc_card *card = w->dapm->card;
216 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
217 
218 	switch (event) {
219 	case SND_SOC_DAPM_PRE_PMU:
220 		gpiod_set_value_cansleep(priv->gpio_mic_bias,  1);
221 		break;
222 	case SND_SOC_DAPM_POST_PMD:
223 		gpiod_set_value_cansleep(priv->gpio_mic_bias,  0);
224 		break;
225 	}
226 
227 	return 0;
228 }
229 
230 static int tm2_set_bias_level(struct snd_soc_card *card,
231 				struct snd_soc_dapm_context *dapm,
232 				enum snd_soc_bias_level level)
233 {
234 	struct snd_soc_pcm_runtime *rtd;
235 
236 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
237 
238 	if (dapm->dev != rtd->codec_dai->dev)
239 		return 0;
240 
241 	switch (level) {
242 	case SND_SOC_BIAS_STANDBY:
243 		if (card->dapm.bias_level == SND_SOC_BIAS_OFF)
244 			tm2_start_sysclk(card);
245 		break;
246 	case SND_SOC_BIAS_OFF:
247 		tm2_stop_sysclk(card);
248 		break;
249 	default:
250 		break;
251 	}
252 
253 	return 0;
254 }
255 
256 static struct snd_soc_aux_dev tm2_speaker_amp_dev;
257 
258 static int tm2_late_probe(struct snd_soc_card *card)
259 {
260 	struct tm2_machine_priv *priv = snd_soc_card_get_drvdata(card);
261 	struct snd_soc_dai_link_component dlc = { 0 };
262 	unsigned int ch_map[] = { 0, 1 };
263 	struct snd_soc_dai *amp_pdm_dai;
264 	struct snd_soc_pcm_runtime *rtd;
265 	struct snd_soc_dai *aif1_dai;
266 	struct snd_soc_dai *aif2_dai;
267 	int ret;
268 
269 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[TM2_DAI_AIF1].name);
270 	aif1_dai = rtd->codec_dai;
271 	priv->codec = rtd->codec;
272 
273 	ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
274 	if (ret < 0) {
275 		dev_err(aif1_dai->dev, "Failed to set SYSCLK: %d\n", ret);
276 		return ret;
277 	}
278 
279 	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[TM2_DAI_AIF2].name);
280 	aif2_dai = rtd->codec_dai;
281 
282 	ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
283 	if (ret < 0) {
284 		dev_err(aif2_dai->dev, "Failed to set ASYNCCLK: %d\n", ret);
285 		return ret;
286 	}
287 
288 	dlc.of_node = tm2_speaker_amp_dev.codec_of_node;
289 	amp_pdm_dai = snd_soc_find_dai(&dlc);
290 	if (!amp_pdm_dai)
291 		return -ENODEV;
292 
293 	/* Set the MAX98504 V/I sense PDM Tx DAI channel mapping */
294 	ret = snd_soc_dai_set_channel_map(amp_pdm_dai, ARRAY_SIZE(ch_map),
295 					  ch_map, 0, NULL);
296 	if (ret < 0)
297 		return ret;
298 
299 	ret = snd_soc_dai_set_tdm_slot(amp_pdm_dai, 0x3, 0x0, 2, 16);
300 	if (ret < 0)
301 		return ret;
302 
303 	return 0;
304 }
305 
306 static const struct snd_kcontrol_new tm2_controls[] = {
307 	SOC_DAPM_PIN_SWITCH("HP"),
308 	SOC_DAPM_PIN_SWITCH("SPK"),
309 	SOC_DAPM_PIN_SWITCH("RCV"),
310 	SOC_DAPM_PIN_SWITCH("VPS"),
311 	SOC_DAPM_PIN_SWITCH("HDMI"),
312 
313 	SOC_DAPM_PIN_SWITCH("Main Mic"),
314 	SOC_DAPM_PIN_SWITCH("Sub Mic"),
315 	SOC_DAPM_PIN_SWITCH("Third Mic"),
316 
317 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
318 };
319 
320 const struct snd_soc_dapm_widget tm2_dapm_widgets[] = {
321 	SND_SOC_DAPM_HP("HP", NULL),
322 	SND_SOC_DAPM_SPK("SPK", NULL),
323 	SND_SOC_DAPM_SPK("RCV", NULL),
324 	SND_SOC_DAPM_LINE("VPS", NULL),
325 	SND_SOC_DAPM_LINE("HDMI", NULL),
326 
327 	SND_SOC_DAPM_MIC("Main Mic", tm2_mic_bias),
328 	SND_SOC_DAPM_MIC("Sub Mic", NULL),
329 	SND_SOC_DAPM_MIC("Third Mic", NULL),
330 
331 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
332 };
333 
334 static const struct snd_soc_component_driver tm2_component = {
335 	.name	= "tm2-audio",
336 };
337 
338 static struct snd_soc_dai_driver tm2_ext_dai[] = {
339 	{
340 		.name = "Voice call",
341 		.playback = {
342 			.channels_min = 1,
343 			.channels_max = 4,
344 			.rate_min = 8000,
345 			.rate_max = 48000,
346 			.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
347 					SNDRV_PCM_RATE_48000),
348 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
349 		},
350 		.capture = {
351 			.channels_min = 1,
352 			.channels_max = 4,
353 			.rate_min = 8000,
354 			.rate_max = 48000,
355 			.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
356 					SNDRV_PCM_RATE_48000),
357 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
358 		},
359 	},
360 	{
361 		.name = "Bluetooth",
362 		.playback = {
363 			.channels_min = 1,
364 			.channels_max = 4,
365 			.rate_min = 8000,
366 			.rate_max = 16000,
367 			.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
368 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
369 		},
370 		.capture = {
371 			.channels_min = 1,
372 			.channels_max = 2,
373 			.rate_min = 8000,
374 			.rate_max = 16000,
375 			.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
376 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
377 		},
378 	},
379 };
380 
381 static struct snd_soc_dai_link tm2_dai_links[] = {
382 	{
383 		.name		= "WM5110 AIF1",
384 		.stream_name	= "HiFi Primary",
385 		.codec_dai_name = "wm5110-aif1",
386 		.ops		= &tm2_aif1_ops,
387 		.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
388 				  SND_SOC_DAIFMT_CBM_CFM,
389 	}, {
390 		.name		= "WM5110 Voice",
391 		.stream_name	= "Voice call",
392 		.codec_dai_name = "wm5110-aif2",
393 		.ops		= &tm2_aif2_ops,
394 		.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
395 				  SND_SOC_DAIFMT_CBM_CFM,
396 		.ignore_suspend = 1,
397 	}, {
398 		.name		= "WM5110 BT",
399 		.stream_name	= "Bluetooth",
400 		.codec_dai_name = "wm5110-aif3",
401 		.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
402 				  SND_SOC_DAIFMT_CBM_CFM,
403 		.ignore_suspend = 1,
404 	}
405 };
406 
407 static struct snd_soc_card tm2_card = {
408 	.owner			= THIS_MODULE,
409 
410 	.dai_link		= tm2_dai_links,
411 	.num_links		= ARRAY_SIZE(tm2_dai_links),
412 	.controls		= tm2_controls,
413 	.num_controls		= ARRAY_SIZE(tm2_controls),
414 	.dapm_widgets		= tm2_dapm_widgets,
415 	.num_dapm_widgets	= ARRAY_SIZE(tm2_dapm_widgets),
416 	.aux_dev		= &tm2_speaker_amp_dev,
417 	.num_aux_devs		= 1,
418 
419 	.late_probe		= tm2_late_probe,
420 	.set_bias_level		= tm2_set_bias_level,
421 };
422 
423 static int tm2_probe(struct platform_device *pdev)
424 {
425 	struct device *dev = &pdev->dev;
426 	struct snd_soc_card *card = &tm2_card;
427 	struct tm2_machine_priv *priv;
428 	struct device_node *cpu_dai_node, *codec_dai_node;
429 	int ret, i;
430 
431 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
432 	if (!priv)
433 		return -ENOMEM;
434 
435 	snd_soc_card_set_drvdata(card, priv);
436 	card->dev = dev;
437 
438 	priv->gpio_mic_bias = devm_gpiod_get(dev, "mic-bias",
439 						GPIOF_OUT_INIT_LOW);
440 	if (IS_ERR(priv->gpio_mic_bias)) {
441 		dev_err(dev, "Failed to get mic bias gpio\n");
442 		return PTR_ERR(priv->gpio_mic_bias);
443 	}
444 
445 	ret = snd_soc_of_parse_card_name(card, "model");
446 	if (ret < 0) {
447 		dev_err(dev, "Card name is not specified\n");
448 		return ret;
449 	}
450 
451 	ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing");
452 	if (ret < 0) {
453 		dev_err(dev, "Audio routing is not specified or invalid\n");
454 		return ret;
455 	}
456 
457 	card->aux_dev[0].codec_of_node = of_parse_phandle(dev->of_node,
458 							"audio-amplifier", 0);
459 	if (!card->aux_dev[0].codec_of_node) {
460 		dev_err(dev, "audio-amplifier property invalid or missing\n");
461 		return -EINVAL;
462 	}
463 
464 	cpu_dai_node = of_parse_phandle(dev->of_node, "i2s-controller", 0);
465 	if (!cpu_dai_node) {
466 		dev_err(dev, "i2s-controllers property invalid or missing\n");
467 		ret = -EINVAL;
468 		goto amp_node_put;
469 	}
470 
471 	codec_dai_node = of_parse_phandle(dev->of_node, "audio-codec", 0);
472 	if (!codec_dai_node) {
473 		dev_err(dev, "audio-codec property invalid or missing\n");
474 		ret = -EINVAL;
475 		goto cpu_dai_node_put;
476 	}
477 
478 	for (i = 0; i < card->num_links; i++) {
479 		card->dai_link[i].cpu_dai_name = NULL;
480 		card->dai_link[i].cpu_name = NULL;
481 		card->dai_link[i].platform_name = NULL;
482 		card->dai_link[i].codec_of_node = codec_dai_node;
483 		card->dai_link[i].cpu_of_node = cpu_dai_node;
484 		card->dai_link[i].platform_of_node = cpu_dai_node;
485 	}
486 
487 	ret = devm_snd_soc_register_component(dev, &tm2_component,
488 				tm2_ext_dai, ARRAY_SIZE(tm2_ext_dai));
489 	if (ret < 0) {
490 		dev_err(dev, "Failed to register component: %d\n", ret);
491 		goto codec_dai_node_put;
492 	}
493 
494 	ret = devm_snd_soc_register_card(dev, card);
495 	if (ret < 0) {
496 		dev_err(dev, "Failed to register card: %d\n", ret);
497 		goto codec_dai_node_put;
498 	}
499 
500 codec_dai_node_put:
501 	of_node_put(codec_dai_node);
502 cpu_dai_node_put:
503 	of_node_put(cpu_dai_node);
504 amp_node_put:
505 	of_node_put(card->aux_dev[0].codec_of_node);
506 	return ret;
507 }
508 
509 static int tm2_pm_prepare(struct device *dev)
510 {
511 	struct snd_soc_card *card = dev_get_drvdata(dev);
512 
513 	return tm2_stop_sysclk(card);
514 }
515 
516 static void tm2_pm_complete(struct device *dev)
517 {
518 	struct snd_soc_card *card = dev_get_drvdata(dev);
519 
520 	tm2_start_sysclk(card);
521 }
522 
523 const struct dev_pm_ops tm2_pm_ops = {
524 	.prepare	= tm2_pm_prepare,
525 	.suspend	= snd_soc_suspend,
526 	.resume		= snd_soc_resume,
527 	.complete	= tm2_pm_complete,
528 	.freeze		= snd_soc_suspend,
529 	.thaw		= snd_soc_resume,
530 	.poweroff	= snd_soc_poweroff,
531 	.restore	= snd_soc_resume,
532 };
533 
534 static const struct of_device_id tm2_of_match[] = {
535 	{ .compatible = "samsung,tm2-audio" },
536 	{ },
537 };
538 MODULE_DEVICE_TABLE(of, tm2_of_match);
539 
540 static struct platform_driver tm2_driver = {
541 	.driver = {
542 		.name		= "tm2-audio",
543 		.pm		= &tm2_pm_ops,
544 		.of_match_table	= tm2_of_match,
545 	},
546 	.probe	= tm2_probe,
547 };
548 module_platform_driver(tm2_driver);
549 
550 MODULE_AUTHOR("Inha Song <ideal.song@samsung.com>");
551 MODULE_DESCRIPTION("ALSA SoC Exynos TM2 Audio Support");
552 MODULE_LICENSE("GPL v2");
553