forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/sound/soc/meson/axg-card.c
....@@ -9,11 +9,7 @@
99 #include <sound/soc-dai.h>
1010
1111 #include "axg-tdm.h"
12
-
13
-struct axg_card {
14
- struct snd_soc_card card;
15
- void **link_data;
16
-};
12
+#include "meson-card.h"
1713
1814 struct axg_dai_link_tdm_mask {
1915 u32 tx;
....@@ -29,159 +25,27 @@
2925 struct axg_dai_link_tdm_mask *codec_masks;
3026 };
3127
32
-#define PREFIX "amlogic,"
33
-
34
-static int axg_card_reallocate_links(struct axg_card *priv,
35
- unsigned int num_links)
36
-{
37
- struct snd_soc_dai_link *links;
38
- void **ldata;
39
-
40
- links = krealloc(priv->card.dai_link,
41
- num_links * sizeof(*priv->card.dai_link),
42
- GFP_KERNEL | __GFP_ZERO);
43
- ldata = krealloc(priv->link_data,
44
- num_links * sizeof(*priv->link_data),
45
- GFP_KERNEL | __GFP_ZERO);
46
-
47
- if (!links || !ldata) {
48
- dev_err(priv->card.dev, "failed to allocate links\n");
49
- return -ENOMEM;
50
- }
51
-
52
- priv->card.dai_link = links;
53
- priv->link_data = ldata;
54
- priv->card.num_links = num_links;
55
- return 0;
56
-}
57
-
58
-static int axg_card_parse_dai(struct snd_soc_card *card,
59
- struct device_node *node,
60
- struct device_node **dai_of_node,
61
- const char **dai_name)
62
-{
63
- struct of_phandle_args args;
64
- int ret;
65
-
66
- if (!dai_name || !dai_of_node || !node)
67
- return -EINVAL;
68
-
69
- ret = of_parse_phandle_with_args(node, "sound-dai",
70
- "#sound-dai-cells", 0, &args);
71
- if (ret) {
72
- if (ret != -EPROBE_DEFER)
73
- dev_err(card->dev, "can't parse dai %d\n", ret);
74
- return ret;
75
- }
76
- *dai_of_node = args.np;
77
-
78
- return snd_soc_get_dai_name(&args, dai_name);
79
-}
80
-
81
-static int axg_card_set_link_name(struct snd_soc_card *card,
82
- struct snd_soc_dai_link *link,
83
- const char *prefix)
84
-{
85
- char *name = devm_kasprintf(card->dev, GFP_KERNEL, "%s.%s",
86
- prefix, link->cpu_of_node->full_name);
87
- if (!name)
88
- return -ENOMEM;
89
-
90
- link->name = name;
91
- link->stream_name = name;
92
-
93
- return 0;
94
-}
95
-
96
-static void axg_card_clean_references(struct axg_card *priv)
97
-{
98
- struct snd_soc_card *card = &priv->card;
99
- struct snd_soc_dai_link *link;
100
- int i, j;
101
-
102
- if (card->dai_link) {
103
- for (i = 0; i < card->num_links; i++) {
104
- link = &card->dai_link[i];
105
- of_node_put(link->cpu_of_node);
106
- for (j = 0; j < link->num_codecs; j++)
107
- of_node_put(link->codecs[j].of_node);
108
- }
109
- }
110
-
111
- if (card->aux_dev) {
112
- for (i = 0; i < card->num_aux_devs; i++)
113
- of_node_put(card->aux_dev[i].codec_of_node);
114
- }
115
-
116
- kfree(card->dai_link);
117
- kfree(priv->link_data);
118
-}
119
-
120
-static int axg_card_add_aux_devices(struct snd_soc_card *card)
121
-{
122
- struct device_node *node = card->dev->of_node;
123
- struct snd_soc_aux_dev *aux;
124
- int num, i;
125
-
126
- num = of_count_phandle_with_args(node, "audio-aux-devs", NULL);
127
- if (num == -ENOENT) {
128
- /*
129
- * It is ok to have no auxiliary devices but for this card it
130
- * is a strange situtation. Let's warn the about it.
131
- */
132
- dev_warn(card->dev, "card has no auxiliary devices\n");
133
- return 0;
134
- } else if (num < 0) {
135
- dev_err(card->dev, "error getting auxiliary devices: %d\n",
136
- num);
137
- return num;
138
- }
139
-
140
- aux = devm_kcalloc(card->dev, num, sizeof(*aux), GFP_KERNEL);
141
- if (!aux)
142
- return -ENOMEM;
143
- card->aux_dev = aux;
144
- card->num_aux_devs = num;
145
-
146
- for (i = 0; i < card->num_aux_devs; i++, aux++) {
147
- aux->codec_of_node =
148
- of_parse_phandle(node, "audio-aux-devs", i);
149
- if (!aux->codec_of_node)
150
- return -EINVAL;
151
- }
152
-
153
- return 0;
154
-}
28
+/*
29
+ * Base params for the codec to codec links
30
+ * Those will be over-written by the CPU side of the link
31
+ */
32
+static const struct snd_soc_pcm_stream codec_params = {
33
+ .formats = SNDRV_PCM_FMTBIT_S24_LE,
34
+ .rate_min = 5525,
35
+ .rate_max = 192000,
36
+ .channels_min = 1,
37
+ .channels_max = 8,
38
+};
15539
15640 static int axg_card_tdm_be_hw_params(struct snd_pcm_substream *substream,
15741 struct snd_pcm_hw_params *params)
15842 {
159
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
160
- struct axg_card *priv = snd_soc_card_get_drvdata(rtd->card);
43
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
44
+ struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card);
16145 struct axg_dai_link_tdm_data *be =
16246 (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num];
163
- struct snd_soc_dai *codec_dai;
164
- unsigned int mclk;
165
- int ret, i;
16647
167
- if (be->mclk_fs) {
168
- mclk = params_rate(params) * be->mclk_fs;
169
-
170
- for (i = 0; i < rtd->num_codecs; i++) {
171
- codec_dai = rtd->codec_dais[i];
172
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
173
- SND_SOC_CLOCK_IN);
174
- if (ret && ret != -ENOTSUPP)
175
- return ret;
176
- }
177
-
178
- ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk,
179
- SND_SOC_CLOCK_OUT);
180
- if (ret && ret != -ENOTSUPP)
181
- return ret;
182
- }
183
-
184
- return 0;
48
+ return meson_card_i2s_set_sysclk(substream, params, be->mclk_fs);
18549 }
18650
18751 static const struct snd_soc_ops axg_card_tdm_be_ops = {
....@@ -190,14 +54,13 @@
19054
19155 static int axg_card_tdm_dai_init(struct snd_soc_pcm_runtime *rtd)
19256 {
193
- struct axg_card *priv = snd_soc_card_get_drvdata(rtd->card);
57
+ struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card);
19458 struct axg_dai_link_tdm_data *be =
19559 (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num];
19660 struct snd_soc_dai *codec_dai;
19761 int ret, i;
19862
199
- for (i = 0; i < rtd->num_codecs; i++) {
200
- codec_dai = rtd->codec_dais[i];
63
+ for_each_rtd_codec_dais(rtd, i, codec_dai) {
20164 ret = snd_soc_dai_set_tdm_slot(codec_dai,
20265 be->codec_masks[i].tx,
20366 be->codec_masks[i].rx,
....@@ -209,10 +72,10 @@
20972 }
21073 }
21174
212
- ret = axg_tdm_set_tdm_slots(rtd->cpu_dai, be->tx_mask, be->rx_mask,
75
+ ret = axg_tdm_set_tdm_slots(asoc_rtd_to_cpu(rtd, 0), be->tx_mask, be->rx_mask,
21376 be->slots, be->slot_width);
21477 if (ret) {
215
- dev_err(rtd->cpu_dai->dev, "setting tdm link slots failed\n");
78
+ dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "setting tdm link slots failed\n");
21679 return ret;
21780 }
21881
....@@ -221,16 +84,16 @@
22184
22285 static int axg_card_tdm_dai_lb_init(struct snd_soc_pcm_runtime *rtd)
22386 {
224
- struct axg_card *priv = snd_soc_card_get_drvdata(rtd->card);
87
+ struct meson_card *priv = snd_soc_card_get_drvdata(rtd->card);
22588 struct axg_dai_link_tdm_data *be =
22689 (struct axg_dai_link_tdm_data *)priv->link_data[rtd->num];
22790 int ret;
22891
22992 /* The loopback rx_mask is the pad tx_mask */
230
- ret = axg_tdm_set_tdm_slots(rtd->cpu_dai, NULL, be->tx_mask,
93
+ ret = axg_tdm_set_tdm_slots(asoc_rtd_to_cpu(rtd, 0), NULL, be->tx_mask,
23194 be->slots, be->slot_width);
23295 if (ret) {
233
- dev_err(rtd->cpu_dai->dev, "setting tdm link slots failed\n");
96
+ dev_err(asoc_rtd_to_cpu(rtd, 0)->dev, "setting tdm link slots failed\n");
23497 return ret;
23598 }
23699
....@@ -240,27 +103,37 @@
240103 static int axg_card_add_tdm_loopback(struct snd_soc_card *card,
241104 int *index)
242105 {
243
- struct axg_card *priv = snd_soc_card_get_drvdata(card);
106
+ struct meson_card *priv = snd_soc_card_get_drvdata(card);
244107 struct snd_soc_dai_link *pad = &card->dai_link[*index];
245108 struct snd_soc_dai_link *lb;
109
+ struct snd_soc_dai_link_component *dlc;
246110 int ret;
247111
248112 /* extend links */
249
- ret = axg_card_reallocate_links(priv, card->num_links + 1);
113
+ ret = meson_card_reallocate_links(card, card->num_links + 1);
250114 if (ret)
251115 return ret;
252116
253117 lb = &card->dai_link[*index + 1];
254118
255
- lb->name = kasprintf(GFP_KERNEL, "%s-lb", pad->name);
119
+ lb->name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-lb", pad->name);
256120 if (!lb->name)
257121 return -ENOMEM;
258122
123
+ dlc = devm_kzalloc(card->dev, 2 * sizeof(*dlc), GFP_KERNEL);
124
+ if (!dlc)
125
+ return -ENOMEM;
126
+
127
+ lb->cpus = &dlc[0];
128
+ lb->codecs = &dlc[1];
129
+ lb->num_cpus = 1;
130
+ lb->num_codecs = 1;
131
+
259132 lb->stream_name = lb->name;
260
- lb->cpu_of_node = pad->cpu_of_node;
261
- lb->cpu_dai_name = "TDM Loopback";
262
- lb->codec_name = "snd-soc-dummy";
263
- lb->codec_dai_name = "snd-soc-dummy-dai";
133
+ lb->cpus->of_node = pad->cpus->of_node;
134
+ lb->cpus->dai_name = "TDM Loopback";
135
+ lb->codecs->name = "snd-soc-dummy";
136
+ lb->codecs->dai_name = "snd-soc-dummy-dai";
264137 lb->dpcm_capture = 1;
265138 lb->no_pcm = 1;
266139 lb->ops = &axg_card_tdm_be_ops;
....@@ -273,38 +146,12 @@
273146 * axg_card_clean_references() will iterate over this link,
274147 * make sure the node count is balanced
275148 */
276
- of_node_get(lb->cpu_of_node);
149
+ of_node_get(lb->cpus->of_node);
277150
278151 /* Let add_links continue where it should */
279152 *index += 1;
280153
281154 return 0;
282
-}
283
-
284
-static unsigned int axg_card_parse_daifmt(struct device_node *node,
285
- struct device_node *cpu_node)
286
-{
287
- struct device_node *bitclkmaster = NULL;
288
- struct device_node *framemaster = NULL;
289
- unsigned int daifmt;
290
-
291
- daifmt = snd_soc_of_parse_daifmt(node, PREFIX,
292
- &bitclkmaster, &framemaster);
293
- daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
294
-
295
- /* If no master is provided, default to cpu master */
296
- if (!bitclkmaster || bitclkmaster == cpu_node) {
297
- daifmt |= (!framemaster || framemaster == cpu_node) ?
298
- SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBS_CFM;
299
- } else {
300
- daifmt |= (!framemaster || framemaster == cpu_node) ?
301
- SND_SOC_DAIFMT_CBM_CFS : SND_SOC_DAIFMT_CBM_CFM;
302
- }
303
-
304
- of_node_put(bitclkmaster);
305
- of_node_put(framemaster);
306
-
307
- return daifmt;
308155 }
309156
310157 static int axg_card_parse_cpu_tdm_slots(struct snd_soc_card *card,
....@@ -401,7 +248,7 @@
401248 struct device_node *node,
402249 int *index)
403250 {
404
- struct axg_card *priv = snd_soc_card_get_drvdata(card);
251
+ struct meson_card *priv = snd_soc_card_get_drvdata(card);
405252 struct snd_soc_dai_link *link = &card->dai_link[*index];
406253 struct axg_dai_link_tdm_data *be;
407254 int ret;
....@@ -415,7 +262,7 @@
415262 /* Setup tdm link */
416263 link->ops = &axg_card_tdm_be_ops;
417264 link->init = axg_card_tdm_dai_init;
418
- link->dai_fmt = axg_card_parse_daifmt(node, link->cpu_of_node);
265
+ link->dai_fmt = meson_card_parse_daifmt(node, link->cpus->of_node);
419266
420267 of_property_read_u32(node, "mclk-fs", &be->mclk_fs);
421268
....@@ -439,226 +286,83 @@
439286 return 0;
440287 }
441288
442
-static int axg_card_set_be_link(struct snd_soc_card *card,
443
- struct snd_soc_dai_link *link,
444
- struct device_node *node)
445
-{
446
- struct snd_soc_dai_link_component *codec;
447
- struct device_node *np;
448
- int ret, num_codecs;
449
-
450
- link->no_pcm = 1;
451
- link->dpcm_playback = 1;
452
- link->dpcm_capture = 1;
453
-
454
- num_codecs = of_get_child_count(node);
455
- if (!num_codecs) {
456
- dev_err(card->dev, "be link %s has no codec\n",
457
- node->full_name);
458
- return -EINVAL;
459
- }
460
-
461
- codec = devm_kcalloc(card->dev, num_codecs, sizeof(*codec), GFP_KERNEL);
462
- if (!codec)
463
- return -ENOMEM;
464
-
465
- link->codecs = codec;
466
- link->num_codecs = num_codecs;
467
-
468
- for_each_child_of_node(node, np) {
469
- ret = axg_card_parse_dai(card, np, &codec->of_node,
470
- &codec->dai_name);
471
- if (ret) {
472
- of_node_put(np);
473
- return ret;
474
- }
475
-
476
- codec++;
477
- }
478
-
479
- ret = axg_card_set_link_name(card, link, "be");
480
- if (ret)
481
- dev_err(card->dev, "error setting %s link name\n", np->name);
482
-
483
- return ret;
484
-}
485
-
486
-static int axg_card_set_fe_link(struct snd_soc_card *card,
487
- struct snd_soc_dai_link *link,
488
- bool is_playback)
489
-{
490
- link->dynamic = 1;
491
- link->dpcm_merged_format = 1;
492
- link->dpcm_merged_chan = 1;
493
- link->dpcm_merged_rate = 1;
494
- link->codec_dai_name = "snd-soc-dummy-dai";
495
- link->codec_name = "snd-soc-dummy";
496
-
497
- if (is_playback)
498
- link->dpcm_playback = 1;
499
- else
500
- link->dpcm_capture = 1;
501
-
502
- return axg_card_set_link_name(card, link, "fe");
503
-}
504
-
505289 static int axg_card_cpu_is_capture_fe(struct device_node *np)
506290 {
507
- return of_device_is_compatible(np, PREFIX "axg-toddr");
291
+ return of_device_is_compatible(np, DT_PREFIX "axg-toddr");
508292 }
509293
510294 static int axg_card_cpu_is_playback_fe(struct device_node *np)
511295 {
512
- return of_device_is_compatible(np, PREFIX "axg-frddr");
296
+ return of_device_is_compatible(np, DT_PREFIX "axg-frddr");
513297 }
514298
515299 static int axg_card_cpu_is_tdm_iface(struct device_node *np)
516300 {
517
- return of_device_is_compatible(np, PREFIX "axg-tdm-iface");
301
+ return of_device_is_compatible(np, DT_PREFIX "axg-tdm-iface");
302
+}
303
+
304
+static int axg_card_cpu_is_codec(struct device_node *np)
305
+{
306
+ return of_device_is_compatible(np, DT_PREFIX "g12a-tohdmitx") ||
307
+ of_device_is_compatible(np, DT_PREFIX "g12a-toacodec");
518308 }
519309
520310 static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,
521311 int *index)
522312 {
523313 struct snd_soc_dai_link *dai_link = &card->dai_link[*index];
314
+ struct snd_soc_dai_link_component *cpu;
524315 int ret;
525316
526
- ret = axg_card_parse_dai(card, np, &dai_link->cpu_of_node,
527
- &dai_link->cpu_dai_name);
317
+ cpu = devm_kzalloc(card->dev, sizeof(*cpu), GFP_KERNEL);
318
+ if (!cpu)
319
+ return -ENOMEM;
320
+
321
+ dai_link->cpus = cpu;
322
+ dai_link->num_cpus = 1;
323
+
324
+ ret = meson_card_parse_dai(card, np, &dai_link->cpus->of_node,
325
+ &dai_link->cpus->dai_name);
528326 if (ret)
529327 return ret;
530328
531
- if (axg_card_cpu_is_playback_fe(dai_link->cpu_of_node))
532
- ret = axg_card_set_fe_link(card, dai_link, true);
533
- else if (axg_card_cpu_is_capture_fe(dai_link->cpu_of_node))
534
- ret = axg_card_set_fe_link(card, dai_link, false);
535
- else
536
- ret = axg_card_set_be_link(card, dai_link, np);
329
+ if (axg_card_cpu_is_playback_fe(dai_link->cpus->of_node))
330
+ return meson_card_set_fe_link(card, dai_link, np, true);
331
+ else if (axg_card_cpu_is_capture_fe(dai_link->cpus->of_node))
332
+ return meson_card_set_fe_link(card, dai_link, np, false);
537333
334
+
335
+ ret = meson_card_set_be_link(card, dai_link, np);
538336 if (ret)
539337 return ret;
540338
541
- if (axg_card_cpu_is_tdm_iface(dai_link->cpu_of_node))
542
- ret = axg_card_parse_tdm(card, np, index);
339
+ if (axg_card_cpu_is_codec(dai_link->cpus->of_node)) {
340
+ dai_link->params = &codec_params;
341
+ } else {
342
+ dai_link->no_pcm = 1;
343
+ snd_soc_dai_link_set_capabilities(dai_link);
344
+ if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node))
345
+ ret = axg_card_parse_tdm(card, np, index);
346
+ }
543347
544348 return ret;
545349 }
546350
547
-static int axg_card_add_links(struct snd_soc_card *card)
548
-{
549
- struct axg_card *priv = snd_soc_card_get_drvdata(card);
550
- struct device_node *node = card->dev->of_node;
551
- struct device_node *np;
552
- int num, i, ret;
553
-
554
- num = of_get_child_count(node);
555
- if (!num) {
556
- dev_err(card->dev, "card has no links\n");
557
- return -EINVAL;
558
- }
559
-
560
- ret = axg_card_reallocate_links(priv, num);
561
- if (ret)
562
- return ret;
563
-
564
- i = 0;
565
- for_each_child_of_node(node, np) {
566
- ret = axg_card_add_link(card, np, &i);
567
- if (ret) {
568
- of_node_put(np);
569
- return ret;
570
- }
571
-
572
- i++;
573
- }
574
-
575
- return 0;
576
-}
577
-
578
-static int axg_card_parse_of_optional(struct snd_soc_card *card,
579
- const char *propname,
580
- int (*func)(struct snd_soc_card *c,
581
- const char *p))
582
-{
583
- /* If property is not provided, don't fail ... */
584
- if (!of_property_read_bool(card->dev->of_node, propname))
585
- return 0;
586
-
587
- /* ... but do fail if it is provided and the parsing fails */
588
- return func(card, propname);
589
-}
351
+static const struct meson_card_match_data axg_card_match_data = {
352
+ .add_link = axg_card_add_link,
353
+};
590354
591355 static const struct of_device_id axg_card_of_match[] = {
592
- { .compatible = "amlogic,axg-sound-card", },
593
- {}
356
+ {
357
+ .compatible = "amlogic,axg-sound-card",
358
+ .data = &axg_card_match_data,
359
+ }, {}
594360 };
595361 MODULE_DEVICE_TABLE(of, axg_card_of_match);
596362
597
-static int axg_card_probe(struct platform_device *pdev)
598
-{
599
- struct device *dev = &pdev->dev;
600
- struct axg_card *priv;
601
- int ret;
602
-
603
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
604
- if (!priv)
605
- return -ENOMEM;
606
-
607
- platform_set_drvdata(pdev, priv);
608
- snd_soc_card_set_drvdata(&priv->card, priv);
609
-
610
- priv->card.owner = THIS_MODULE;
611
- priv->card.dev = dev;
612
-
613
- ret = snd_soc_of_parse_card_name(&priv->card, "model");
614
- if (ret < 0)
615
- return ret;
616
-
617
- ret = axg_card_parse_of_optional(&priv->card, "audio-routing",
618
- snd_soc_of_parse_audio_routing);
619
- if (ret) {
620
- dev_err(dev, "error while parsing routing\n");
621
- return ret;
622
- }
623
-
624
- ret = axg_card_parse_of_optional(&priv->card, "audio-widgets",
625
- snd_soc_of_parse_audio_simple_widgets);
626
- if (ret) {
627
- dev_err(dev, "error while parsing widgets\n");
628
- return ret;
629
- }
630
-
631
- ret = axg_card_add_links(&priv->card);
632
- if (ret)
633
- goto out_err;
634
-
635
- ret = axg_card_add_aux_devices(&priv->card);
636
- if (ret)
637
- goto out_err;
638
-
639
- ret = devm_snd_soc_register_card(dev, &priv->card);
640
- if (ret)
641
- goto out_err;
642
-
643
- return 0;
644
-
645
-out_err:
646
- axg_card_clean_references(priv);
647
- return ret;
648
-}
649
-
650
-static int axg_card_remove(struct platform_device *pdev)
651
-{
652
- struct axg_card *priv = platform_get_drvdata(pdev);
653
-
654
- axg_card_clean_references(priv);
655
-
656
- return 0;
657
-}
658
-
659363 static struct platform_driver axg_card_pdrv = {
660
- .probe = axg_card_probe,
661
- .remove = axg_card_remove,
364
+ .probe = meson_card_probe,
365
+ .remove = meson_card_remove,
662366 .driver = {
663367 .name = "axg-sound-card",
664368 .of_match_table = axg_card_of_match,