1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/module.h>
21#include <linux/moduleparam.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/pm.h>
25#include <linux/bitops.h>
26#include <linux/debugfs.h>
27#include <linux/platform_device.h>
28#include <linux/pinctrl/consumer.h>
29#include <linux/ctype.h>
30#include <linux/slab.h>
31#include <linux/of.h>
32#include <linux/of_graph.h>
33#include <linux/dmi.h>
34#include <linux/acpi.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39#include <sound/soc-dpcm.h>
40#include <sound/soc-topology.h>
41#include <sound/soc-link.h>
42#include <sound/initval.h>
43
44#define CREATE_TRACE_POINTS
45#include <trace/events/asoc.h>
46
47static DEFINE_MUTEX(client_mutex);
48static LIST_HEAD(component_list);
49static LIST_HEAD(unbind_card_list);
50
51#define for_each_component(component) \
52 list_for_each_entry(component, &component_list, list)
53
54
55
56
57
58struct snd_soc_dai_link_component null_dailink_component[0];
59EXPORT_SYMBOL_GPL(null_dailink_component);
60
61
62
63
64
65
66static int pmdown_time = 5000;
67module_param(pmdown_time, int, 0);
68MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
69
70static ssize_t pmdown_time_show(struct device *dev,
71 struct device_attribute *attr, char *buf)
72{
73 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
74
75 return sprintf(buf, "%ld\n", rtd->pmdown_time);
76}
77
78static ssize_t pmdown_time_store(struct device *dev,
79 struct device_attribute *attr,
80 const char *buf, size_t count)
81{
82 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
83 int ret;
84
85 ret = kstrtol(buf, 10, &rtd->pmdown_time);
86 if (ret)
87 return ret;
88
89 return count;
90}
91
92static DEVICE_ATTR_RW(pmdown_time);
93
94static struct attribute *soc_dev_attrs[] = {
95 &dev_attr_pmdown_time.attr,
96 NULL
97};
98
99static umode_t soc_dev_attr_is_visible(struct kobject *kobj,
100 struct attribute *attr, int idx)
101{
102 struct device *dev = kobj_to_dev(kobj);
103 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
104
105 if (!rtd)
106 return 0;
107
108 if (attr == &dev_attr_pmdown_time.attr)
109 return attr->mode;
110 return rtd->num_codecs ? attr->mode : 0;
111}
112
113static const struct attribute_group soc_dapm_dev_group = {
114 .attrs = soc_dapm_dev_attrs,
115 .is_visible = soc_dev_attr_is_visible,
116};
117
118static const struct attribute_group soc_dev_group = {
119 .attrs = soc_dev_attrs,
120 .is_visible = soc_dev_attr_is_visible,
121};
122
123static const struct attribute_group *soc_dev_attr_groups[] = {
124 &soc_dapm_dev_group,
125 &soc_dev_group,
126 NULL
127};
128
129#ifdef CONFIG_DEBUG_FS
130struct dentry *snd_soc_debugfs_root;
131EXPORT_SYMBOL_GPL(snd_soc_debugfs_root);
132
133static void soc_init_component_debugfs(struct snd_soc_component *component)
134{
135 if (!component->card->debugfs_card_root)
136 return;
137
138 if (component->debugfs_prefix) {
139 char *name;
140
141 name = kasprintf(GFP_KERNEL, "%s:%s",
142 component->debugfs_prefix, component->name);
143 if (name) {
144 component->debugfs_root = debugfs_create_dir(name,
145 component->card->debugfs_card_root);
146 kfree(name);
147 }
148 } else {
149 component->debugfs_root = debugfs_create_dir(component->name,
150 component->card->debugfs_card_root);
151 }
152
153 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
154 component->debugfs_root);
155}
156
157static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
158{
159 if (!component->debugfs_root)
160 return;
161 debugfs_remove_recursive(component->debugfs_root);
162 component->debugfs_root = NULL;
163}
164
165static int dai_list_show(struct seq_file *m, void *v)
166{
167 struct snd_soc_component *component;
168 struct snd_soc_dai *dai;
169
170 mutex_lock(&client_mutex);
171
172 for_each_component(component)
173 for_each_component_dais(component, dai)
174 seq_printf(m, "%s\n", dai->name);
175
176 mutex_unlock(&client_mutex);
177
178 return 0;
179}
180DEFINE_SHOW_ATTRIBUTE(dai_list);
181
182static int component_list_show(struct seq_file *m, void *v)
183{
184 struct snd_soc_component *component;
185
186 mutex_lock(&client_mutex);
187
188 for_each_component(component)
189 seq_printf(m, "%s\n", component->name);
190
191 mutex_unlock(&client_mutex);
192
193 return 0;
194}
195DEFINE_SHOW_ATTRIBUTE(component_list);
196
197static void soc_init_card_debugfs(struct snd_soc_card *card)
198{
199 card->debugfs_card_root = debugfs_create_dir(card->name,
200 snd_soc_debugfs_root);
201
202 debugfs_create_u32("dapm_pop_time", 0644, card->debugfs_card_root,
203 &card->pop_time);
204
205 snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
206}
207
208static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
209{
210 debugfs_remove_recursive(card->debugfs_card_root);
211 card->debugfs_card_root = NULL;
212}
213
214static void snd_soc_debugfs_init(void)
215{
216 snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL);
217
218 debugfs_create_file("dais", 0444, snd_soc_debugfs_root, NULL,
219 &dai_list_fops);
220
221 debugfs_create_file("components", 0444, snd_soc_debugfs_root, NULL,
222 &component_list_fops);
223}
224
225static void snd_soc_debugfs_exit(void)
226{
227 debugfs_remove_recursive(snd_soc_debugfs_root);
228}
229
230#else
231
232static inline void soc_init_component_debugfs(struct snd_soc_component *component) { }
233static inline void soc_cleanup_component_debugfs(struct snd_soc_component *component) { }
234static inline void soc_init_card_debugfs(struct snd_soc_card *card) { }
235static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) { }
236static inline void snd_soc_debugfs_init(void) { }
237static inline void snd_soc_debugfs_exit(void) { }
238
239#endif
240
241static int snd_soc_rtd_add_component(struct snd_soc_pcm_runtime *rtd,
242 struct snd_soc_component *component)
243{
244 struct snd_soc_component *comp;
245 int i;
246
247 for_each_rtd_components(rtd, i, comp) {
248
249 if (comp == component)
250 return 0;
251 }
252
253
254 rtd->components[rtd->num_components] = component;
255 rtd->num_components++;
256
257 return 0;
258}
259
260struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
261 const char *driver_name)
262{
263 struct snd_soc_component *component;
264 int i;
265
266 if (!driver_name)
267 return NULL;
268
269
270
271
272
273
274
275
276
277 for_each_rtd_components(rtd, i, component) {
278 const char *component_name = component->driver->name;
279
280 if (!component_name)
281 continue;
282
283 if ((component_name == driver_name) ||
284 strcmp(component_name, driver_name) == 0)
285 return component;
286 }
287
288 return NULL;
289}
290EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup);
291
292struct snd_soc_component
293*snd_soc_lookup_component_nolocked(struct device *dev, const char *driver_name)
294{
295 struct snd_soc_component *component;
296 struct snd_soc_component *found_component;
297
298 found_component = NULL;
299 for_each_component(component) {
300 if ((dev == component->dev) &&
301 (!driver_name ||
302 (driver_name == component->driver->name) ||
303 (strcmp(component->driver->name, driver_name) == 0))) {
304 found_component = component;
305 break;
306 }
307 }
308
309 return found_component;
310}
311EXPORT_SYMBOL_GPL(snd_soc_lookup_component_nolocked);
312
313struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
314 const char *driver_name)
315{
316 struct snd_soc_component *component;
317
318 mutex_lock(&client_mutex);
319 component = snd_soc_lookup_component_nolocked(dev, driver_name);
320 mutex_unlock(&client_mutex);
321
322 return component;
323}
324EXPORT_SYMBOL_GPL(snd_soc_lookup_component);
325
326struct snd_soc_pcm_runtime
327*snd_soc_get_pcm_runtime(struct snd_soc_card *card,
328 struct snd_soc_dai_link *dai_link)
329{
330 struct snd_soc_pcm_runtime *rtd;
331
332 for_each_card_rtds(card, rtd) {
333 if (rtd->dai_link == dai_link)
334 return rtd;
335 }
336 dev_dbg(card->dev, "ASoC: failed to find rtd %s\n", dai_link->name);
337 return NULL;
338}
339EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);
340
341
342
343
344
345
346void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd)
347{
348 struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
349 int playback = SNDRV_PCM_STREAM_PLAYBACK;
350
351 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
352
353 dev_dbg(rtd->dev,
354 "ASoC: pop wq checking: %s status: %s waiting: %s\n",
355 codec_dai->driver->playback.stream_name,
356 snd_soc_dai_stream_active(codec_dai, playback) ?
357 "active" : "inactive",
358 rtd->pop_wait ? "yes" : "no");
359
360
361 if (rtd->pop_wait == 1) {
362 rtd->pop_wait = 0;
363 snd_soc_dapm_stream_event(rtd, playback,
364 SND_SOC_DAPM_STREAM_STOP);
365 }
366
367 mutex_unlock(&rtd->card->pcm_mutex);
368}
369EXPORT_SYMBOL_GPL(snd_soc_close_delayed_work);
370
371static void soc_release_rtd_dev(struct device *dev)
372{
373
374 kfree(dev);
375}
376
377static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd)
378{
379 if (!rtd)
380 return;
381
382 list_del(&rtd->list);
383
384 if (delayed_work_pending(&rtd->delayed_work))
385 flush_delayed_work(&rtd->delayed_work);
386 snd_soc_pcm_component_free(rtd);
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 device_unregister(rtd->dev);
407}
408
409static void close_delayed_work(struct work_struct *work) {
410 struct snd_soc_pcm_runtime *rtd =
411 container_of(work, struct snd_soc_pcm_runtime,
412 delayed_work.work);
413
414 if (rtd->close_delayed_work_func)
415 rtd->close_delayed_work_func(rtd);
416}
417
418static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
419 struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
420{
421 struct snd_soc_pcm_runtime *rtd;
422 struct snd_soc_component *component;
423 struct device *dev;
424 int ret;
425 int stream;
426
427
428
429
430 dev = kzalloc(sizeof(struct device), GFP_KERNEL);
431 if (!dev)
432 return NULL;
433
434 dev->parent = card->dev;
435 dev->release = soc_release_rtd_dev;
436
437 dev_set_name(dev, "%s", dai_link->name);
438
439 ret = device_register(dev);
440 if (ret < 0) {
441 put_device(dev);
442 return NULL;
443 }
444
445
446
447
448 rtd = devm_kzalloc(dev,
449 sizeof(*rtd) +
450 sizeof(*component) * (dai_link->num_cpus +
451 dai_link->num_codecs +
452 dai_link->num_platforms),
453 GFP_KERNEL);
454 if (!rtd) {
455 device_unregister(dev);
456 return NULL;
457 }
458
459 rtd->dev = dev;
460 INIT_LIST_HEAD(&rtd->list);
461 for_each_pcm_streams(stream) {
462 INIT_LIST_HEAD(&rtd->dpcm[stream].be_clients);
463 INIT_LIST_HEAD(&rtd->dpcm[stream].fe_clients);
464 }
465 dev_set_drvdata(dev, rtd);
466 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
467
468
469
470
471 rtd->dais = devm_kcalloc(dev, dai_link->num_cpus + dai_link->num_codecs,
472 sizeof(struct snd_soc_dai *),
473 GFP_KERNEL);
474 if (!rtd->dais)
475 goto free_rtd;
476
477
478
479
480
481
482
483
484
485 rtd->num_cpus = dai_link->num_cpus;
486 rtd->num_codecs = dai_link->num_codecs;
487 rtd->card = card;
488 rtd->dai_link = dai_link;
489 rtd->num = card->num_rtd++;
490
491
492 list_add_tail(&rtd->list, &card->rtd_list);
493
494 ret = device_add_groups(dev, soc_dev_attr_groups);
495 if (ret < 0)
496 goto free_rtd;
497
498 return rtd;
499
500free_rtd:
501 soc_free_pcm_runtime(rtd);
502 return NULL;
503}
504
505static void snd_soc_flush_all_delayed_work(struct snd_soc_card *card)
506{
507 struct snd_soc_pcm_runtime *rtd;
508
509 for_each_card_rtds(card, rtd)
510 flush_delayed_work(&rtd->delayed_work);
511}
512
513#ifdef CONFIG_PM_SLEEP
514static void soc_playback_digital_mute(struct snd_soc_card *card, int mute)
515{
516 struct snd_soc_pcm_runtime *rtd;
517 struct snd_soc_dai *dai;
518 int playback = SNDRV_PCM_STREAM_PLAYBACK;
519 int i;
520
521 for_each_card_rtds(card, rtd) {
522
523 if (rtd->dai_link->ignore_suspend)
524 continue;
525
526 for_each_rtd_dais(rtd, i, dai) {
527 if (snd_soc_dai_stream_active(dai, playback))
528 snd_soc_dai_digital_mute(dai, mute, playback);
529 }
530 }
531}
532
533static void soc_dapm_suspend_resume(struct snd_soc_card *card, int event)
534{
535 struct snd_soc_pcm_runtime *rtd;
536 int stream;
537
538 for_each_card_rtds(card, rtd) {
539
540 if (rtd->dai_link->ignore_suspend)
541 continue;
542
543 for_each_pcm_streams(stream)
544 snd_soc_dapm_stream_event(rtd, stream, event);
545 }
546}
547
548
549int snd_soc_suspend(struct device *dev)
550{
551 struct snd_soc_card *card = dev_get_drvdata(dev);
552 struct snd_soc_component *component;
553 struct snd_soc_pcm_runtime *rtd;
554 int i;
555
556
557 if (!card->instantiated)
558 return 0;
559
560
561
562
563
564 snd_power_wait(card->snd_card);
565
566
567 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
568
569
570 soc_playback_digital_mute(card, 1);
571
572
573 for_each_card_rtds(card, rtd) {
574 if (rtd->dai_link->ignore_suspend)
575 continue;
576
577 snd_pcm_suspend_all(rtd->pcm);
578 }
579
580 snd_soc_card_suspend_pre(card);
581
582
583 snd_soc_flush_all_delayed_work(card);
584
585 soc_dapm_suspend_resume(card, SND_SOC_DAPM_STREAM_SUSPEND);
586
587
588 dapm_mark_endpoints_dirty(card);
589 snd_soc_dapm_sync(&card->dapm);
590
591
592 for_each_card_rtds(card, rtd) {
593
594 if (rtd->dai_link->ignore_suspend)
595 continue;
596
597 for_each_rtd_components(rtd, i, component) {
598 struct snd_soc_dapm_context *dapm =
599 snd_soc_component_get_dapm(component);
600
601
602
603
604 if (snd_soc_component_is_suspended(component))
605 continue;
606
607
608
609
610
611 switch (snd_soc_dapm_get_bias_level(dapm)) {
612 case SND_SOC_BIAS_STANDBY:
613
614
615
616
617
618
619 if (dapm->idle_bias_off) {
620 dev_dbg(component->dev,
621 "ASoC: idle_bias_off CODEC on over suspend\n");
622 break;
623 }
624 fallthrough;
625
626 case SND_SOC_BIAS_OFF:
627 snd_soc_component_suspend(component);
628 if (component->regmap)
629 regcache_mark_dirty(component->regmap);
630
631 pinctrl_pm_select_sleep_state(component->dev);
632 break;
633 default:
634 dev_dbg(component->dev,
635 "ASoC: COMPONENT is on over suspend\n");
636 break;
637 }
638 }
639 }
640
641 snd_soc_card_suspend_post(card);
642
643 return 0;
644}
645EXPORT_SYMBOL_GPL(snd_soc_suspend);
646
647
648
649
650
651static void soc_resume_deferred(struct work_struct *work)
652{
653 struct snd_soc_card *card =
654 container_of(work, struct snd_soc_card,
655 deferred_resume_work);
656 struct snd_soc_component *component;
657
658
659
660
661
662
663 dev_dbg(card->dev, "ASoC: starting resume work\n");
664
665
666 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
667
668 snd_soc_card_resume_pre(card);
669
670 for_each_card_components(card, component) {
671 if (snd_soc_component_is_suspended(component))
672 snd_soc_component_resume(component);
673 }
674
675 soc_dapm_suspend_resume(card, SND_SOC_DAPM_STREAM_RESUME);
676
677
678 soc_playback_digital_mute(card, 0);
679
680 snd_soc_card_resume_post(card);
681
682 dev_dbg(card->dev, "ASoC: resume work completed\n");
683
684
685 dapm_mark_endpoints_dirty(card);
686 snd_soc_dapm_sync(&card->dapm);
687
688
689 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
690}
691
692
693int snd_soc_resume(struct device *dev)
694{
695 struct snd_soc_card *card = dev_get_drvdata(dev);
696 struct snd_soc_component *component;
697
698
699 if (!card->instantiated)
700 return 0;
701
702
703 for_each_card_components(card, component)
704 if (snd_soc_component_active(component))
705 pinctrl_pm_select_default_state(component->dev);
706
707 dev_dbg(dev, "ASoC: Scheduling resume work\n");
708 if (!schedule_work(&card->deferred_resume_work))
709 dev_err(dev, "ASoC: resume work item may be lost\n");
710
711 return 0;
712}
713EXPORT_SYMBOL_GPL(snd_soc_resume);
714
715static void soc_resume_init(struct snd_soc_card *card)
716{
717
718 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
719}
720#else
721#define snd_soc_suspend NULL
722#define snd_soc_resume NULL
723static inline void soc_resume_init(struct snd_soc_card *card) { }
724#endif
725
726static struct device_node
727*soc_component_to_node(struct snd_soc_component *component)
728{
729 struct device_node *of_node;
730
731 of_node = component->dev->of_node;
732 if (!of_node && component->dev->parent)
733 of_node = component->dev->parent->of_node;
734
735 return of_node;
736}
737
738static int snd_soc_is_matching_component(
739 const struct snd_soc_dai_link_component *dlc,
740 struct snd_soc_component *component)
741{
742 struct device_node *component_of_node;
743
744 if (!dlc)
745 return 0;
746
747 component_of_node = soc_component_to_node(component);
748
749 if (dlc->of_node && component_of_node != dlc->of_node)
750 return 0;
751 if (dlc->name && strcmp(component->name, dlc->name))
752 return 0;
753
754 return 1;
755}
756
757static struct snd_soc_component *soc_find_component(
758 const struct snd_soc_dai_link_component *dlc)
759{
760 struct snd_soc_component *component;
761
762 lockdep_assert_held(&client_mutex);
763
764
765
766
767
768
769
770
771
772 for_each_component(component)
773 if (snd_soc_is_matching_component(dlc, component))
774 return component;
775
776 return NULL;
777}
778
779
780
781
782
783
784
785
786
787
788
789
790struct snd_soc_dai *snd_soc_find_dai(
791 const struct snd_soc_dai_link_component *dlc)
792{
793 struct snd_soc_component *component;
794 struct snd_soc_dai *dai;
795
796 lockdep_assert_held(&client_mutex);
797
798
799 for_each_component(component) {
800 if (!snd_soc_is_matching_component(dlc, component))
801 continue;
802 for_each_component_dais(component, dai) {
803 if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)
804 && (!dai->driver->name
805 || strcmp(dai->driver->name, dlc->dai_name)))
806 continue;
807
808 return dai;
809 }
810 }
811
812 return NULL;
813}
814EXPORT_SYMBOL_GPL(snd_soc_find_dai);
815
816struct snd_soc_dai *snd_soc_find_dai_with_mutex(
817 const struct snd_soc_dai_link_component *dlc)
818{
819 struct snd_soc_dai *dai;
820
821 mutex_lock(&client_mutex);
822 dai = snd_soc_find_dai(dlc);
823 mutex_unlock(&client_mutex);
824
825 return dai;
826}
827EXPORT_SYMBOL_GPL(snd_soc_find_dai_with_mutex);
828
829static int soc_dai_link_sanity_check(struct snd_soc_card *card,
830 struct snd_soc_dai_link *link)
831{
832 int i;
833 struct snd_soc_dai_link_component *cpu, *codec, *platform;
834
835 for_each_link_codecs(link, i, codec) {
836
837
838
839
840 if (!!codec->name == !!codec->of_node) {
841 dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
842 link->name);
843 return -EINVAL;
844 }
845
846
847 if (!codec->dai_name) {
848 dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
849 link->name);
850 return -EINVAL;
851 }
852
853
854
855
856
857 if (!soc_find_component(codec)) {
858 dev_dbg(card->dev,
859 "ASoC: codec component %s not found for link %s\n",
860 codec->name, link->name);
861 return -EPROBE_DEFER;
862 }
863 }
864
865 for_each_link_platforms(link, i, platform) {
866
867
868
869
870
871 if (!!platform->name == !!platform->of_node) {
872 dev_err(card->dev,
873 "ASoC: Neither/both platform name/of_node are set for %s\n",
874 link->name);
875 return -EINVAL;
876 }
877
878
879
880
881
882 if (!soc_find_component(platform)) {
883 dev_dbg(card->dev,
884 "ASoC: platform component %s not found for link %s\n",
885 platform->name, link->name);
886 return -EPROBE_DEFER;
887 }
888 }
889
890 for_each_link_cpus(link, i, cpu) {
891
892
893
894
895
896 if (cpu->name && cpu->of_node) {
897 dev_err(card->dev,
898 "ASoC: Neither/both cpu name/of_node are set for %s\n",
899 link->name);
900 return -EINVAL;
901 }
902
903
904
905
906
907 if ((cpu->of_node || cpu->name) &&
908 !soc_find_component(cpu)) {
909 dev_dbg(card->dev,
910 "ASoC: cpu component %s not found for link %s\n",
911 cpu->name, link->name);
912 return -EPROBE_DEFER;
913 }
914
915
916
917
918
919 if (!cpu->dai_name &&
920 !(cpu->name || cpu->of_node)) {
921 dev_err(card->dev,
922 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
923 link->name);
924 return -EINVAL;
925 }
926 }
927
928 return 0;
929}
930
931
932
933
934
935
936
937
938void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
939 struct snd_soc_pcm_runtime *rtd)
940{
941 lockdep_assert_held(&client_mutex);
942
943
944 snd_soc_link_exit(rtd);
945
946
947
948
949 snd_soc_card_remove_dai_link(card, rtd->dai_link);
950
951 soc_free_pcm_runtime(rtd);
952}
953EXPORT_SYMBOL_GPL(snd_soc_remove_pcm_runtime);
954
955
956
957
958
959
960
961
962
963
964
965
966int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
967 struct snd_soc_dai_link *dai_link)
968{
969 struct snd_soc_pcm_runtime *rtd;
970 struct snd_soc_dai_link_component *codec, *platform, *cpu;
971 struct snd_soc_component *component;
972 int i, ret;
973
974 lockdep_assert_held(&client_mutex);
975
976
977
978
979 ret = snd_soc_card_add_dai_link(card, dai_link);
980 if (ret < 0)
981 return ret;
982
983 if (dai_link->ignore)
984 return 0;
985
986 dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);
987
988 ret = soc_dai_link_sanity_check(card, dai_link);
989 if (ret < 0)
990 return ret;
991
992 rtd = soc_new_pcm_runtime(card, dai_link);
993 if (!rtd)
994 return -ENOMEM;
995
996 for_each_link_cpus(dai_link, i, cpu) {
997 asoc_rtd_to_cpu(rtd, i) = snd_soc_find_dai(cpu);
998 if (!asoc_rtd_to_cpu(rtd, i)) {
999 dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",
1000 cpu->dai_name);
1001 goto _err_defer;
1002 }
1003 snd_soc_rtd_add_component(rtd, asoc_rtd_to_cpu(rtd, i)->component);
1004 }
1005
1006
1007 for_each_link_codecs(dai_link, i, codec) {
1008 asoc_rtd_to_codec(rtd, i) = snd_soc_find_dai(codec);
1009 if (!asoc_rtd_to_codec(rtd, i)) {
1010 dev_info(card->dev, "ASoC: CODEC DAI %s not registered\n",
1011 codec->dai_name);
1012 goto _err_defer;
1013 }
1014
1015 snd_soc_rtd_add_component(rtd, asoc_rtd_to_codec(rtd, i)->component);
1016 }
1017
1018
1019 for_each_link_platforms(dai_link, i, platform) {
1020 for_each_component(component) {
1021 if (!snd_soc_is_matching_component(platform, component))
1022 continue;
1023
1024 snd_soc_rtd_add_component(rtd, component);
1025 }
1026 }
1027
1028 return 0;
1029
1030_err_defer:
1031 snd_soc_remove_pcm_runtime(card, rtd);
1032 return -EPROBE_DEFER;
1033}
1034EXPORT_SYMBOL_GPL(snd_soc_add_pcm_runtime);
1035
1036static void snd_soc_runtime_get_dai_fmt(struct snd_soc_pcm_runtime *rtd)
1037{
1038 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1039 struct snd_soc_dai *dai, *not_used;
1040 struct device *dev = rtd->dev;
1041 u64 pos, possible_fmt;
1042 unsigned int mask = 0, dai_fmt = 0;
1043 int i, j, priority, pri, until;
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080 until = snd_soc_dai_get_fmt_max_priority(rtd);
1081 for (priority = 1; priority <= until; priority++) {
1082
1083 dev_dbg(dev, "priority = %d\n", priority);
1084 for_each_rtd_dais(rtd, j, not_used) {
1085
1086 possible_fmt = ULLONG_MAX;
1087 for_each_rtd_dais(rtd, i, dai) {
1088 u64 fmt = 0;
1089
1090 pri = (j >= i) ? priority : priority - 1;
1091 fmt = snd_soc_dai_get_fmt(dai, pri);
1092 dev_dbg(dev, "%s: (pri, fmt) = (%d, %016llX)\n", dai->name, pri, fmt);
1093 possible_fmt &= fmt;
1094 }
1095 if (possible_fmt)
1096 goto found;
1097 }
1098 }
1099
1100 return;
1101found:
1102 dev_dbg(dev, "found auto selected format: %016llX\n", possible_fmt);
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 for (i = 63; i >= 0; i--) {
1121 pos = 1ULL << i;
1122 switch (possible_fmt & pos) {
1123
1124
1125
1126 case SND_SOC_POSSIBLE_DAIFMT_I2S:
1127 case SND_SOC_POSSIBLE_DAIFMT_RIGHT_J:
1128 case SND_SOC_POSSIBLE_DAIFMT_LEFT_J:
1129 case SND_SOC_POSSIBLE_DAIFMT_DSP_A:
1130 case SND_SOC_POSSIBLE_DAIFMT_DSP_B:
1131 case SND_SOC_POSSIBLE_DAIFMT_AC97:
1132 case SND_SOC_POSSIBLE_DAIFMT_PDM:
1133 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) | i;
1134 break;
1135
1136
1137
1138 case SND_SOC_POSSIBLE_DAIFMT_CONT:
1139 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_CONT;
1140 break;
1141 case SND_SOC_POSSIBLE_DAIFMT_GATED:
1142 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_MASK) | SND_SOC_DAIFMT_GATED;
1143 break;
1144
1145
1146
1147 case SND_SOC_POSSIBLE_DAIFMT_NB_NF:
1148 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_NF;
1149 break;
1150 case SND_SOC_POSSIBLE_DAIFMT_NB_IF:
1151 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_NB_IF;
1152 break;
1153 case SND_SOC_POSSIBLE_DAIFMT_IB_NF:
1154 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_NF;
1155 break;
1156 case SND_SOC_POSSIBLE_DAIFMT_IB_IF:
1157 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_INV_MASK) | SND_SOC_DAIFMT_IB_IF;
1158 break;
1159
1160
1161
1162 case SND_SOC_POSSIBLE_DAIFMT_CBP_CFP:
1163 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBP_CFP;
1164 break;
1165 case SND_SOC_POSSIBLE_DAIFMT_CBC_CFP:
1166 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBC_CFP;
1167 break;
1168 case SND_SOC_POSSIBLE_DAIFMT_CBP_CFC:
1169 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBP_CFC;
1170 break;
1171 case SND_SOC_POSSIBLE_DAIFMT_CBC_CFC:
1172 dai_fmt = (dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) | SND_SOC_DAIFMT_CBC_CFC;
1173 break;
1174 }
1175 }
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK))
1188 mask |= SND_SOC_DAIFMT_FORMAT_MASK;
1189 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_MASK))
1190 mask |= SND_SOC_DAIFMT_CLOCK_MASK;
1191 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_INV_MASK))
1192 mask |= SND_SOC_DAIFMT_INV_MASK;
1193 if (!(dai_link->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK))
1194 mask |= SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
1195
1196 dai_link->dai_fmt |= (dai_fmt & mask);
1197}
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
1213 unsigned int dai_fmt)
1214{
1215 struct snd_soc_dai *cpu_dai;
1216 struct snd_soc_dai *codec_dai;
1217 unsigned int inv_dai_fmt;
1218 unsigned int i;
1219 int ret;
1220
1221 if (!dai_fmt)
1222 return 0;
1223
1224 for_each_rtd_codec_dais(rtd, i, codec_dai) {
1225 ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt);
1226 if (ret != 0 && ret != -ENOTSUPP)
1227 return ret;
1228 }
1229
1230
1231
1232
1233 inv_dai_fmt = snd_soc_daifmt_clock_provider_fliped(dai_fmt);
1234
1235 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
1236 unsigned int fmt = dai_fmt;
1237
1238 if (snd_soc_component_is_codec(cpu_dai->component))
1239 fmt = inv_dai_fmt;
1240
1241 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
1242 if (ret != 0 && ret != -ENOTSUPP)
1243 return ret;
1244 }
1245
1246 return 0;
1247}
1248EXPORT_SYMBOL_GPL(snd_soc_runtime_set_dai_fmt);
1249
1250static int soc_init_pcm_runtime(struct snd_soc_card *card,
1251 struct snd_soc_pcm_runtime *rtd)
1252{
1253 struct snd_soc_dai_link *dai_link = rtd->dai_link;
1254 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
1255 struct snd_soc_component *component;
1256 int ret, num, i;
1257
1258
1259 rtd->pmdown_time = pmdown_time;
1260
1261
1262 ret = snd_soc_link_init(rtd);
1263 if (ret < 0)
1264 return ret;
1265
1266 snd_soc_runtime_get_dai_fmt(rtd);
1267 ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
1268 if (ret)
1269 return ret;
1270
1271
1272 soc_dpcm_debugfs_add(rtd);
1273
1274 num = rtd->num;
1275
1276
1277
1278
1279
1280
1281 for_each_rtd_components(rtd, i, component) {
1282 if (!component->driver->use_dai_pcm_id)
1283 continue;
1284
1285 if (rtd->dai_link->no_pcm)
1286 num += component->driver->be_pcm_base;
1287 else
1288 num = rtd->dai_link->id;
1289 }
1290
1291
1292 ret = snd_soc_dai_compress_new(cpu_dai, rtd, num);
1293 if (ret != -ENOTSUPP)
1294 return ret;
1295
1296
1297 ret = soc_new_pcm(rtd, num);
1298 if (ret < 0) {
1299 dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
1300 dai_link->stream_name, ret);
1301 return ret;
1302 }
1303
1304 return snd_soc_pcm_dai_new(rtd);
1305}
1306
1307static void soc_set_name_prefix(struct snd_soc_card *card,
1308 struct snd_soc_component *component)
1309{
1310 struct device_node *of_node = soc_component_to_node(component);
1311 const char *str;
1312 int ret, i;
1313
1314 for (i = 0; i < card->num_configs; i++) {
1315 struct snd_soc_codec_conf *map = &card->codec_conf[i];
1316
1317 if (snd_soc_is_matching_component(&map->dlc, component) &&
1318 map->name_prefix) {
1319 component->name_prefix = map->name_prefix;
1320 return;
1321 }
1322 }
1323
1324
1325
1326
1327
1328 ret = of_property_read_string(of_node, "sound-name-prefix", &str);
1329 if (ret < 0)
1330 return;
1331
1332 component->name_prefix = str;
1333}
1334
1335static void soc_remove_component(struct snd_soc_component *component,
1336 int probed)
1337{
1338
1339 if (!component->card)
1340 return;
1341
1342 if (probed)
1343 snd_soc_component_remove(component);
1344
1345 list_del_init(&component->card_list);
1346 snd_soc_dapm_free(snd_soc_component_get_dapm(component));
1347 soc_cleanup_component_debugfs(component);
1348 component->card = NULL;
1349 snd_soc_component_module_put_when_remove(component);
1350}
1351
1352static int soc_probe_component(struct snd_soc_card *card,
1353 struct snd_soc_component *component)
1354{
1355 struct snd_soc_dapm_context *dapm =
1356 snd_soc_component_get_dapm(component);
1357 struct snd_soc_dai *dai;
1358 int probed = 0;
1359 int ret;
1360
1361 if (snd_soc_component_is_dummy(component))
1362 return 0;
1363
1364 if (component->card) {
1365 if (component->card != card) {
1366 dev_err(component->dev,
1367 "Trying to bind component to card \"%s\" but is already bound to card \"%s\"\n",
1368 card->name, component->card->name);
1369 return -ENODEV;
1370 }
1371 return 0;
1372 }
1373
1374 ret = snd_soc_component_module_get_when_probe(component);
1375 if (ret < 0)
1376 return ret;
1377
1378 component->card = card;
1379 soc_set_name_prefix(card, component);
1380
1381 soc_init_component_debugfs(component);
1382
1383 snd_soc_dapm_init(dapm, card, component);
1384
1385 ret = snd_soc_dapm_new_controls(dapm,
1386 component->driver->dapm_widgets,
1387 component->driver->num_dapm_widgets);
1388
1389 if (ret != 0) {
1390 dev_err(component->dev,
1391 "Failed to create new controls %d\n", ret);
1392 goto err_probe;
1393 }
1394
1395 for_each_component_dais(component, dai) {
1396 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1397 if (ret != 0) {
1398 dev_err(component->dev,
1399 "Failed to create DAI widgets %d\n", ret);
1400 goto err_probe;
1401 }
1402 }
1403
1404 ret = snd_soc_component_probe(component);
1405 if (ret < 0)
1406 goto err_probe;
1407
1408 WARN(dapm->idle_bias_off &&
1409 dapm->bias_level != SND_SOC_BIAS_OFF,
1410 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1411 component->name);
1412 probed = 1;
1413
1414
1415
1416
1417
1418
1419 ret = snd_soc_component_init(component);
1420 if (ret < 0)
1421 goto err_probe;
1422
1423 ret = snd_soc_add_component_controls(component,
1424 component->driver->controls,
1425 component->driver->num_controls);
1426 if (ret < 0)
1427 goto err_probe;
1428
1429 ret = snd_soc_dapm_add_routes(dapm,
1430 component->driver->dapm_routes,
1431 component->driver->num_dapm_routes);
1432 if (ret < 0) {
1433 if (card->disable_route_checks) {
1434 dev_info(card->dev,
1435 "%s: disable_route_checks set, ignoring errors on add_routes\n",
1436 __func__);
1437 } else {
1438 dev_err(card->dev,
1439 "%s: snd_soc_dapm_add_routes failed: %d\n",
1440 __func__, ret);
1441 goto err_probe;
1442 }
1443 }
1444
1445
1446 list_add(&component->card_list, &card->component_dev_list);
1447
1448err_probe:
1449 if (ret < 0)
1450 soc_remove_component(component, probed);
1451
1452 return ret;
1453}
1454
1455static void soc_remove_link_dais(struct snd_soc_card *card)
1456{
1457 struct snd_soc_pcm_runtime *rtd;
1458 int order;
1459
1460 for_each_comp_order(order) {
1461 for_each_card_rtds(card, rtd) {
1462
1463 snd_soc_pcm_dai_remove(rtd, order);
1464 }
1465 }
1466}
1467
1468static int soc_probe_link_dais(struct snd_soc_card *card)
1469{
1470 struct snd_soc_pcm_runtime *rtd;
1471 int order, ret;
1472
1473 for_each_comp_order(order) {
1474 for_each_card_rtds(card, rtd) {
1475
1476 dev_dbg(card->dev,
1477 "ASoC: probe %s dai link %d late %d\n",
1478 card->name, rtd->num, order);
1479
1480
1481 ret = snd_soc_pcm_dai_probe(rtd, order);
1482 if (ret)
1483 return ret;
1484 }
1485 }
1486
1487 return 0;
1488}
1489
1490static void soc_remove_link_components(struct snd_soc_card *card)
1491{
1492 struct snd_soc_component *component;
1493 struct snd_soc_pcm_runtime *rtd;
1494 int i, order;
1495
1496 for_each_comp_order(order) {
1497 for_each_card_rtds(card, rtd) {
1498 for_each_rtd_components(rtd, i, component) {
1499 if (component->driver->remove_order != order)
1500 continue;
1501
1502 soc_remove_component(component, 1);
1503 }
1504 }
1505 }
1506}
1507
1508static int soc_probe_link_components(struct snd_soc_card *card)
1509{
1510 struct snd_soc_component *component;
1511 struct snd_soc_pcm_runtime *rtd;
1512 int i, ret, order;
1513
1514 for_each_comp_order(order) {
1515 for_each_card_rtds(card, rtd) {
1516 for_each_rtd_components(rtd, i, component) {
1517 if (component->driver->probe_order != order)
1518 continue;
1519
1520 ret = soc_probe_component(card, component);
1521 if (ret < 0)
1522 return ret;
1523 }
1524 }
1525 }
1526
1527 return 0;
1528}
1529
1530static void soc_unbind_aux_dev(struct snd_soc_card *card)
1531{
1532 struct snd_soc_component *component, *_component;
1533
1534 for_each_card_auxs_safe(card, component, _component) {
1535
1536 snd_soc_component_set_aux(component, NULL);
1537 list_del(&component->card_aux_list);
1538 }
1539}
1540
1541static int soc_bind_aux_dev(struct snd_soc_card *card)
1542{
1543 struct snd_soc_component *component;
1544 struct snd_soc_aux_dev *aux;
1545 int i;
1546
1547 for_each_card_pre_auxs(card, i, aux) {
1548
1549 component = soc_find_component(&aux->dlc);
1550 if (!component)
1551 return -EPROBE_DEFER;
1552
1553
1554 snd_soc_component_set_aux(component, aux);
1555
1556 list_add(&component->card_aux_list, &card->aux_comp_list);
1557 }
1558 return 0;
1559}
1560
1561static int soc_probe_aux_devices(struct snd_soc_card *card)
1562{
1563 struct snd_soc_component *component;
1564 int order;
1565 int ret;
1566
1567 for_each_comp_order(order) {
1568 for_each_card_auxs(card, component) {
1569 if (component->driver->probe_order != order)
1570 continue;
1571
1572 ret = soc_probe_component(card, component);
1573 if (ret < 0)
1574 return ret;
1575 }
1576 }
1577
1578 return 0;
1579}
1580
1581static void soc_remove_aux_devices(struct snd_soc_card *card)
1582{
1583 struct snd_soc_component *comp, *_comp;
1584 int order;
1585
1586 for_each_comp_order(order) {
1587 for_each_card_auxs_safe(card, comp, _comp) {
1588 if (comp->driver->remove_order == order)
1589 soc_remove_component(comp, 1);
1590 }
1591 }
1592}
1593
1594#ifdef CONFIG_DMI
1595
1596
1597
1598
1599
1600static const char * const dmi_blacklist[] = {
1601 "To be filled by OEM",
1602 "TBD by OEM",
1603 "Default String",
1604 "Board Manufacturer",
1605 "Board Vendor Name",
1606 "Board Product Name",
1607 NULL,
1608};
1609
1610
1611
1612
1613
1614
1615static void cleanup_dmi_name(char *name)
1616{
1617 int i, j = 0;
1618
1619 for (i = 0; name[i]; i++) {
1620 if (isalnum(name[i]) || (name[i] == '.')
1621 || (name[i] == '_'))
1622 name[j++] = name[i];
1623 else if (name[i] == '-')
1624 name[j++] = '_';
1625 }
1626
1627 name[j] = '\0';
1628}
1629
1630
1631
1632
1633
1634static int is_dmi_valid(const char *field)
1635{
1636 int i = 0;
1637
1638 while (dmi_blacklist[i]) {
1639 if (strstr(field, dmi_blacklist[i]))
1640 return 0;
1641 i++;
1642 }
1643
1644 return 1;
1645}
1646
1647
1648
1649
1650static void append_dmi_string(struct snd_soc_card *card, const char *str)
1651{
1652 char *dst = card->dmi_longname;
1653 size_t dst_len = sizeof(card->dmi_longname);
1654 size_t len;
1655
1656 len = strlen(dst);
1657 snprintf(dst + len, dst_len - len, "-%s", str);
1658
1659 len++;
1660 if (len < dst_len)
1661 cleanup_dmi_name(dst + len);
1662}
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
1696{
1697 const char *vendor, *product, *board;
1698
1699 if (card->long_name)
1700 return 0;
1701
1702 if (!dmi_available)
1703 return 0;
1704
1705
1706 vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1707 if (!vendor || !is_dmi_valid(vendor)) {
1708 dev_warn(card->dev, "ASoC: no DMI vendor name!\n");
1709 return 0;
1710 }
1711
1712 snprintf(card->dmi_longname, sizeof(card->dmi_longname), "%s", vendor);
1713 cleanup_dmi_name(card->dmi_longname);
1714
1715 product = dmi_get_system_info(DMI_PRODUCT_NAME);
1716 if (product && is_dmi_valid(product)) {
1717 const char *product_version = dmi_get_system_info(DMI_PRODUCT_VERSION);
1718
1719 append_dmi_string(card, product);
1720
1721
1722
1723
1724
1725 if (product_version && is_dmi_valid(product_version))
1726 append_dmi_string(card, product_version);
1727 }
1728
1729 board = dmi_get_system_info(DMI_BOARD_NAME);
1730 if (board && is_dmi_valid(board)) {
1731 if (!product || strcasecmp(board, product))
1732 append_dmi_string(card, board);
1733 } else if (!product) {
1734
1735 dev_warn(card->dev, "ASoC: no DMI board/product name!\n");
1736 return 0;
1737 }
1738
1739
1740 if (flavour)
1741 append_dmi_string(card, flavour);
1742
1743
1744 card->long_name = card->dmi_longname;
1745
1746 return 0;
1747}
1748EXPORT_SYMBOL_GPL(snd_soc_set_dmi_name);
1749#endif
1750
1751static void soc_check_tplg_fes(struct snd_soc_card *card)
1752{
1753 struct snd_soc_component *component;
1754 const struct snd_soc_component_driver *comp_drv;
1755 struct snd_soc_dai_link *dai_link;
1756 int i;
1757
1758 for_each_component(component) {
1759
1760
1761 if (!component->driver->ignore_machine)
1762 continue;
1763
1764
1765 if (!strcmp(component->driver->ignore_machine,
1766 card->dev->driver->name))
1767 goto match;
1768 if (strcmp(component->driver->ignore_machine,
1769 dev_name(card->dev)))
1770 continue;
1771match:
1772
1773 for_each_card_prelinks(card, i, dai_link) {
1774
1775
1776 if (dai_link->dynamic) {
1777 dai_link->ignore = true;
1778 continue;
1779 }
1780
1781 dev_dbg(card->dev, "info: override BE DAI link %s\n",
1782 card->dai_link[i].name);
1783
1784
1785 if (!dai_link->platforms) {
1786 dev_err(card->dev, "init platform error");
1787 continue;
1788 }
1789
1790 if (component->dev->of_node)
1791 dai_link->platforms->of_node = component->dev->of_node;
1792 else
1793 dai_link->platforms->name = component->name;
1794
1795
1796 if (!dai_link->no_pcm) {
1797 dai_link->no_pcm = 1;
1798
1799 if (dai_link->dpcm_playback)
1800 dev_warn(card->dev,
1801 "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_playback=1\n",
1802 dai_link->name);
1803 if (dai_link->dpcm_capture)
1804 dev_warn(card->dev,
1805 "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_capture=1\n",
1806 dai_link->name);
1807
1808
1809 if (!(dai_link->dpcm_playback ||
1810 dai_link->dpcm_capture)) {
1811 dai_link->dpcm_playback = !dai_link->capture_only;
1812 dai_link->dpcm_capture = !dai_link->playback_only;
1813 }
1814 }
1815
1816
1817
1818
1819
1820
1821 dai_link->be_hw_params_fixup =
1822 component->driver->be_hw_params_fixup;
1823
1824
1825
1826
1827
1828 if (!dai_link->stream_name)
1829 dai_link->stream_name = dai_link->name;
1830 }
1831
1832
1833 if (component->driver->topology_name_prefix) {
1834
1835
1836 if (!card->topology_shortname_created) {
1837 comp_drv = component->driver;
1838
1839 snprintf(card->topology_shortname, 32, "%s-%s",
1840 comp_drv->topology_name_prefix,
1841 card->name);
1842 card->topology_shortname_created = true;
1843 }
1844
1845
1846 card->name = card->topology_shortname;
1847 }
1848 }
1849}
1850
1851#define soc_setup_card_name(name, name1, name2, norm) \
1852 __soc_setup_card_name(name, sizeof(name), name1, name2, norm)
1853static void __soc_setup_card_name(char *name, int len,
1854 const char *name1, const char *name2,
1855 int normalization)
1856{
1857 int i;
1858
1859 snprintf(name, len, "%s", name1 ? name1 : name2);
1860
1861 if (!normalization)
1862 return;
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873 for (i = 0; i < len; i++) {
1874 switch (name[i]) {
1875 case '_':
1876 case '-':
1877 case '\0':
1878 break;
1879 default:
1880 if (!isalnum(name[i]))
1881 name[i] = '_';
1882 break;
1883 }
1884 }
1885}
1886
1887static void soc_cleanup_card_resources(struct snd_soc_card *card)
1888{
1889 struct snd_soc_pcm_runtime *rtd, *n;
1890
1891 if (card->snd_card)
1892 snd_card_disconnect_sync(card->snd_card);
1893
1894 snd_soc_dapm_shutdown(card);
1895
1896
1897 soc_remove_link_dais(card);
1898 soc_remove_link_components(card);
1899
1900 for_each_card_rtds_safe(card, rtd, n)
1901 snd_soc_remove_pcm_runtime(card, rtd);
1902
1903
1904 soc_remove_aux_devices(card);
1905 soc_unbind_aux_dev(card);
1906
1907 snd_soc_dapm_free(&card->dapm);
1908 soc_cleanup_card_debugfs(card);
1909
1910
1911 snd_soc_card_remove(card);
1912
1913 if (card->snd_card) {
1914 snd_card_free(card->snd_card);
1915 card->snd_card = NULL;
1916 }
1917}
1918
1919static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister)
1920{
1921 if (card->instantiated) {
1922 card->instantiated = false;
1923 snd_soc_flush_all_delayed_work(card);
1924
1925 soc_cleanup_card_resources(card);
1926 if (!unregister)
1927 list_add(&card->list, &unbind_card_list);
1928 } else {
1929 if (unregister)
1930 list_del(&card->list);
1931 }
1932}
1933
1934static int snd_soc_bind_card(struct snd_soc_card *card)
1935{
1936 struct snd_soc_pcm_runtime *rtd;
1937 struct snd_soc_component *component;
1938 struct snd_soc_dai_link *dai_link;
1939 int ret, i;
1940
1941 mutex_lock(&client_mutex);
1942 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
1943
1944 snd_soc_dapm_init(&card->dapm, card, NULL);
1945
1946
1947 soc_check_tplg_fes(card);
1948
1949
1950 ret = soc_bind_aux_dev(card);
1951 if (ret < 0)
1952 goto probe_end;
1953
1954
1955 card->num_rtd = 0;
1956 for_each_card_prelinks(card, i, dai_link) {
1957 ret = snd_soc_add_pcm_runtime(card, dai_link);
1958 if (ret < 0)
1959 goto probe_end;
1960 }
1961
1962
1963 ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1964 card->owner, 0, &card->snd_card);
1965 if (ret < 0) {
1966 dev_err(card->dev,
1967 "ASoC: can't create sound card for card %s: %d\n",
1968 card->name, ret);
1969 goto probe_end;
1970 }
1971
1972 soc_init_card_debugfs(card);
1973
1974 soc_resume_init(card);
1975
1976 ret = snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
1977 card->num_dapm_widgets);
1978 if (ret < 0)
1979 goto probe_end;
1980
1981 ret = snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets,
1982 card->num_of_dapm_widgets);
1983 if (ret < 0)
1984 goto probe_end;
1985
1986
1987 ret = snd_soc_card_probe(card);
1988 if (ret < 0)
1989 goto probe_end;
1990
1991
1992 ret = soc_probe_link_components(card);
1993 if (ret < 0) {
1994 dev_err(card->dev,
1995 "ASoC: failed to instantiate card %d\n", ret);
1996 goto probe_end;
1997 }
1998
1999
2000 ret = soc_probe_aux_devices(card);
2001 if (ret < 0) {
2002 dev_err(card->dev,
2003 "ASoC: failed to probe aux component %d\n", ret);
2004 goto probe_end;
2005 }
2006
2007
2008 ret = soc_probe_link_dais(card);
2009 if (ret < 0) {
2010 dev_err(card->dev,
2011 "ASoC: failed to instantiate card %d\n", ret);
2012 goto probe_end;
2013 }
2014
2015 for_each_card_rtds(card, rtd) {
2016 ret = soc_init_pcm_runtime(card, rtd);
2017 if (ret < 0)
2018 goto probe_end;
2019 }
2020
2021 snd_soc_dapm_link_dai_widgets(card);
2022 snd_soc_dapm_connect_dai_link_widgets(card);
2023
2024 ret = snd_soc_add_card_controls(card, card->controls,
2025 card->num_controls);
2026 if (ret < 0)
2027 goto probe_end;
2028
2029 ret = snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
2030 card->num_dapm_routes);
2031 if (ret < 0) {
2032 if (card->disable_route_checks) {
2033 dev_info(card->dev,
2034 "%s: disable_route_checks set, ignoring errors on add_routes\n",
2035 __func__);
2036 } else {
2037 dev_err(card->dev,
2038 "%s: snd_soc_dapm_add_routes failed: %d\n",
2039 __func__, ret);
2040 goto probe_end;
2041 }
2042 }
2043
2044 ret = snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
2045 card->num_of_dapm_routes);
2046 if (ret < 0)
2047 goto probe_end;
2048
2049
2050 snd_soc_set_dmi_name(card, NULL);
2051
2052 soc_setup_card_name(card->snd_card->shortname,
2053 card->name, NULL, 0);
2054 soc_setup_card_name(card->snd_card->longname,
2055 card->long_name, card->name, 0);
2056 soc_setup_card_name(card->snd_card->driver,
2057 card->driver_name, card->name, 1);
2058
2059 if (card->components) {
2060
2061
2062
2063
2064 ret = snd_component_add(card->snd_card, card->components);
2065 if (ret < 0) {
2066 dev_err(card->dev, "ASoC: %s snd_component_add() failed: %d\n",
2067 card->name, ret);
2068 goto probe_end;
2069 }
2070 }
2071
2072 ret = snd_soc_card_late_probe(card);
2073 if (ret < 0)
2074 goto probe_end;
2075
2076 snd_soc_dapm_new_widgets(card);
2077
2078 ret = snd_card_register(card->snd_card);
2079 if (ret < 0) {
2080 dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
2081 ret);
2082 goto probe_end;
2083 }
2084
2085 card->instantiated = 1;
2086 dapm_mark_endpoints_dirty(card);
2087 snd_soc_dapm_sync(&card->dapm);
2088
2089
2090 for_each_card_components(card, component)
2091 if (!snd_soc_component_active(component))
2092 pinctrl_pm_select_sleep_state(component->dev);
2093
2094probe_end:
2095 if (ret < 0)
2096 soc_cleanup_card_resources(card);
2097
2098 mutex_unlock(&card->mutex);
2099 mutex_unlock(&client_mutex);
2100
2101 return ret;
2102}
2103
2104
2105static int soc_probe(struct platform_device *pdev)
2106{
2107 struct snd_soc_card *card = platform_get_drvdata(pdev);
2108
2109
2110
2111
2112
2113 if (!card)
2114 return -EINVAL;
2115
2116 dev_warn(&pdev->dev,
2117 "ASoC: machine %s should use snd_soc_register_card()\n",
2118 card->name);
2119
2120
2121 card->dev = &pdev->dev;
2122
2123 return devm_snd_soc_register_card(&pdev->dev, card);
2124}
2125
2126int snd_soc_poweroff(struct device *dev)
2127{
2128 struct snd_soc_card *card = dev_get_drvdata(dev);
2129 struct snd_soc_component *component;
2130
2131 if (!card->instantiated)
2132 return 0;
2133
2134
2135
2136
2137
2138 snd_soc_flush_all_delayed_work(card);
2139
2140 snd_soc_dapm_shutdown(card);
2141
2142
2143 for_each_card_components(card, component)
2144 pinctrl_pm_select_sleep_state(component->dev);
2145
2146 return 0;
2147}
2148EXPORT_SYMBOL_GPL(snd_soc_poweroff);
2149
2150const struct dev_pm_ops snd_soc_pm_ops = {
2151 .suspend = snd_soc_suspend,
2152 .resume = snd_soc_resume,
2153 .freeze = snd_soc_suspend,
2154 .thaw = snd_soc_resume,
2155 .poweroff = snd_soc_poweroff,
2156 .restore = snd_soc_resume,
2157};
2158EXPORT_SYMBOL_GPL(snd_soc_pm_ops);
2159
2160
2161static struct platform_driver soc_driver = {
2162 .driver = {
2163 .name = "soc-audio",
2164 .pm = &snd_soc_pm_ops,
2165 },
2166 .probe = soc_probe,
2167};
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2181 void *data, const char *long_name,
2182 const char *prefix)
2183{
2184 struct snd_kcontrol_new template;
2185 struct snd_kcontrol *kcontrol;
2186 char *name = NULL;
2187
2188 memcpy(&template, _template, sizeof(template));
2189 template.index = 0;
2190
2191 if (!long_name)
2192 long_name = template.name;
2193
2194 if (prefix) {
2195 name = kasprintf(GFP_KERNEL, "%s %s", prefix, long_name);
2196 if (!name)
2197 return NULL;
2198
2199 template.name = name;
2200 } else {
2201 template.name = long_name;
2202 }
2203
2204 kcontrol = snd_ctl_new1(&template, data);
2205
2206 kfree(name);
2207
2208 return kcontrol;
2209}
2210EXPORT_SYMBOL_GPL(snd_soc_cnew);
2211
2212static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
2213 const struct snd_kcontrol_new *controls, int num_controls,
2214 const char *prefix, void *data)
2215{
2216 int i;
2217
2218 for (i = 0; i < num_controls; i++) {
2219 const struct snd_kcontrol_new *control = &controls[i];
2220 int err = snd_ctl_add(card, snd_soc_cnew(control, data,
2221 control->name, prefix));
2222 if (err < 0) {
2223 dev_err(dev, "ASoC: Failed to add %s: %d\n",
2224 control->name, err);
2225 return err;
2226 }
2227 }
2228
2229 return 0;
2230}
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241int snd_soc_add_component_controls(struct snd_soc_component *component,
2242 const struct snd_kcontrol_new *controls, unsigned int num_controls)
2243{
2244 struct snd_card *card = component->card->snd_card;
2245
2246 return snd_soc_add_controls(card, component->dev, controls,
2247 num_controls, component->name_prefix, component);
2248}
2249EXPORT_SYMBOL_GPL(snd_soc_add_component_controls);
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261int snd_soc_add_card_controls(struct snd_soc_card *soc_card,
2262 const struct snd_kcontrol_new *controls, int num_controls)
2263{
2264 struct snd_card *card = soc_card->snd_card;
2265
2266 return snd_soc_add_controls(card, soc_card->dev, controls, num_controls,
2267 NULL, soc_card);
2268}
2269EXPORT_SYMBOL_GPL(snd_soc_add_card_controls);
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
2282 const struct snd_kcontrol_new *controls, int num_controls)
2283{
2284 struct snd_card *card = dai->component->card->snd_card;
2285
2286 return snd_soc_add_controls(card, dai->dev, controls, num_controls,
2287 NULL, dai);
2288}
2289EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
2290
2291
2292
2293
2294
2295
2296
2297int snd_soc_register_card(struct snd_soc_card *card)
2298{
2299 if (!card->name || !card->dev)
2300 return -EINVAL;
2301
2302 dev_set_drvdata(card->dev, card);
2303
2304 INIT_LIST_HEAD(&card->widgets);
2305 INIT_LIST_HEAD(&card->paths);
2306 INIT_LIST_HEAD(&card->dapm_list);
2307 INIT_LIST_HEAD(&card->aux_comp_list);
2308 INIT_LIST_HEAD(&card->component_dev_list);
2309 INIT_LIST_HEAD(&card->list);
2310 INIT_LIST_HEAD(&card->rtd_list);
2311 INIT_LIST_HEAD(&card->dapm_dirty);
2312 INIT_LIST_HEAD(&card->dobj_list);
2313
2314 card->instantiated = 0;
2315 mutex_init(&card->mutex);
2316 mutex_init(&card->dapm_mutex);
2317 mutex_init(&card->pcm_mutex);
2318
2319 return snd_soc_bind_card(card);
2320}
2321EXPORT_SYMBOL_GPL(snd_soc_register_card);
2322
2323
2324
2325
2326
2327
2328
2329int snd_soc_unregister_card(struct snd_soc_card *card)
2330{
2331 mutex_lock(&client_mutex);
2332 snd_soc_unbind_card(card, true);
2333 mutex_unlock(&client_mutex);
2334 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
2335
2336 return 0;
2337}
2338EXPORT_SYMBOL_GPL(snd_soc_unregister_card);
2339
2340
2341
2342
2343
2344static char *fmt_single_name(struct device *dev, int *id)
2345{
2346 const char *devname = dev_name(dev);
2347 char *found, *name;
2348 unsigned int id1, id2;
2349
2350 if (devname == NULL)
2351 return NULL;
2352
2353 name = devm_kstrdup(dev, devname, GFP_KERNEL);
2354 if (!name)
2355 return NULL;
2356
2357
2358 found = strstr(name, dev->driver->name);
2359 if (found) {
2360
2361 if (sscanf(&found[strlen(dev->driver->name)], ".%d", id) == 1) {
2362
2363
2364 if (*id == -1)
2365 found[strlen(dev->driver->name)] = '\0';
2366 }
2367
2368
2369 } else if (sscanf(name, "%x-%x", &id1, &id2) == 2) {
2370
2371
2372 *id = ((id1 & 0xffff) << 16) + id2;
2373
2374 devm_kfree(dev, name);
2375
2376
2377 name = devm_kasprintf(dev, GFP_KERNEL, "%s.%s", dev->driver->name, devname);
2378 } else {
2379 *id = 0;
2380 }
2381
2382 return name;
2383}
2384
2385
2386
2387
2388
2389static inline char *fmt_multiple_name(struct device *dev,
2390 struct snd_soc_dai_driver *dai_drv)
2391{
2392 if (dai_drv->name == NULL) {
2393 dev_err(dev,
2394 "ASoC: error - multiple DAI %s registered with no name\n",
2395 dev_name(dev));
2396 return NULL;
2397 }
2398
2399 return devm_kstrdup(dev, dai_drv->name, GFP_KERNEL);
2400}
2401
2402void snd_soc_unregister_dai(struct snd_soc_dai *dai)
2403{
2404 dev_dbg(dai->dev, "ASoC: Unregistered DAI '%s'\n", dai->name);
2405 list_del(&dai->list);
2406}
2407EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
2422 struct snd_soc_dai_driver *dai_drv,
2423 bool legacy_dai_naming)
2424{
2425 struct device *dev = component->dev;
2426 struct snd_soc_dai *dai;
2427
2428 dev_dbg(dev, "ASoC: dynamically register DAI %s\n", dev_name(dev));
2429
2430 lockdep_assert_held(&client_mutex);
2431
2432 dai = devm_kzalloc(dev, sizeof(*dai), GFP_KERNEL);
2433 if (dai == NULL)
2434 return NULL;
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444 if (legacy_dai_naming &&
2445 (dai_drv->id == 0 || dai_drv->name == NULL)) {
2446 dai->name = fmt_single_name(dev, &dai->id);
2447 } else {
2448 dai->name = fmt_multiple_name(dev, dai_drv);
2449 if (dai_drv->id)
2450 dai->id = dai_drv->id;
2451 else
2452 dai->id = component->num_dai;
2453 }
2454 if (!dai->name)
2455 return NULL;
2456
2457 dai->component = component;
2458 dai->dev = dev;
2459 dai->driver = dai_drv;
2460
2461
2462 list_add_tail(&dai->list, &component->dai_list);
2463 component->num_dai++;
2464
2465 dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);
2466 return dai;
2467}
2468
2469
2470
2471
2472
2473
2474static void snd_soc_unregister_dais(struct snd_soc_component *component)
2475{
2476 struct snd_soc_dai *dai, *_dai;
2477
2478 for_each_component_dais_safe(component, dai, _dai)
2479 snd_soc_unregister_dai(dai);
2480}
2481
2482
2483
2484
2485
2486
2487
2488
2489static int snd_soc_register_dais(struct snd_soc_component *component,
2490 struct snd_soc_dai_driver *dai_drv,
2491 size_t count)
2492{
2493 struct snd_soc_dai *dai;
2494 unsigned int i;
2495 int ret;
2496
2497 for (i = 0; i < count; i++) {
2498 dai = snd_soc_register_dai(component, dai_drv + i, count == 1 &&
2499 !snd_soc_component_is_codec(component));
2500 if (dai == NULL) {
2501 ret = -ENOMEM;
2502 goto err;
2503 }
2504 }
2505
2506 return 0;
2507
2508err:
2509 snd_soc_unregister_dais(component);
2510
2511 return ret;
2512}
2513
2514#define ENDIANNESS_MAP(name) \
2515 (SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE)
2516static u64 endianness_format_map[] = {
2517 ENDIANNESS_MAP(S16_),
2518 ENDIANNESS_MAP(U16_),
2519 ENDIANNESS_MAP(S24_),
2520 ENDIANNESS_MAP(U24_),
2521 ENDIANNESS_MAP(S32_),
2522 ENDIANNESS_MAP(U32_),
2523 ENDIANNESS_MAP(S24_3),
2524 ENDIANNESS_MAP(U24_3),
2525 ENDIANNESS_MAP(S20_3),
2526 ENDIANNESS_MAP(U20_3),
2527 ENDIANNESS_MAP(S18_3),
2528 ENDIANNESS_MAP(U18_3),
2529 ENDIANNESS_MAP(FLOAT_),
2530 ENDIANNESS_MAP(FLOAT64_),
2531 ENDIANNESS_MAP(IEC958_SUBFRAME_),
2532};
2533
2534
2535
2536
2537
2538
2539
2540static void convert_endianness_formats(struct snd_soc_pcm_stream *stream)
2541{
2542 int i;
2543
2544 for (i = 0; i < ARRAY_SIZE(endianness_format_map); i++)
2545 if (stream->formats & endianness_format_map[i])
2546 stream->formats |= endianness_format_map[i];
2547}
2548
2549static void snd_soc_try_rebind_card(void)
2550{
2551 struct snd_soc_card *card, *c;
2552
2553 list_for_each_entry_safe(card, c, &unbind_card_list, list)
2554 if (!snd_soc_bind_card(card))
2555 list_del(&card->list);
2556}
2557
2558static void snd_soc_del_component_unlocked(struct snd_soc_component *component)
2559{
2560 struct snd_soc_card *card = component->card;
2561
2562 snd_soc_unregister_dais(component);
2563
2564 if (card)
2565 snd_soc_unbind_card(card, false);
2566
2567 list_del(&component->list);
2568}
2569
2570int snd_soc_component_initialize(struct snd_soc_component *component,
2571 const struct snd_soc_component_driver *driver,
2572 struct device *dev)
2573{
2574 INIT_LIST_HEAD(&component->dai_list);
2575 INIT_LIST_HEAD(&component->dobj_list);
2576 INIT_LIST_HEAD(&component->card_list);
2577 INIT_LIST_HEAD(&component->list);
2578 mutex_init(&component->io_mutex);
2579
2580 component->name = fmt_single_name(dev, &component->id);
2581 if (!component->name) {
2582 dev_err(dev, "ASoC: Failed to allocate name\n");
2583 return -ENOMEM;
2584 }
2585
2586 component->dev = dev;
2587 component->driver = driver;
2588
2589 return 0;
2590}
2591EXPORT_SYMBOL_GPL(snd_soc_component_initialize);
2592
2593int snd_soc_add_component(struct snd_soc_component *component,
2594 struct snd_soc_dai_driver *dai_drv,
2595 int num_dai)
2596{
2597 int ret;
2598 int i;
2599
2600 mutex_lock(&client_mutex);
2601
2602 if (component->driver->endianness) {
2603 for (i = 0; i < num_dai; i++) {
2604 convert_endianness_formats(&dai_drv[i].playback);
2605 convert_endianness_formats(&dai_drv[i].capture);
2606 }
2607 }
2608
2609 ret = snd_soc_register_dais(component, dai_drv, num_dai);
2610 if (ret < 0) {
2611 dev_err(component->dev, "ASoC: Failed to register DAIs: %d\n",
2612 ret);
2613 goto err_cleanup;
2614 }
2615
2616 if (!component->driver->write && !component->driver->read) {
2617 if (!component->regmap)
2618 component->regmap = dev_get_regmap(component->dev,
2619 NULL);
2620 if (component->regmap)
2621 snd_soc_component_setup_regmap(component);
2622 }
2623
2624
2625 list_add(&component->list, &component_list);
2626
2627err_cleanup:
2628 if (ret < 0)
2629 snd_soc_del_component_unlocked(component);
2630
2631 mutex_unlock(&client_mutex);
2632
2633 if (ret == 0)
2634 snd_soc_try_rebind_card();
2635
2636 return ret;
2637}
2638EXPORT_SYMBOL_GPL(snd_soc_add_component);
2639
2640int snd_soc_register_component(struct device *dev,
2641 const struct snd_soc_component_driver *component_driver,
2642 struct snd_soc_dai_driver *dai_drv,
2643 int num_dai)
2644{
2645 struct snd_soc_component *component;
2646 int ret;
2647
2648 component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL);
2649 if (!component)
2650 return -ENOMEM;
2651
2652 ret = snd_soc_component_initialize(component, component_driver, dev);
2653 if (ret < 0)
2654 return ret;
2655
2656 return snd_soc_add_component(component, dai_drv, num_dai);
2657}
2658EXPORT_SYMBOL_GPL(snd_soc_register_component);
2659
2660
2661
2662
2663
2664
2665
2666
2667void snd_soc_unregister_component_by_driver(struct device *dev,
2668 const struct snd_soc_component_driver *component_driver)
2669{
2670 struct snd_soc_component *component;
2671
2672 if (!component_driver)
2673 return;
2674
2675 mutex_lock(&client_mutex);
2676 component = snd_soc_lookup_component_nolocked(dev, component_driver->name);
2677 if (!component)
2678 goto out;
2679
2680 snd_soc_del_component_unlocked(component);
2681
2682out:
2683 mutex_unlock(&client_mutex);
2684}
2685EXPORT_SYMBOL_GPL(snd_soc_unregister_component_by_driver);
2686
2687
2688
2689
2690
2691
2692
2693void snd_soc_unregister_component(struct device *dev)
2694{
2695 mutex_lock(&client_mutex);
2696 while (1) {
2697 struct snd_soc_component *component = snd_soc_lookup_component_nolocked(dev, NULL);
2698
2699 if (!component)
2700 break;
2701
2702 snd_soc_del_component_unlocked(component);
2703 }
2704 mutex_unlock(&client_mutex);
2705}
2706EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
2707
2708
2709int snd_soc_of_parse_card_name(struct snd_soc_card *card,
2710 const char *propname)
2711{
2712 struct device_node *np;
2713 int ret;
2714
2715 if (!card->dev) {
2716 pr_err("card->dev is not set before calling %s\n", __func__);
2717 return -EINVAL;
2718 }
2719
2720 np = card->dev->of_node;
2721
2722 ret = of_property_read_string_index(np, propname, 0, &card->name);
2723
2724
2725
2726
2727
2728 if (ret < 0 && ret != -EINVAL) {
2729 dev_err(card->dev,
2730 "ASoC: Property '%s' could not be read: %d\n",
2731 propname, ret);
2732 return ret;
2733 }
2734
2735 return 0;
2736}
2737EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
2738
2739static const struct snd_soc_dapm_widget simple_widgets[] = {
2740 SND_SOC_DAPM_MIC("Microphone", NULL),
2741 SND_SOC_DAPM_LINE("Line", NULL),
2742 SND_SOC_DAPM_HP("Headphone", NULL),
2743 SND_SOC_DAPM_SPK("Speaker", NULL),
2744};
2745
2746int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
2747 const char *propname)
2748{
2749 struct device_node *np = card->dev->of_node;
2750 struct snd_soc_dapm_widget *widgets;
2751 const char *template, *wname;
2752 int i, j, num_widgets;
2753
2754 num_widgets = of_property_count_strings(np, propname);
2755 if (num_widgets < 0) {
2756 dev_err(card->dev,
2757 "ASoC: Property '%s' does not exist\n", propname);
2758 return -EINVAL;
2759 }
2760 if (num_widgets & 1) {
2761 dev_err(card->dev,
2762 "ASoC: Property '%s' length is not even\n", propname);
2763 return -EINVAL;
2764 }
2765
2766 num_widgets /= 2;
2767 if (!num_widgets) {
2768 dev_err(card->dev, "ASoC: Property '%s's length is zero\n",
2769 propname);
2770 return -EINVAL;
2771 }
2772
2773 widgets = devm_kcalloc(card->dev, num_widgets, sizeof(*widgets),
2774 GFP_KERNEL);
2775 if (!widgets) {
2776 dev_err(card->dev,
2777 "ASoC: Could not allocate memory for widgets\n");
2778 return -ENOMEM;
2779 }
2780
2781 for (i = 0; i < num_widgets; i++) {
2782 int ret = of_property_read_string_index(np, propname,
2783 2 * i, &template);
2784 if (ret) {
2785 dev_err(card->dev,
2786 "ASoC: Property '%s' index %d read error:%d\n",
2787 propname, 2 * i, ret);
2788 return -EINVAL;
2789 }
2790
2791 for (j = 0; j < ARRAY_SIZE(simple_widgets); j++) {
2792 if (!strncmp(template, simple_widgets[j].name,
2793 strlen(simple_widgets[j].name))) {
2794 widgets[i] = simple_widgets[j];
2795 break;
2796 }
2797 }
2798
2799 if (j >= ARRAY_SIZE(simple_widgets)) {
2800 dev_err(card->dev,
2801 "ASoC: DAPM widget '%s' is not supported\n",
2802 template);
2803 return -EINVAL;
2804 }
2805
2806 ret = of_property_read_string_index(np, propname,
2807 (2 * i) + 1,
2808 &wname);
2809 if (ret) {
2810 dev_err(card->dev,
2811 "ASoC: Property '%s' index %d read error:%d\n",
2812 propname, (2 * i) + 1, ret);
2813 return -EINVAL;
2814 }
2815
2816 widgets[i].name = wname;
2817 }
2818
2819 card->of_dapm_widgets = widgets;
2820 card->num_of_dapm_widgets = num_widgets;
2821
2822 return 0;
2823}
2824EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
2825
2826int snd_soc_of_parse_pin_switches(struct snd_soc_card *card, const char *prop)
2827{
2828 const unsigned int nb_controls_max = 16;
2829 const char **strings, *control_name;
2830 struct snd_kcontrol_new *controls;
2831 struct device *dev = card->dev;
2832 unsigned int i, nb_controls;
2833 int ret;
2834
2835 if (!of_property_read_bool(dev->of_node, prop))
2836 return 0;
2837
2838 strings = devm_kcalloc(dev, nb_controls_max,
2839 sizeof(*strings), GFP_KERNEL);
2840 if (!strings)
2841 return -ENOMEM;
2842
2843 ret = of_property_read_string_array(dev->of_node, prop,
2844 strings, nb_controls_max);
2845 if (ret < 0)
2846 return ret;
2847
2848 nb_controls = (unsigned int)ret;
2849
2850 controls = devm_kcalloc(dev, nb_controls,
2851 sizeof(*controls), GFP_KERNEL);
2852 if (!controls)
2853 return -ENOMEM;
2854
2855 for (i = 0; i < nb_controls; i++) {
2856 control_name = devm_kasprintf(dev, GFP_KERNEL,
2857 "%s Switch", strings[i]);
2858 if (!control_name)
2859 return -ENOMEM;
2860
2861 controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2862 controls[i].name = control_name;
2863 controls[i].info = snd_soc_dapm_info_pin_switch;
2864 controls[i].get = snd_soc_dapm_get_pin_switch;
2865 controls[i].put = snd_soc_dapm_put_pin_switch;
2866 controls[i].private_value = (unsigned long)strings[i];
2867 }
2868
2869 card->controls = controls;
2870 card->num_controls = nb_controls;
2871
2872 return 0;
2873}
2874EXPORT_SYMBOL_GPL(snd_soc_of_parse_pin_switches);
2875
2876int snd_soc_of_get_slot_mask(struct device_node *np,
2877 const char *prop_name,
2878 unsigned int *mask)
2879{
2880 u32 val;
2881 const __be32 *of_slot_mask = of_get_property(np, prop_name, &val);
2882 int i;
2883
2884 if (!of_slot_mask)
2885 return 0;
2886 val /= sizeof(u32);
2887 for (i = 0; i < val; i++)
2888 if (be32_to_cpup(&of_slot_mask[i]))
2889 *mask |= (1 << i);
2890
2891 return val;
2892}
2893EXPORT_SYMBOL_GPL(snd_soc_of_get_slot_mask);
2894
2895int snd_soc_of_parse_tdm_slot(struct device_node *np,
2896 unsigned int *tx_mask,
2897 unsigned int *rx_mask,
2898 unsigned int *slots,
2899 unsigned int *slot_width)
2900{
2901 u32 val;
2902 int ret;
2903
2904 if (tx_mask)
2905 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-tx-mask", tx_mask);
2906 if (rx_mask)
2907 snd_soc_of_get_slot_mask(np, "dai-tdm-slot-rx-mask", rx_mask);
2908
2909 if (of_property_read_bool(np, "dai-tdm-slot-num")) {
2910 ret = of_property_read_u32(np, "dai-tdm-slot-num", &val);
2911 if (ret)
2912 return ret;
2913
2914 if (slots)
2915 *slots = val;
2916 }
2917
2918 if (of_property_read_bool(np, "dai-tdm-slot-width")) {
2919 ret = of_property_read_u32(np, "dai-tdm-slot-width", &val);
2920 if (ret)
2921 return ret;
2922
2923 if (slot_width)
2924 *slot_width = val;
2925 }
2926
2927 return 0;
2928}
2929EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
2930
2931void snd_soc_of_parse_node_prefix(struct device_node *np,
2932 struct snd_soc_codec_conf *codec_conf,
2933 struct device_node *of_node,
2934 const char *propname)
2935{
2936 const char *str;
2937 int ret;
2938
2939 ret = of_property_read_string(np, propname, &str);
2940 if (ret < 0) {
2941
2942 return;
2943 }
2944
2945 codec_conf->dlc.of_node = of_node;
2946 codec_conf->name_prefix = str;
2947}
2948EXPORT_SYMBOL_GPL(snd_soc_of_parse_node_prefix);
2949
2950int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
2951 const char *propname)
2952{
2953 struct device_node *np = card->dev->of_node;
2954 int num_routes;
2955 struct snd_soc_dapm_route *routes;
2956 int i;
2957
2958 num_routes = of_property_count_strings(np, propname);
2959 if (num_routes < 0 || num_routes & 1) {
2960 dev_err(card->dev,
2961 "ASoC: Property '%s' does not exist or its length is not even\n",
2962 propname);
2963 return -EINVAL;
2964 }
2965 num_routes /= 2;
2966
2967 routes = devm_kcalloc(card->dev, num_routes, sizeof(*routes),
2968 GFP_KERNEL);
2969 if (!routes) {
2970 dev_err(card->dev,
2971 "ASoC: Could not allocate DAPM route table\n");
2972 return -ENOMEM;
2973 }
2974
2975 for (i = 0; i < num_routes; i++) {
2976 int ret = of_property_read_string_index(np, propname,
2977 2 * i, &routes[i].sink);
2978 if (ret) {
2979 dev_err(card->dev,
2980 "ASoC: Property '%s' index %d could not be read: %d\n",
2981 propname, 2 * i, ret);
2982 return -EINVAL;
2983 }
2984 ret = of_property_read_string_index(np, propname,
2985 (2 * i) + 1, &routes[i].source);
2986 if (ret) {
2987 dev_err(card->dev,
2988 "ASoC: Property '%s' index %d could not be read: %d\n",
2989 propname, (2 * i) + 1, ret);
2990 return -EINVAL;
2991 }
2992 }
2993
2994 card->num_of_dapm_routes = num_routes;
2995 card->of_dapm_routes = routes;
2996
2997 return 0;
2998}
2999EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
3000
3001int snd_soc_of_parse_aux_devs(struct snd_soc_card *card, const char *propname)
3002{
3003 struct device_node *node = card->dev->of_node;
3004 struct snd_soc_aux_dev *aux;
3005 int num, i;
3006
3007 num = of_count_phandle_with_args(node, propname, NULL);
3008 if (num == -ENOENT) {
3009 return 0;
3010 } else if (num < 0) {
3011 dev_err(card->dev, "ASOC: Property '%s' could not be read: %d\n",
3012 propname, num);
3013 return num;
3014 }
3015
3016 aux = devm_kcalloc(card->dev, num, sizeof(*aux), GFP_KERNEL);
3017 if (!aux)
3018 return -ENOMEM;
3019 card->aux_dev = aux;
3020 card->num_aux_devs = num;
3021
3022 for_each_card_pre_auxs(card, i, aux) {
3023 aux->dlc.of_node = of_parse_phandle(node, propname, i);
3024 if (!aux->dlc.of_node)
3025 return -EINVAL;
3026 }
3027
3028 return 0;
3029}
3030EXPORT_SYMBOL_GPL(snd_soc_of_parse_aux_devs);
3031
3032unsigned int snd_soc_daifmt_clock_provider_fliped(unsigned int dai_fmt)
3033{
3034 unsigned int inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK;
3035
3036 switch (dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
3037 case SND_SOC_DAIFMT_CBP_CFP:
3038 inv_dai_fmt |= SND_SOC_DAIFMT_CBC_CFC;
3039 break;
3040 case SND_SOC_DAIFMT_CBP_CFC:
3041 inv_dai_fmt |= SND_SOC_DAIFMT_CBC_CFP;
3042 break;
3043 case SND_SOC_DAIFMT_CBC_CFP:
3044 inv_dai_fmt |= SND_SOC_DAIFMT_CBP_CFC;
3045 break;
3046 case SND_SOC_DAIFMT_CBC_CFC:
3047 inv_dai_fmt |= SND_SOC_DAIFMT_CBP_CFP;
3048 break;
3049 }
3050
3051 return inv_dai_fmt;
3052}
3053EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_fliped);
3054
3055unsigned int snd_soc_daifmt_clock_provider_from_bitmap(unsigned int bit_frame)
3056{
3057
3058
3059
3060
3061
3062
3063 switch (bit_frame) {
3064 case 0x11:
3065 return SND_SOC_DAIFMT_CBP_CFP;
3066 case 0x10:
3067 return SND_SOC_DAIFMT_CBP_CFC;
3068 case 0x01:
3069 return SND_SOC_DAIFMT_CBC_CFP;
3070 default:
3071 return SND_SOC_DAIFMT_CBC_CFC;
3072 }
3073
3074 return 0;
3075}
3076EXPORT_SYMBOL_GPL(snd_soc_daifmt_clock_provider_from_bitmap);
3077
3078unsigned int snd_soc_daifmt_parse_format(struct device_node *np,
3079 const char *prefix)
3080{
3081 int ret;
3082 char prop[128];
3083 unsigned int format = 0;
3084 int bit, frame;
3085 const char *str;
3086 struct {
3087 char *name;
3088 unsigned int val;
3089 } of_fmt_table[] = {
3090 { "i2s", SND_SOC_DAIFMT_I2S },
3091 { "right_j", SND_SOC_DAIFMT_RIGHT_J },
3092 { "left_j", SND_SOC_DAIFMT_LEFT_J },
3093 { "dsp_a", SND_SOC_DAIFMT_DSP_A },
3094 { "dsp_b", SND_SOC_DAIFMT_DSP_B },
3095 { "ac97", SND_SOC_DAIFMT_AC97 },
3096 { "pdm", SND_SOC_DAIFMT_PDM},
3097 { "msb", SND_SOC_DAIFMT_MSB },
3098 { "lsb", SND_SOC_DAIFMT_LSB },
3099 };
3100
3101 if (!prefix)
3102 prefix = "";
3103
3104
3105
3106
3107
3108
3109 ret = of_property_read_string(np, "dai-format", &str);
3110 if (ret < 0) {
3111 snprintf(prop, sizeof(prop), "%sformat", prefix);
3112 ret = of_property_read_string(np, prop, &str);
3113 }
3114 if (ret == 0) {
3115 int i;
3116
3117 for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
3118 if (strcmp(str, of_fmt_table[i].name) == 0) {
3119 format |= of_fmt_table[i].val;
3120 break;
3121 }
3122 }
3123 }
3124
3125
3126
3127
3128
3129 snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix);
3130 if (of_property_read_bool(np, prop))
3131 format |= SND_SOC_DAIFMT_CONT;
3132 else
3133 format |= SND_SOC_DAIFMT_GATED;
3134
3135
3136
3137
3138
3139
3140 snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);
3141 bit = !!of_get_property(np, prop, NULL);
3142
3143 snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);
3144 frame = !!of_get_property(np, prop, NULL);
3145
3146 switch ((bit << 4) + frame) {
3147 case 0x11:
3148 format |= SND_SOC_DAIFMT_IB_IF;
3149 break;
3150 case 0x10:
3151 format |= SND_SOC_DAIFMT_IB_NF;
3152 break;
3153 case 0x01:
3154 format |= SND_SOC_DAIFMT_NB_IF;
3155 break;
3156 default:
3157
3158 break;
3159 }
3160
3161 return format;
3162}
3163EXPORT_SYMBOL_GPL(snd_soc_daifmt_parse_format);
3164
3165unsigned int snd_soc_daifmt_parse_clock_provider_raw(struct device_node *np,
3166 const char *prefix,
3167 struct device_node **bitclkmaster,
3168 struct device_node **framemaster)
3169{
3170 char prop[128];
3171 unsigned int bit, frame;
3172
3173 if (!prefix)
3174 prefix = "";
3175
3176
3177
3178
3179
3180 snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
3181 bit = !!of_get_property(np, prop, NULL);
3182 if (bit && bitclkmaster)
3183 *bitclkmaster = of_parse_phandle(np, prop, 0);
3184
3185 snprintf(prop, sizeof(prop), "%sframe-master", prefix);
3186 frame = !!of_get_property(np, prop, NULL);
3187 if (frame && framemaster)
3188 *framemaster = of_parse_phandle(np, prop, 0);
3189
3190
3191
3192
3193
3194
3195 return (bit << 4) + frame;
3196}
3197EXPORT_SYMBOL_GPL(snd_soc_daifmt_parse_clock_provider_raw);
3198
3199int snd_soc_get_dai_id(struct device_node *ep)
3200{
3201 struct snd_soc_component *component;
3202 struct snd_soc_dai_link_component dlc;
3203 int ret;
3204
3205 dlc.of_node = of_graph_get_port_parent(ep);
3206 dlc.name = NULL;
3207
3208
3209
3210
3211
3212
3213 ret = -ENOTSUPP;
3214 mutex_lock(&client_mutex);
3215 component = soc_find_component(&dlc);
3216 if (component)
3217 ret = snd_soc_component_of_xlate_dai_id(component, ep);
3218 mutex_unlock(&client_mutex);
3219
3220 of_node_put(dlc.of_node);
3221
3222 return ret;
3223}
3224EXPORT_SYMBOL_GPL(snd_soc_get_dai_id);
3225
3226int snd_soc_get_dai_name(const struct of_phandle_args *args,
3227 const char **dai_name)
3228{
3229 struct snd_soc_component *pos;
3230 int ret = -EPROBE_DEFER;
3231
3232 mutex_lock(&client_mutex);
3233 for_each_component(pos) {
3234 struct device_node *component_of_node = soc_component_to_node(pos);
3235
3236 if (component_of_node != args->np)
3237 continue;
3238
3239 ret = snd_soc_component_of_xlate_dai_name(pos, args, dai_name);
3240 if (ret == -ENOTSUPP) {
3241 struct snd_soc_dai *dai;
3242 int id = -1;
3243
3244 switch (args->args_count) {
3245 case 0:
3246 id = 0;
3247 break;
3248 case 1:
3249 id = args->args[0];
3250 break;
3251 default:
3252
3253 break;
3254 }
3255
3256 if (id < 0 || id >= pos->num_dai) {
3257 ret = -EINVAL;
3258 continue;
3259 }
3260
3261 ret = 0;
3262
3263
3264 for_each_component_dais(pos, dai) {
3265 if (id == 0)
3266 break;
3267 id--;
3268 }
3269
3270 *dai_name = dai->driver->name;
3271 if (!*dai_name)
3272 *dai_name = pos->name;
3273 } else if (ret) {
3274
3275
3276
3277
3278
3279
3280 continue;
3281 }
3282
3283 break;
3284 }
3285 mutex_unlock(&client_mutex);
3286 return ret;
3287}
3288EXPORT_SYMBOL_GPL(snd_soc_get_dai_name);
3289
3290int snd_soc_of_get_dai_name(struct device_node *of_node,
3291 const char **dai_name)
3292{
3293 struct of_phandle_args args;
3294 int ret;
3295
3296 ret = of_parse_phandle_with_args(of_node, "sound-dai",
3297 "#sound-dai-cells", 0, &args);
3298 if (ret)
3299 return ret;
3300
3301 ret = snd_soc_get_dai_name(&args, dai_name);
3302
3303 of_node_put(args.np);
3304
3305 return ret;
3306}
3307EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
3308
3309
3310
3311
3312
3313
3314
3315void snd_soc_of_put_dai_link_codecs(struct snd_soc_dai_link *dai_link)
3316{
3317 struct snd_soc_dai_link_component *component;
3318 int index;
3319
3320 for_each_link_codecs(dai_link, index, component) {
3321 if (!component->of_node)
3322 break;
3323 of_node_put(component->of_node);
3324 component->of_node = NULL;
3325 }
3326}
3327EXPORT_SYMBOL_GPL(snd_soc_of_put_dai_link_codecs);
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343int snd_soc_of_get_dai_link_codecs(struct device *dev,
3344 struct device_node *of_node,
3345 struct snd_soc_dai_link *dai_link)
3346{
3347 struct of_phandle_args args;
3348 struct snd_soc_dai_link_component *component;
3349 char *name;
3350 int index, num_codecs, ret;
3351
3352
3353 name = "sound-dai";
3354 num_codecs = of_count_phandle_with_args(of_node, name,
3355 "#sound-dai-cells");
3356 if (num_codecs <= 0) {
3357 if (num_codecs == -ENOENT)
3358 dev_err(dev, "No 'sound-dai' property\n");
3359 else
3360 dev_err(dev, "Bad phandle in 'sound-dai'\n");
3361 return num_codecs;
3362 }
3363 component = devm_kcalloc(dev,
3364 num_codecs, sizeof(*component),
3365 GFP_KERNEL);
3366 if (!component)
3367 return -ENOMEM;
3368 dai_link->codecs = component;
3369 dai_link->num_codecs = num_codecs;
3370
3371
3372 for_each_link_codecs(dai_link, index, component) {
3373 ret = of_parse_phandle_with_args(of_node, name,
3374 "#sound-dai-cells",
3375 index, &args);
3376 if (ret)
3377 goto err;
3378 component->of_node = args.np;
3379 ret = snd_soc_get_dai_name(&args, &component->dai_name);
3380 if (ret < 0)
3381 goto err;
3382 }
3383 return 0;
3384err:
3385 snd_soc_of_put_dai_link_codecs(dai_link);
3386 dai_link->codecs = NULL;
3387 dai_link->num_codecs = 0;
3388 return ret;
3389}
3390EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);
3391
3392static int __init snd_soc_init(void)
3393{
3394 snd_soc_debugfs_init();
3395 snd_soc_util_init();
3396
3397 return platform_driver_register(&soc_driver);
3398}
3399module_init(snd_soc_init);
3400
3401static void __exit snd_soc_exit(void)
3402{
3403 snd_soc_util_exit();
3404 snd_soc_debugfs_exit();
3405
3406 platform_driver_unregister(&soc_driver);
3407}
3408module_exit(snd_soc_exit);
3409
3410
3411MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
3412MODULE_DESCRIPTION("ALSA SoC Core");
3413MODULE_LICENSE("GPL");
3414MODULE_ALIAS("platform:soc-audio");
3415