]> Git Repo - J-linux.git/blob - sound/soc/intel/boards/sof_maxim_common.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / sound / soc / intel / boards / sof_maxim_common.c
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 static const struct {
82         unsigned int rx;
83 } max_98373_tdm_mask[] = {
84         {.rx = 0x3},
85         {.rx = 0x3},
86 };
87
88 /*
89  * The tx mask indicates which channel(s) contains output IV-sense data and
90  * others should set to Hi-Z. Here we get the channel number from codec's ACPI
91  * device property "maxim,vmon-slot-no" and "maxim,imon-slot-no" to generate the
92  * mask. Refer to the max98373_slot_config() function in max98373.c codec driver.
93  */
94 static unsigned int max_98373_get_tx_mask(struct device *dev)
95 {
96         int vmon_slot;
97         int imon_slot;
98
99         if (device_property_read_u32(dev, "maxim,vmon-slot-no", &vmon_slot))
100                 vmon_slot = 0;
101
102         if (device_property_read_u32(dev, "maxim,imon-slot-no", &imon_slot))
103                 imon_slot = 1;
104
105         dev_dbg(dev, "vmon_slot %d imon_slot %d\n", vmon_slot, imon_slot);
106
107         return (0x1 << vmon_slot) | (0x1 << imon_slot);
108 }
109
110 static int max_98373_hw_params(struct snd_pcm_substream *substream,
111                                struct snd_pcm_hw_params *params)
112 {
113         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
114         struct snd_soc_dai_link *dai_link = rtd->dai_link;
115         struct snd_soc_dai *codec_dai;
116         int i;
117         int tdm_slots;
118         unsigned int tx_mask;
119         unsigned int tx_mask_used = 0x0;
120         int ret = 0;
121
122         for_each_rtd_codec_dais(rtd, i, codec_dai) {
123                 if (i >= ARRAY_SIZE(max_98373_tdm_mask)) {
124                         dev_err(codec_dai->dev, "only 2 amps are supported\n");
125                         return -EINVAL;
126                 }
127
128                 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
129                 case SND_SOC_DAIFMT_DSP_A:
130                 case SND_SOC_DAIFMT_DSP_B:
131                         /* get the tplg configured tdm slot number */
132                         tdm_slots = sof_dai_get_tdm_slots(rtd);
133                         if (tdm_slots <= 0) {
134                                 dev_err(rtd->dev, "invalid tdm slots %d\n",
135                                         tdm_slots);
136                                 return -EINVAL;
137                         }
138
139                         /* get the tx mask from ACPI device properties */
140                         tx_mask = max_98373_get_tx_mask(codec_dai->dev);
141                         if (!tx_mask)
142                                 return -EINVAL;
143
144                         if (tx_mask & tx_mask_used) {
145                                 dev_err(codec_dai->dev, "invalid tx mask 0x%x, used 0x%x\n",
146                                         tx_mask, tx_mask_used);
147                                 return -EINVAL;
148                         }
149
150                         tx_mask_used |= tx_mask;
151
152                         /*
153                          * check if tdm slot number is too small for channel
154                          * allocation
155                          */
156                         if (fls(tx_mask) > tdm_slots) {
157                                 dev_err(codec_dai->dev, "slot mismatch, tx %d slots %d\n",
158                                         fls(tx_mask), tdm_slots);
159                                 return -EINVAL;
160                         }
161
162                         if (fls(max_98373_tdm_mask[i].rx) > tdm_slots) {
163                                 dev_err(codec_dai->dev, "slot mismatch, rx %d slots %d\n",
164                                         fls(max_98373_tdm_mask[i].rx), tdm_slots);
165                                 return -EINVAL;
166                         }
167
168                         dev_dbg(codec_dai->dev, "set tdm slot: tx 0x%x rx 0x%x slots %d width %d\n",
169                                 tx_mask, max_98373_tdm_mask[i].rx,
170                                 tdm_slots, params_width(params));
171
172                         ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask,
173                                                        max_98373_tdm_mask[i].rx,
174                                                        tdm_slots,
175                                                        params_width(params));
176                         if (ret < 0) {
177                                 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
178                                         ret);
179                                 return ret;
180                         }
181                         break;
182                 default:
183                         dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
184                         break;
185                 }
186         }
187         return 0;
188 }
189
190 static int max_98373_trigger(struct snd_pcm_substream *substream, int cmd)
191 {
192         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
193         struct snd_soc_dai *codec_dai;
194         struct snd_soc_dai *cpu_dai;
195         int j;
196         int ret = 0;
197
198         /* set spk pin by playback only */
199         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
200                 return 0;
201
202         cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
203         for_each_rtd_codec_dais(rtd, j, codec_dai) {
204                 struct snd_soc_dapm_context *dapm =
205                                 snd_soc_component_get_dapm(cpu_dai->component);
206                 char pin_name[MAX_98373_PIN_NAME];
207
208                 snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
209                          codec_dai->component->name_prefix);
210
211                 switch (cmd) {
212                 case SNDRV_PCM_TRIGGER_START:
213                 case SNDRV_PCM_TRIGGER_RESUME:
214                 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
215                         ret = snd_soc_dapm_enable_pin(dapm, pin_name);
216                         if (!ret)
217                                 snd_soc_dapm_sync(dapm);
218                         break;
219                 case SNDRV_PCM_TRIGGER_STOP:
220                 case SNDRV_PCM_TRIGGER_SUSPEND:
221                 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
222                         ret = snd_soc_dapm_disable_pin(dapm, pin_name);
223                         if (!ret)
224                                 snd_soc_dapm_sync(dapm);
225                         break;
226                 default:
227                         break;
228                 }
229         }
230
231         return ret;
232 }
233
234 static const struct snd_soc_ops max_98373_ops = {
235         .hw_params = max_98373_hw_params,
236         .trigger = max_98373_trigger,
237 };
238
239 static int max_98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
240 {
241         struct snd_soc_card *card = rtd->card;
242         unsigned int num_codecs = get_num_codecs(MAX_98373_ACPI_HID);
243         int ret;
244
245         switch (num_codecs) {
246         case 2:
247                 ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets,
248                                                 ARRAY_SIZE(maxim_2spk_widgets));
249                 if (ret) {
250                         dev_err(rtd->dev, "fail to add max98373 widgets, ret %d\n",
251                                 ret);
252                         return ret;
253                 }
254
255                 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols,
256                                                 ARRAY_SIZE(maxim_2spk_kcontrols));
257                 if (ret) {
258                         dev_err(rtd->dev, "fail to add max98373 kcontrols, ret %d\n",
259                                 ret);
260                         return ret;
261                 }
262
263                 ret = snd_soc_dapm_add_routes(&card->dapm, max_98373_dapm_routes,
264                                               ARRAY_SIZE(max_98373_dapm_routes));
265                 if (ret) {
266                         dev_err(rtd->dev, "fail to add max98373 routes, ret %d\n",
267                                 ret);
268                         return ret;
269                 }
270                 break;
271         default:
272                 dev_err(rtd->dev, "max98373: invalid num_codecs %d\n", num_codecs);
273                 return -EINVAL;
274         }
275
276         return ret;
277 }
278
279 void max_98373_dai_link(struct device *dev, struct snd_soc_dai_link *link)
280 {
281         link->codecs = max_98373_components;
282         link->num_codecs = ARRAY_SIZE(max_98373_components);
283         link->init = max_98373_spk_codec_init;
284         link->ops = &max_98373_ops;
285 }
286 EXPORT_SYMBOL_NS(max_98373_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON");
287
288 void max_98373_set_codec_conf(struct snd_soc_card *card)
289 {
290         card->codec_conf = max_98373_codec_conf;
291         card->num_configs = ARRAY_SIZE(max_98373_codec_conf);
292 }
293 EXPORT_SYMBOL_NS(max_98373_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON");
294
295 /*
296  * Maxim MAX98390
297  */
298 static const struct snd_soc_dapm_route max_98390_dapm_routes[] = {
299         /* speaker */
300         { "Left Spk", NULL, "Left BE_OUT" },
301         { "Right Spk", NULL, "Right BE_OUT" },
302 };
303
304 static const struct snd_kcontrol_new max_98390_tt_kcontrols[] = {
305         SOC_DAPM_PIN_SWITCH("TL Spk"),
306         SOC_DAPM_PIN_SWITCH("TR Spk"),
307 };
308
309 static const struct snd_soc_dapm_widget max_98390_tt_dapm_widgets[] = {
310         SND_SOC_DAPM_SPK("TL Spk", NULL),
311         SND_SOC_DAPM_SPK("TR Spk", NULL),
312 };
313
314 static const struct snd_soc_dapm_route max_98390_tt_dapm_routes[] = {
315         /* Tweeter speaker */
316         { "TL Spk", NULL, "Tweeter Left BE_OUT" },
317         { "TR Spk", NULL, "Tweeter Right BE_OUT" },
318 };
319
320 static struct snd_soc_codec_conf max_98390_cml_codec_conf[] = {
321         {
322                 .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME),
323                 .name_prefix = "Left",
324         },
325         {
326                 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME),
327                 .name_prefix = "Right",
328         },
329 };
330
331 static struct snd_soc_codec_conf max_98390_codec_conf[] = {
332         {
333                 .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME),
334                 .name_prefix = "Right",
335         },
336         {
337                 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME),
338                 .name_prefix = "Left",
339         },
340         {
341                 .dlc = COMP_CODEC_CONF(MAX_98390_DEV2_NAME),
342                 .name_prefix = "Tweeter Right",
343         },
344         {
345                 .dlc = COMP_CODEC_CONF(MAX_98390_DEV3_NAME),
346                 .name_prefix = "Tweeter Left",
347         },
348 };
349
350 static struct snd_soc_dai_link_component max_98390_components[] = {
351         {
352                 .name = MAX_98390_DEV0_NAME,
353                 .dai_name = MAX_98390_CODEC_DAI,
354         },
355         {
356                 .name = MAX_98390_DEV1_NAME,
357                 .dai_name = MAX_98390_CODEC_DAI,
358         },
359         {
360                 .name = MAX_98390_DEV2_NAME,
361                 .dai_name = MAX_98390_CODEC_DAI,
362         },
363         {
364                 .name = MAX_98390_DEV3_NAME,
365                 .dai_name = MAX_98390_CODEC_DAI,
366         },
367 };
368
369 static const struct {
370         unsigned int tx;
371         unsigned int rx;
372 } max_98390_tdm_mask[] = {
373         {.tx = 0x01, .rx = 0x3},
374         {.tx = 0x02, .rx = 0x3},
375         {.tx = 0x04, .rx = 0x3},
376         {.tx = 0x08, .rx = 0x3},
377 };
378
379 static int max_98390_hw_params(struct snd_pcm_substream *substream,
380                                struct snd_pcm_hw_params *params)
381 {
382         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
383         struct snd_soc_dai_link *dai_link = rtd->dai_link;
384         struct snd_soc_dai *codec_dai;
385         int i, ret;
386
387         for_each_rtd_codec_dais(rtd, i, codec_dai) {
388                 if (i >= ARRAY_SIZE(max_98390_tdm_mask)) {
389                         dev_err(codec_dai->dev, "invalid codec index %d\n", i);
390                         return -ENODEV;
391                 }
392
393                 switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
394                 case SND_SOC_DAIFMT_DSP_A:
395                 case SND_SOC_DAIFMT_DSP_B:
396                         /* 4-slot TDM */
397                         ret = snd_soc_dai_set_tdm_slot(codec_dai,
398                                                        max_98390_tdm_mask[i].tx,
399                                                        max_98390_tdm_mask[i].rx,
400                                                        4,
401                                                        params_width(params));
402                         if (ret < 0) {
403                                 dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
404                                         ret);
405                                 return ret;
406                         }
407                         break;
408                 default:
409                         dev_dbg(codec_dai->dev, "codec is in I2S mode\n");
410                         break;
411                 }
412         }
413         return 0;
414 }
415
416 static int max_98390_init(struct snd_soc_pcm_runtime *rtd)
417 {
418         struct snd_soc_card *card = rtd->card;
419         unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID);
420         int ret;
421
422         switch (num_codecs) {
423         case 4:
424                 /* add widgets/controls/dapm for tweeter speakers */
425                 ret = snd_soc_dapm_new_controls(&card->dapm, max_98390_tt_dapm_widgets,
426                                                 ARRAY_SIZE(max_98390_tt_dapm_widgets));
427                 if (ret) {
428                         dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n",
429                                 ret);
430                         /* Don't need to add routes if widget addition failed */
431                         return ret;
432                 }
433
434                 ret = snd_soc_add_card_controls(card, max_98390_tt_kcontrols,
435                                                 ARRAY_SIZE(max_98390_tt_kcontrols));
436                 if (ret) {
437                         dev_err(rtd->dev, "unable to add tweeter controls, ret %d\n",
438                                 ret);
439                         return ret;
440                 }
441
442                 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_tt_dapm_routes,
443                                               ARRAY_SIZE(max_98390_tt_dapm_routes));
444                 if (ret) {
445                         dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n",
446                                 ret);
447                         return ret;
448                 }
449
450                 fallthrough;
451         case 2:
452                 /* add regular speakers dapm route */
453                 ret = snd_soc_dapm_new_controls(&card->dapm, maxim_2spk_widgets,
454                                                 ARRAY_SIZE(maxim_2spk_widgets));
455                 if (ret) {
456                         dev_err(rtd->dev, "fail to add max98390 woofer widgets, ret %d\n",
457                                 ret);
458                         return ret;
459                 }
460
461                 ret = snd_soc_add_card_controls(card, maxim_2spk_kcontrols,
462                                                 ARRAY_SIZE(maxim_2spk_kcontrols));
463                 if (ret) {
464                         dev_err(rtd->dev, "fail to add max98390 woofer kcontrols, ret %d\n",
465                                 ret);
466                         return ret;
467                 }
468
469                 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes,
470                                               ARRAY_SIZE(max_98390_dapm_routes));
471                 if (ret) {
472                         dev_err(rtd->dev, "unable to add dapm routes, ret %d\n",
473                                 ret);
474                         return ret;
475                 }
476                 break;
477         default:
478                 dev_err(rtd->dev, "invalid codec number %d\n", num_codecs);
479                 return -EINVAL;
480         }
481
482         return ret;
483 }
484
485 static const struct snd_soc_ops max_98390_ops = {
486         .hw_params = max_98390_hw_params,
487 };
488
489 void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link)
490 {
491         unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID);
492
493         link->codecs = max_98390_components;
494
495         switch (num_codecs) {
496         case 2:
497         case 4:
498                 link->num_codecs = num_codecs;
499                 break;
500         default:
501                 dev_err(dev, "invalid codec number %d for %s\n", num_codecs,
502                         MAX_98390_ACPI_HID);
503                 break;
504         }
505
506         link->init = max_98390_init;
507         link->ops = &max_98390_ops;
508 }
509 EXPORT_SYMBOL_NS(max_98390_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON");
510
511 void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card)
512 {
513         unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID);
514
515         card->codec_conf = max_98390_codec_conf;
516
517         switch (num_codecs) {
518         case 2:
519                 if (soc_intel_is_cml())
520                         card->codec_conf = max_98390_cml_codec_conf;
521
522                 fallthrough;
523         case 4:
524                 card->num_configs = num_codecs;
525                 break;
526         default:
527                 dev_err(dev, "invalid codec number %d for %s\n", num_codecs,
528                         MAX_98390_ACPI_HID);
529                 break;
530         }
531 }
532 EXPORT_SYMBOL_NS(max_98390_set_codec_conf, "SND_SOC_INTEL_SOF_MAXIM_COMMON");
533
534 /*
535  * Maxim MAX98357A/MAX98360A
536  */
537 static const struct snd_kcontrol_new max_98357a_kcontrols[] = {
538         SOC_DAPM_PIN_SWITCH("Spk"),
539 };
540
541 static const struct snd_soc_dapm_widget max_98357a_dapm_widgets[] = {
542         SND_SOC_DAPM_SPK("Spk", NULL),
543 };
544
545 static const struct snd_soc_dapm_route max_98357a_dapm_routes[] = {
546         /* speaker */
547         {"Spk", NULL, "Speaker"},
548 };
549
550 static struct snd_soc_dai_link_component max_98357a_components[] = {
551         {
552                 .name = MAX_98357A_DEV0_NAME,
553                 .dai_name = MAX_98357A_CODEC_DAI,
554         }
555 };
556
557 static struct snd_soc_dai_link_component max_98360a_components[] = {
558         {
559                 .name = MAX_98360A_DEV0_NAME,
560                 .dai_name = MAX_98357A_CODEC_DAI,
561         }
562 };
563
564 static int max_98357a_init(struct snd_soc_pcm_runtime *rtd)
565 {
566         struct snd_soc_card *card = rtd->card;
567         int ret;
568
569         ret = snd_soc_dapm_new_controls(&card->dapm, max_98357a_dapm_widgets,
570                                         ARRAY_SIZE(max_98357a_dapm_widgets));
571         if (ret) {
572                 dev_err(rtd->dev, "unable to add dapm controls, ret %d\n", ret);
573                 /* Don't need to add routes if widget addition failed */
574                 return ret;
575         }
576
577         ret = snd_soc_add_card_controls(card, max_98357a_kcontrols,
578                                         ARRAY_SIZE(max_98357a_kcontrols));
579         if (ret) {
580                 dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
581                 return ret;
582         }
583
584         ret = snd_soc_dapm_add_routes(&card->dapm, max_98357a_dapm_routes,
585                                       ARRAY_SIZE(max_98357a_dapm_routes));
586
587         if (ret)
588                 dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", ret);
589
590         return ret;
591 }
592
593 void max_98357a_dai_link(struct snd_soc_dai_link *link)
594 {
595         link->codecs = max_98357a_components;
596         link->num_codecs = ARRAY_SIZE(max_98357a_components);
597         link->init = max_98357a_init;
598 }
599 EXPORT_SYMBOL_NS(max_98357a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON");
600
601 void max_98360a_dai_link(struct snd_soc_dai_link *link)
602 {
603         link->codecs = max_98360a_components;
604         link->num_codecs = ARRAY_SIZE(max_98360a_components);
605         link->init = max_98357a_init;
606 }
607 EXPORT_SYMBOL_NS(max_98360a_dai_link, "SND_SOC_INTEL_SOF_MAXIM_COMMON");
608
609 MODULE_DESCRIPTION("ASoC Intel SOF Maxim helpers");
610 MODULE_LICENSE("GPL");
This page took 0.065408 seconds and 4 git commands to generate.