xref: /linux/sound/soc/intel/boards/sof_maxim_common.c (revision 34864c05a54d1bc544c8c3939aababbc481d99e3)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Copyright(c) 2020 Intel Corporation
4 #include <linux/module.h>
5 #include <linux/string.h>
6 #include <sound/pcm.h>
7 #include <sound/pcm_params.h>
8 #include <sound/soc.h>
9 #include <sound/soc-acpi.h>
10 #include <sound/soc-dai.h>
11 #include <sound/soc-dapm.h>
12 #include <sound/sof.h>
13 #include <uapi/sound/asound.h>
14 #include "../common/soc-intel-quirks.h"
15 #include "sof_maxim_common.h"
16 
17 /*
18  * Common structures and functions
19  */
20 static const struct snd_kcontrol_new maxim_2spk_kcontrols[] = {
21 	SOC_DAPM_PIN_SWITCH("Left Spk"),
22 	SOC_DAPM_PIN_SWITCH("Right Spk"),
23 
24 };
25 
26 static const struct snd_soc_dapm_widget maxim_2spk_widgets[] = {
27 	SND_SOC_DAPM_SPK("Left Spk", NULL),
28 	SND_SOC_DAPM_SPK("Right Spk", NULL),
29 };
30 
31 /* helper function to get the number of specific codec */
32 static unsigned int get_num_codecs(const char *hid)
33 {
34 	struct acpi_device *adev;
35 	unsigned int dev_num = 0;
36 
37 	for_each_acpi_dev_match(adev, hid, NULL, -1)
38 		dev_num++;
39 
40 	return dev_num;
41 }
42 
43 /*
44  * Maxim MAX98373
45  */
46 #define MAX_98373_PIN_NAME 16
47 
48 static const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
49 	/* speaker */
50 	{ "Left Spk", NULL, "Left BE_OUT" },
51 	{ "Right Spk", NULL, "Right BE_OUT" },
52 };
53 
54 static struct snd_soc_codec_conf max_98373_codec_conf[] = {
55 	{
56 		.dlc = COMP_CODEC_CONF(MAX_98373_DEV0_NAME),
57 		.name_prefix = "Right",
58 	},
59 	{
60 		.dlc = COMP_CODEC_CONF(MAX_98373_DEV1_NAME),
61 		.name_prefix = "Left",
62 	},
63 };
64 
65 static struct snd_soc_dai_link_component max_98373_components[] = {
66 	{  /* For Right */
67 		.name = MAX_98373_DEV0_NAME,
68 		.dai_name = MAX_98373_CODEC_DAI,
69 	},
70 	{  /* For Left */
71 		.name = MAX_98373_DEV1_NAME,
72 		.dai_name = MAX_98373_CODEC_DAI,
73 	},
74 };
75 
76 /*
77  * According to the definition of 'DAI Sel Mux' mixer in max98373.c, rx mask
78  * should choose two channels from TDM slots, the LSB of rx mask is left channel
79  * and the other one is right channel.
80  *
81  * For tx mask, each codec requires two channels: one for V-sense and the other
82  * one for I-sense. Must match the device property "maxim,vmon-slot-no" and
83  * "maxim,imon-slot-no" in ACPI table.
84  */
85 static const struct {
86 	unsigned int tx;
87 	unsigned int rx;
88 } max_98373_tdm_mask[] = {
89 	{.tx = 0x03, .rx = 0x3},
90 	{.tx = 0x0c, .rx = 0x3},
91 };
92 
93 static int max_98373_hw_params(struct snd_pcm_substream *substream,
94 			       struct snd_pcm_hw_params *params)
95 {
96 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
97 	struct snd_soc_dai_link *dai_link = rtd->dai_link;
98 	struct snd_soc_dai *codec_dai;
99 	int i;
100 	int tdm_slots;
101 	int ret = 0;
102 
103 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
104 		if (i >= ARRAY_SIZE(max_98373_tdm_mask)) {
105 			dev_err(codec_dai->dev, "only 2 amps are supported\n");
106 			return -EINVAL;
107 		}
108 
109 		switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
110 		case SND_SOC_DAIFMT_DSP_A:
111 		case SND_SOC_DAIFMT_DSP_B:
112 			/* get the tplg configured tdm slot number */
113 			tdm_slots = sof_dai_get_tdm_slots(rtd);
114 			if (tdm_slots <= 0) {
115 				dev_err(rtd->dev, "invalid tdm slots %d\n",
116 					tdm_slots);
117 				return -EINVAL;
118 			}
119 
120 			/*
121 			 * check if tdm slot number is too small for channel
122 			 * allocation
123 			 */
124 			if (fls(max_98373_tdm_mask[i].tx) > tdm_slots) {
125 				dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",
126 					fls(max_98373_tdm_mask[i].tx), tdm_slots);
127 				return -EINVAL;
128 			}
129 
130 			if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) {
131 				dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n",
132 					fls(max_98373_tdm_mask[i].rx), tdm_slots);
133 				return -EINVAL;
134 			}
135 
136 			dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n",
137 				max_98373_tdm_mask[i].tx,
138 				max_98373_tdm_mask[i].rx,
139 				tdm_slots, params_width(params));
140 
141 			ret = snd_soc_dai_set_tdm_slot(codec_dai,
142 						       max_98373_tdm_mask[i].tx,
143 						       max_98373_tdm_mask[i].rx,
144 						       tdm_slots,
145 						       params_width(params));
146 			if (ret < 0) {
147 				dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
148 					ret);
149 				return ret;
150 			}
151 			break;
152 		default:
153 			dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
154 			break;
155 		}
156 	}
157 	return 0;
158 }
159 
160 static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd)
161 {
162 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
163 	struct snd_soc_dai *codec_dai;
164 	struct snd_soc_dai *cpu_dai;
165 	int j;
166 	int ret = 0;
167 
168 	/* set spk pin by playback only */
169 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
170 		return 0;
171 
172 	cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
173 	for_each_rtd_codec_dais(rtd, j, codec_dai) {
174 		struct snd_soc_dapm_context *dapm =
175 				snd_soc_component_get_dapm(cpu_dai->component);
176 		char pin_name[MAX_98373_PIN_NAME];
177 
178 		snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
179 			 codec_dai->component->name_prefix);
180 
181 		switch (cmd) {
182 		case SNDRV_PCM_TRIGGER_START:
183 		case SNDRV_PCM_TRIGGER_RESUME:
184 		case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
185 			ret = snd_soc_dapm_enable_pin(dapm, pin_name);
186 			if (!ret)
187 				snd_soc_dapm_sync(dapm);
188 			break;
189 		case SNDRV_PCM_TRIGGER_STOP:
190 		case SNDRV_PCM_TRIGGER_SUSPEND:
191 		case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
192 			ret = snd_soc_dapm_disable_pin(dapm, pin_name);
193 			if (!ret)
194 				snd_soc_dapm_sync(dapm);
195 			break;
196 		default:
197 			break;
198 		}
199 	}
200 
201 	return ret;
202 }
203 
204 static const struct snd_soc_ops max_98373_ops = {
205 	.hw_params = max_98373_hw_params,
206 	.trigger = max_98373_trigger,
207 };
208 
209 static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
210 {
211 	struct snd_soc_card *card = rtd->card;
212 	unsigned int num_codecs = get_num_codecs(MAX_98373_ACPI_HID);
213 	int ret;
214 
215 	switch (num_codecs) {
216 	case 2:
217 		ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets,
218 						ARRAY_SIZE(maxim_2spk_widgets));
219 		if (ret) {
220 			dev_err(rtd->dev, "fail to add max98373 widgets, ret %d\n",
221 				ret);
222 			return ret;
223 		}
224 
225 		ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols,
226 						ARRAY_SIZE(maxim_2spk_kcontrols));
227 		if (ret) {
228 			dev_err(rtd->dev, "fail to add max98373 kcontrols, ret %d\n",
229 				ret);
230 			return ret;
231 		}
232 
233 		ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes,
234 					      ARRAY_SIZE(max_98373_dapm_routes));
235 		if (ret) {
236 			dev_err(rtd->dev, "fail to add max98373 routes, ret %d\n",
237 				ret);
238 			return ret;
239 		}
240 		break;
241 	default:
242 		dev_err(rtd->dev, "max98373: invalid num_codecs %d\n", num_codecs);
243 		return -EINVAL;
244 	}
245 
246 	return ret;
247 }
248 
249 void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link)
250 {
251 	link->codecs = max_98373_components;
252 	link->num_codecs = ARRAY_SIZE(max_98373_components);
253 	link->init = max_98373_spk_codec_init;
254 	link->ops = &max_98373_ops;
255 }
256 EXPORT_SYMBOL_NS(max_98373_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
257 
258 void max_98373_set_codec_conf(struct snd_soc_card *card)
259 {
260 	card->codec_conf = max_98373_codec_conf;
261 	card->num_configs = ARRAY_SIZE(max_98373_codec_conf);
262 }
263 EXPORT_SYMBOL_NS(max_98373_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON);
264 
265 /*
266  * Maxim MAX98390
267  */
268 static const struct snd_soc_dapm_route max_98390_dapm_routes[] = {
269 	/* speaker */
270 	{ "Left Spk", NULL, "Left BE_OUT" },
271 	{ "Right Spk", NULL, "Right BE_OUT" },
272 };
273 
274 static const struct snd_kcontrol_new max_98390_tt_kcontrols[] = {
275 	SOC_DAPM_PIN_SWITCH("TL Spk"),
276 	SOC_DAPM_PIN_SWITCH("TR Spk"),
277 };
278 
279 static const struct snd_soc_dapm_widget max_98390_tt_dapm_widgets[] = {
280 	SND_SOC_DAPM_SPK("TL Spk", NULL),
281 	SND_SOC_DAPM_SPK("TR Spk", NULL),
282 };
283 
284 static const struct snd_soc_dapm_route max_98390_tt_dapm_routes[] = {
285 	/* Tweeter speaker */
286 	{ "TL Spk", NULL, "Tweeter Left BE_OUT" },
287 	{ "TR Spk", NULL, "Tweeter Right BE_OUT" },
288 };
289 
290 static struct snd_soc_codec_conf max_98390_cml_codec_conf[] = {
291 	{
292 		.dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME),
293 		.name_prefix = "Left",
294 	},
295 	{
296 		.dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME),
297 		.name_prefix = "Right",
298 	},
299 };
300 
301 static struct snd_soc_codec_conf max_98390_codec_conf[] = {
302 	{
303 		.dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME),
304 		.name_prefix = "Right",
305 	},
306 	{
307 		.dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME),
308 		.name_prefix = "Left",
309 	},
310 	{
311 		.dlc = COMP_CODEC_CONF(MAX_98390_DEV2_NAME),
312 		.name_prefix = "Tweeter Right",
313 	},
314 	{
315 		.dlc = COMP_CODEC_CONF(MAX_98390_DEV3_NAME),
316 		.name_prefix = "Tweeter Left",
317 	},
318 };
319 
320 static struct snd_soc_dai_link_component max_98390_components[] = {
321 	{
322 		.name = MAX_98390_DEV0_NAME,
323 		.dai_name = MAX_98390_CODEC_DAI,
324 	},
325 	{
326 		.name = MAX_98390_DEV1_NAME,
327 		.dai_name = MAX_98390_CODEC_DAI,
328 	},
329 	{
330 		.name = MAX_98390_DEV2_NAME,
331 		.dai_name = MAX_98390_CODEC_DAI,
332 	},
333 	{
334 		.name = MAX_98390_DEV3_NAME,
335 		.dai_name = MAX_98390_CODEC_DAI,
336 	},
337 };
338 
339 static const struct {
340 	unsigned int tx;
341 	unsigned int rx;
342 } max_98390_tdm_mask[] = {
343 	{.tx = 0x01, .rx = 0x3},
344 	{.tx = 0x02, .rx = 0x3},
345 	{.tx = 0x04, .rx = 0x3},
346 	{.tx = 0x08, .rx = 0x3},
347 };
348 
349 static int max_98390_hw_params(struct snd_pcm_substream *substream,
350 			       struct snd_pcm_hw_params *params)
351 {
352 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
353 	struct snd_soc_dai_link *dai_link = rtd->dai_link;
354 	struct snd_soc_dai *codec_dai;
355 	int i, ret;
356 
357 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
358 		if (i >= ARRAY_SIZE(max_98390_tdm_mask)) {
359 			dev_err(codec_dai->dev, "invalid codec index %d\n", i);
360 			return -ENODEV;
361 		}
362 
363 		switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
364 		case SND_SOC_DAIFMT_DSP_A:
365 		case SND_SOC_DAIFMT_DSP_B:
366 			/* 4-slot TDM */
367 			ret = snd_soc_dai_set_tdm_slot(codec_dai,
368 						       max_98390_tdm_mask[i].tx,
369 						       max_98390_tdm_mask[i].rx,
370 						       4,
371 						       params_width(params));
372 			if (ret < 0) {
373 				dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
374 					ret);
375 				return ret;
376 			}
377 			break;
378 		default:
379 			dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
380 			break;
381 		}
382 	}
383 	return 0;
384 }
385 
386 static int max_98390_init(struct snd_soc_pcm_runtime *rtd)
387 {
388 	struct snd_soc_card *card = rtd->card;
389 	unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID);
390 	int ret;
391 
392 	switch (num_codecs) {
393 	case 4:
394 		/* add widgets/controls/dapm for tweeter speakers */
395 		ret = snd_soc_dapm_new_controls(&card->dapm, max_98390_tt_dapm_widgets,
396 						ARRAY_SIZE(max_98390_tt_dapm_widgets));
397 		if (ret) {
398 			dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n",
399 				ret);
400 			/* Don't need to add routes if widget addition failed */
401 			return ret;
402 		}
403 
404 		ret = snd_soc_add_card_controls(card, max_98390_tt_kcontrols,
405 						ARRAY_SIZE(max_98390_tt_kcontrols));
406 		if (ret) {
407 			dev_err(rtd->dev, "unable to add tweeter controls, ret %d\n",
408 				ret);
409 			return ret;
410 		}
411 
412 		ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_tt_dapm_routes,
413 					      ARRAY_SIZE(max_98390_tt_dapm_routes));
414 		if (ret) {
415 			dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n",
416 				ret);
417 			return ret;
418 		}
419 
420 		fallthrough;
421 	case 2:
422 		/* add regular speakers dapm route */
423 		ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets,
424 						ARRAY_SIZE(maxim_2spk_widgets));
425 		if (ret) {
426 			dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n",
427 				ret);
428 			return ret;
429 		}
430 
431 		ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols,
432 						ARRAY_SIZE(maxim_2spk_kcontrols));
433 		if (ret) {
434 			dev_err(rtd->dev, "fail to add max98390 woofer kcontrols, ret %d\n",
435 				ret);
436 			return ret;
437 		}
438 
439 		ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes,
440 					      ARRAY_SIZE(max_98390_dapm_routes));
441 		if (ret) {
442 			dev_err(rtd->dev, "unable to add dapm routes, ret %d\n",
443 				ret);
444 			return ret;
445 		}
446 		break;
447 	default:
448 		dev_err(rtd->dev, "invalid codec number %d\n", num_codecs);
449 		return -EINVAL;
450 	}
451 
452 	return ret;
453 }
454 
455 static const struct snd_soc_ops max_98390_ops = {
456 	.hw_params = max_98390_hw_params,
457 };
458 
459 void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link)
460 {
461 	unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID);
462 
463 	link->codecs = max_98390_components;
464 
465 	switch (num_codecs) {
466 	case 2:
467 	case 4:
468 		link->num_codecs = num_codecs;
469 		break;
470 	default:
471 		dev_err(dev, "invalid codec number %d for %s\n", num_codecs,
472 			MAX_98390_ACPI_HID);
473 		break;
474 	}
475 
476 	link->init = max_98390_init;
477 	link->ops = &max_98390_ops;
478 }
479 EXPORT_SYMBOL_NS(max_98390_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
480 
481 void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card)
482 {
483 	unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID);
484 
485 	card->codec_conf = max_98390_codec_conf;
486 
487 	switch (num_codecs) {
488 	case 2:
489 		if (soc_intel_is_cml())
490 			card->codec_conf = max_98390_cml_codec_conf;
491 
492 		fallthrough;
493 	case 4:
494 		card->num_configs = num_codecs;
495 		break;
496 	default:
497 		dev_err(dev, "invalid codec number %d for %s\n", num_codecs,
498 			MAX_98390_ACPI_HID);
499 		break;
500 	}
501 }
502 EXPORT_SYMBOL_NS(max_98390_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON);
503 
504 /*
505  * Maxim MAX98357A/MAX98360A
506  */
507 static const struct snd_kcontrol_new max_98357a_kcontrols[] = {
508 	SOC_DAPM_PIN_SWITCH("Spk"),
509 };
510 
511 static const struct snd_soc_dapm_widget max_98357a_dapm_widgets[] = {
512 	SND_SOC_DAPM_SPK("Spk", NULL),
513 };
514 
515 static const struct snd_soc_dapm_route max_98357a_dapm_routes[] = {
516 	/* speaker */
517 	{"Spk", NULL, "Speaker"},
518 };
519 
520 static struct snd_soc_dai_link_component max_98357a_components[] = {
521 	{
522 		.name = MAX_98357A_DEV0_NAME,
523 		.dai_name = MAX_98357A_CODEC_DAI,
524 	}
525 };
526 
527 static struct snd_soc_dai_link_component max_98360a_components[] = {
528 	{
529 		.name = MAX_98360A_DEV0_NAME,
530 		.dai_name = MAX_98357A_CODEC_DAI,
531 	}
532 };
533 
534 static int max_98357a_init(struct snd_soc_pcm_runtime *rtd)
535 {
536 	struct snd_soc_card *card = rtd->card;
537 	int ret;
538 
539 	ret = snd_soc_dapm_new_controls(&card->dapm, max_98357a_dapm_widgets,
540 					ARRAY_SIZE(max_98357a_dapm_widgets));
541 	if (ret) {
542 		dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret);
543 		/* Don't need to add routes if widget addition failed */
544 		return ret;
545 	}
546 
547 	ret = snd_soc_add_card_controls(card, max_98357a_kcontrols,
548 					ARRAY_SIZE(max_98357a_kcontrols));
549 	if (ret) {
550 		dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
551 		return ret;
552 	}
553 
554 	ret = snd_soc_dapm_add_routes(&card->dapm, max_98357a_dapm_routes,
555 				      ARRAY_SIZE(max_98357a_dapm_routes));
556 
557 	if (ret)
558 		dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret);
559 
560 	return ret;
561 }
562 
563 void max_98357a_dai_link(struct snd_soc_dai_link *link)
564 {
565 	link->codecs = max_98357a_components;
566 	link->num_codecs = ARRAY_SIZE(max_98357a_components);
567 	link->init = max_98357a_init;
568 }
569 EXPORT_SYMBOL_NS(max_98357a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
570 
571 void max_98360a_dai_link(struct snd_soc_dai_link *link)
572 {
573 	link->codecs = max_98360a_components;
574 	link->num_codecs = ARRAY_SIZE(max_98360a_components);
575 	link->init = max_98357a_init;
576 }
577 EXPORT_SYMBOL_NS(max_98360a_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON);
578 
579 MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers");
580 MODULE_LICENSE("GPL");
581