1
2
3
4#include <linux/module.h>
5#include <linux/init.h>
6#include <linux/slab.h>
7#include <linux/gpio/consumer.h>
8#include <linux/of_device.h>
9#include <linux/i2c.h>
10#include <linux/of_gpio.h>
11#include <linux/clk.h>
12#include <sound/soc.h>
13#include <sound/pcm_params.h>
14#include <sound/pcm.h>
15#include <sound/soc-dapm.h>
16#include <sound/simple_card_utils.h>
17
18#include "fsl_sai.h"
19
20enum codec_type {
21 CODEC_DUMMY = 0,
22 CODEC_AK5558 = 1,
23 CODEC_AK4458,
24 CODEC_AK4497,
25 CODEC_AK5552,
26};
27
28
29
30
31
32
33
34
35struct imx_akcodec_fs_mul {
36 unsigned int rmin;
37 unsigned int rmax;
38 unsigned int wmin;
39 unsigned int wmax;
40};
41
42
43
44
45struct imx_akcodec_tdm_fs_mul {
46 unsigned int min;
47 unsigned int max;
48 unsigned int mul;
49};
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68struct imx_card_plat_data {
69 struct imx_akcodec_fs_mul *fs_mul;
70 struct imx_akcodec_tdm_fs_mul *tdm_fs_mul;
71 const u32 *support_rates;
72 const u32 *support_tdm_rates;
73 const u32 *support_channels;
74 const u32 *support_tdm_channels;
75 unsigned int num_fs_mul;
76 unsigned int num_tdm_fs_mul;
77 unsigned int num_rates;
78 unsigned int num_tdm_rates;
79 unsigned int num_channels;
80 unsigned int num_tdm_channels;
81 unsigned int num_codecs;
82 enum codec_type type;
83};
84
85
86
87
88
89
90
91
92
93struct dai_link_data {
94 unsigned int slots;
95 unsigned int slot_width;
96 unsigned int cpu_sysclk_id;
97 bool one2one_ratio;
98};
99
100
101
102
103
104
105
106
107
108
109
110
111struct imx_card_data {
112 struct imx_card_plat_data *plat_data;
113 struct snd_soc_dapm_route *dapm_routes;
114 struct dai_link_data *link_data;
115 struct snd_soc_card card;
116 int num_dapm_routes;
117 u32 asrc_rate;
118 u32 asrc_format;
119};
120
121static struct imx_akcodec_fs_mul ak4458_fs_mul[] = {
122
123 { .rmin = 8000, .rmax = 24000, .wmin = 256, .wmax = 1024, },
124
125 { .rmin = 32000, .rmax = 32000, .wmin = 256, .wmax = 1024, },
126
127 { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 768, },
128
129 { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 512, },
130
131 { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 256, },
132
133 { .rmin = 352800, .rmax = 384000, .wmin = 32, .wmax = 128, },
134
135 { .rmin = 705600, .rmax = 768000, .wmin = 16, .wmax = 64, },
136};
137
138static struct imx_akcodec_tdm_fs_mul ak4458_tdm_fs_mul[] = {
139
140
141
142
143
144 { .min = 128, .max = 128, .mul = 256 },
145 { .min = 256, .max = 256, .mul = 512 },
146 { .min = 512, .max = 512, .mul = 1024 },
147};
148
149static struct imx_akcodec_fs_mul ak4497_fs_mul[] = {
150
151
152
153
154 { .rmin = 8000, .rmax = 32000, .wmin = 256, .wmax = 1024, },
155 { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 512, },
156 { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, },
157 { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, },
158 { .rmin = 352800, .rmax = 384000, .wmin = 128, .wmax = 128, },
159 { .rmin = 705600, .rmax = 768000, .wmin = 64, .wmax = 64, },
160};
161
162
163
164
165
166static struct imx_akcodec_fs_mul ak5558_fs_mul[] = {
167 { .rmin = 8000, .rmax = 32000, .wmin = 512, .wmax = 1024, },
168 { .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, },
169 { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, },
170 { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, },
171 { .rmin = 352800, .rmax = 384000, .wmin = 64, .wmax = 64, },
172 { .rmin = 705600, .rmax = 768000, .wmin = 32, .wmax = 32, },
173};
174
175
176
177
178
179
180static struct imx_akcodec_tdm_fs_mul ak5558_tdm_fs_mul[] = {
181 { .min = 128, .max = 128, .mul = 256 },
182 { .min = 256, .max = 256, .mul = 512 },
183 { .min = 512, .max = 512, .mul = 1024 },
184};
185
186static const u32 akcodec_rates[] = {
187 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
188 96000, 176400, 192000, 352800, 384000, 705600, 768000,
189};
190
191static const u32 akcodec_tdm_rates[] = {
192 8000, 16000, 32000, 48000, 96000,
193};
194
195static const u32 ak4458_channels[] = {
196 1, 2, 4, 6, 8, 10, 12, 14, 16,
197};
198
199static const u32 ak4458_tdm_channels[] = {
200 1, 2, 3, 4, 5, 6, 7, 8, 16,
201};
202
203static const u32 ak5558_channels[] = {
204 1, 2, 4, 6, 8,
205};
206
207static const u32 ak5558_tdm_channels[] = {
208 1, 2, 3, 4, 5, 6, 7, 8,
209};
210
211static bool format_is_dsd(struct snd_pcm_hw_params *params)
212{
213 snd_pcm_format_t format = params_format(params);
214
215 switch (format) {
216 case SNDRV_PCM_FORMAT_DSD_U8:
217 case SNDRV_PCM_FORMAT_DSD_U16_LE:
218 case SNDRV_PCM_FORMAT_DSD_U16_BE:
219 case SNDRV_PCM_FORMAT_DSD_U32_LE:
220 case SNDRV_PCM_FORMAT_DSD_U32_BE:
221 return true;
222 default:
223 return false;
224 }
225}
226
227static bool format_is_tdm(struct dai_link_data *link_data)
228{
229 if (link_data->slots > 2)
230 return true;
231 else
232 return false;
233}
234
235static bool codec_is_akcodec(unsigned int type)
236{
237 switch (type) {
238 case CODEC_AK4458:
239 case CODEC_AK4497:
240 case CODEC_AK5558:
241 case CODEC_AK5552:
242 return true;
243 default:
244 break;
245 }
246 return false;
247}
248
249static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream,
250 struct snd_pcm_hw_params *params,
251 int slots, int slot_width)
252{
253 struct snd_soc_pcm_runtime *rtd = substream->private_data;
254 struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card);
255 const struct imx_card_plat_data *plat_data = data->plat_data;
256 struct dai_link_data *link_data = &data->link_data[rtd->num];
257 unsigned int width = slots * slot_width;
258 unsigned int rate = params_rate(params);
259 int i;
260
261 if (format_is_tdm(link_data)) {
262 for (i = 0; i < plat_data->num_tdm_fs_mul; i++) {
263
264 if (width != plat_data->tdm_fs_mul[i].min)
265 continue;
266 return rate * plat_data->tdm_fs_mul[i].mul;
267 }
268 } else {
269 for (i = 0; i < plat_data->num_fs_mul; i++) {
270 if (rate >= plat_data->fs_mul[i].rmin &&
271 rate <= plat_data->fs_mul[i].rmax) {
272 width = max(width, plat_data->fs_mul[i].wmin);
273 width = min(width, plat_data->fs_mul[i].wmax);
274
275
276 width *= link_data->one2one_ratio ? 1 : 2;
277
278 return rate * width;
279 }
280 }
281 }
282
283
284 return 0;
285}
286
287static int imx_aif_hw_params(struct snd_pcm_substream *substream,
288 struct snd_pcm_hw_params *params)
289{
290 struct snd_soc_pcm_runtime *rtd = substream->private_data;
291 struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
292 struct snd_soc_card *card = rtd->card;
293 struct imx_card_data *data = snd_soc_card_get_drvdata(card);
294 struct dai_link_data *link_data = &data->link_data[rtd->num];
295 struct imx_card_plat_data *plat_data = data->plat_data;
296 struct device *dev = card->dev;
297 struct snd_soc_dai *codec_dai;
298 unsigned long mclk_freq;
299 unsigned int fmt = rtd->dai_link->dai_fmt;
300 unsigned int slots, slot_width;
301 int ret, i;
302
303 slots = link_data->slots;
304 slot_width = link_data->slot_width;
305
306 if (!format_is_tdm(link_data)) {
307 if (format_is_dsd(params)) {
308 slots = 1;
309 slot_width = params_width(params);
310 fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
311 SND_SOC_DAIFMT_PDM;
312 } else {
313 slots = 2;
314 slot_width = params_physical_width(params);
315 fmt = (rtd->dai_link->dai_fmt & ~SND_SOC_DAIFMT_FORMAT_MASK) |
316 SND_SOC_DAIFMT_I2S;
317 }
318 }
319
320 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
321 if (ret && ret != -ENOTSUPP) {
322 dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
323 return ret;
324 }
325 ret = snd_soc_dai_set_tdm_slot(cpu_dai,
326 BIT(slots) - 1,
327 BIT(slots) - 1,
328 slots, slot_width);
329 if (ret && ret != -ENOTSUPP) {
330 dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
331 return ret;
332 }
333
334 for_each_rtd_codec_dais(rtd, i, codec_dai) {
335 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
336 if (ret && ret != -ENOTSUPP) {
337 dev_err(dev, "failed to set codec dai[%d] fmt: %d\n", i, ret);
338 return ret;
339 }
340
341 ret = snd_soc_dai_set_tdm_slot(codec_dai,
342 BIT(slots) - 1,
343 BIT(slots) - 1,
344 slots, slot_width);
345 if (ret && ret != -ENOTSUPP) {
346 dev_err(dev, "failed to set codec dai[%d] tdm slot: %d\n", i, ret);
347 return ret;
348 }
349 }
350
351
352 if (codec_is_akcodec(plat_data->type))
353 mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width);
354 else
355 mclk_freq = params_rate(params) * slots * slot_width;
356
357 if (format_is_dsd(params))
358 mclk_freq = 22579200;
359
360 ret = snd_soc_dai_set_sysclk(cpu_dai, link_data->cpu_sysclk_id, mclk_freq,
361 SND_SOC_CLOCK_OUT);
362 if (ret && ret != -ENOTSUPP) {
363 dev_err(dev, "failed to set cpui dai mclk1 rate (%lu): %d\n", mclk_freq, ret);
364 return ret;
365 }
366
367 return 0;
368}
369
370static int ak5558_hw_rule_rate(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *r)
371{
372 struct dai_link_data *link_data = r->private;
373 struct snd_interval t = { .min = 8000, .max = 8000, };
374 unsigned long mclk_freq;
375 unsigned int fs;
376 int i;
377
378 fs = hw_param_interval(p, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;
379 fs *= link_data->slots;
380
381
382 for (i = 0; i < ARRAY_SIZE(akcodec_rates); i++) {
383 mclk_freq = fs * akcodec_rates[i];
384
385 mclk_freq *= link_data->one2one_ratio ? 1 : 2;
386
387
388 if (mclk_freq > 36864000)
389 continue;
390
391 if (t.max < akcodec_rates[i])
392 t.max = akcodec_rates[i];
393 }
394
395 return snd_interval_refine(hw_param_interval(p, r->var), &t);
396}
397
398static int imx_aif_startup(struct snd_pcm_substream *substream)
399{
400 struct snd_pcm_runtime *runtime = substream->runtime;
401 struct snd_soc_pcm_runtime *rtd = substream->private_data;
402 struct snd_soc_card *card = rtd->card;
403 struct imx_card_data *data = snd_soc_card_get_drvdata(card);
404 struct dai_link_data *link_data = &data->link_data[rtd->num];
405 static struct snd_pcm_hw_constraint_list constraint_rates;
406 static struct snd_pcm_hw_constraint_list constraint_channels;
407 int ret = 0;
408
409 if (format_is_tdm(link_data)) {
410 constraint_channels.list = data->plat_data->support_tdm_channels;
411 constraint_channels.count = data->plat_data->num_tdm_channels;
412 constraint_rates.list = data->plat_data->support_tdm_rates;
413 constraint_rates.count = data->plat_data->num_tdm_rates;
414 } else {
415 constraint_channels.list = data->plat_data->support_channels;
416 constraint_channels.count = data->plat_data->num_channels;
417 constraint_rates.list = data->plat_data->support_rates;
418 constraint_rates.count = data->plat_data->num_rates;
419 }
420
421 if (constraint_channels.count) {
422 ret = snd_pcm_hw_constraint_list(runtime, 0,
423 SNDRV_PCM_HW_PARAM_CHANNELS,
424 &constraint_channels);
425 if (ret)
426 return ret;
427 }
428
429 if (constraint_rates.count) {
430 ret = snd_pcm_hw_constraint_list(runtime, 0,
431 SNDRV_PCM_HW_PARAM_RATE,
432 &constraint_rates);
433 if (ret)
434 return ret;
435 }
436
437 if (data->plat_data->type == CODEC_AK5558)
438 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
439 SNDRV_PCM_HW_PARAM_RATE,
440 ak5558_hw_rule_rate, link_data,
441 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
442
443 return ret;
444}
445
446static const struct snd_soc_ops imx_aif_ops = {
447 .hw_params = imx_aif_hw_params,
448 .startup = imx_aif_startup,
449};
450
451static const struct snd_soc_ops imx_aif_ops_be = {
452 .hw_params = imx_aif_hw_params,
453};
454
455static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
456 struct snd_pcm_hw_params *params)
457{
458 struct snd_soc_card *card = rtd->card;
459 struct imx_card_data *data = snd_soc_card_get_drvdata(card);
460 struct snd_interval *rate;
461 struct snd_mask *mask;
462
463 rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
464 rate->max = data->asrc_rate;
465 rate->min = data->asrc_rate;
466
467 mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
468 snd_mask_none(mask);
469 snd_mask_set(mask, data->asrc_format);
470
471 return 0;
472}
473
474static int imx_card_parse_of(struct imx_card_data *data)
475{
476 struct imx_card_plat_data *plat_data = data->plat_data;
477 struct snd_soc_card *card = &data->card;
478 struct snd_soc_dai_link_component *dlc;
479 struct device_node *platform = NULL;
480 struct device_node *codec = NULL;
481 struct device_node *cpu = NULL;
482 struct device_node *np;
483 struct device *dev = card->dev;
484 struct snd_soc_dai_link *link;
485 struct dai_link_data *link_data;
486 struct of_phandle_args args;
487 int ret, num_links;
488 u32 width;
489
490 ret = snd_soc_of_parse_card_name(card, "model");
491 if (ret) {
492 dev_err(dev, "Error parsing card name: %d\n", ret);
493 return ret;
494 }
495
496
497 if (of_property_read_bool(dev->of_node, "audio-routing")) {
498 ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
499 if (ret)
500 return ret;
501 }
502
503
504 num_links = of_get_child_count(dev->of_node);
505
506
507 card->dai_link = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
508 if (!card->dai_link)
509 return -ENOMEM;
510
511 data->link_data = devm_kcalloc(dev, num_links, sizeof(*link), GFP_KERNEL);
512 if (!data->link_data)
513 return -ENOMEM;
514
515 card->num_links = num_links;
516 link = card->dai_link;
517 link_data = data->link_data;
518
519 for_each_child_of_node(dev->of_node, np) {
520 dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
521 if (!dlc) {
522 ret = -ENOMEM;
523 goto err_put_np;
524 }
525
526 link->cpus = &dlc[0];
527 link->platforms = &dlc[1];
528
529 link->num_cpus = 1;
530 link->num_platforms = 1;
531
532 ret = of_property_read_string(np, "link-name", &link->name);
533 if (ret) {
534 dev_err(card->dev, "error getting codec dai_link name\n");
535 goto err_put_np;
536 }
537
538 cpu = of_get_child_by_name(np, "cpu");
539 if (!cpu) {
540 dev_err(dev, "%s: Can't find cpu DT node\n", link->name);
541 ret = -EINVAL;
542 goto err;
543 }
544
545 ret = of_parse_phandle_with_args(cpu, "sound-dai",
546 "#sound-dai-cells", 0, &args);
547 if (ret) {
548 dev_err(card->dev, "%s: error getting cpu phandle\n", link->name);
549 goto err;
550 }
551
552 if (of_node_name_eq(args.np, "sai")) {
553
554 link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1;
555
556
557 if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) {
558 link_data->one2one_ratio = true;
559 } else {
560 int i;
561
562
563
564
565
566 for (i = 0; i < ARRAY_SIZE(ak4497_fs_mul); i++) {
567 if (ak4497_fs_mul[i].rmin == 705600 &&
568 ak4497_fs_mul[i].rmax == 768000) {
569 ak4497_fs_mul[i].wmin = 32;
570 ak4497_fs_mul[i].wmax = 32;
571 }
572 }
573 }
574 }
575
576 link->cpus->of_node = args.np;
577 link->platforms->of_node = link->cpus->of_node;
578 link->id = args.args[0];
579
580 ret = snd_soc_of_get_dai_name(cpu, &link->cpus->dai_name);
581 if (ret) {
582 dev_err_probe(card->dev, ret,
583 "%s: error getting cpu dai name\n", link->name);
584 goto err;
585 }
586
587 codec = of_get_child_by_name(np, "codec");
588 if (codec) {
589 ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
590 if (ret < 0) {
591 dev_err_probe(dev, ret, "%s: codec dai not found\n",
592 link->name);
593 goto err;
594 }
595
596 plat_data->num_codecs = link->num_codecs;
597
598
599 if (!strcmp(link->codecs->dai_name, "ak4458-aif"))
600 plat_data->type = CODEC_AK4458;
601 else if (!strcmp(link->codecs->dai_name, "ak4497-aif"))
602 plat_data->type = CODEC_AK4497;
603 else if (!strcmp(link->codecs->dai_name, "ak5558-aif"))
604 plat_data->type = CODEC_AK5558;
605 else if (!strcmp(link->codecs->dai_name, "ak5552-aif"))
606 plat_data->type = CODEC_AK5552;
607
608 } else {
609 dlc = devm_kzalloc(dev, sizeof(*dlc), GFP_KERNEL);
610 if (!dlc) {
611 ret = -ENOMEM;
612 goto err;
613 }
614
615 link->codecs = dlc;
616 link->num_codecs = 1;
617
618 link->codecs->dai_name = "snd-soc-dummy-dai";
619 link->codecs->name = "snd-soc-dummy";
620 }
621
622 if (!strncmp(link->name, "HiFi-ASRC-FE", 12)) {
623
624 link->dynamic = 1;
625 link->dpcm_merged_chan = 1;
626
627 ret = of_property_read_u32(args.np, "fsl,asrc-rate", &data->asrc_rate);
628 if (ret) {
629 dev_err(dev, "failed to get output rate\n");
630 ret = -EINVAL;
631 goto err;
632 }
633
634 ret = of_property_read_u32(args.np, "fsl,asrc-format", &data->asrc_format);
635 if (ret) {
636
637 ret = of_property_read_u32(args.np, "fsl,asrc-width", &width);
638 if (ret) {
639 dev_err(dev,
640 "failed to decide output format\n");
641 goto err;
642 }
643
644 if (width == 24)
645 data->asrc_format = SNDRV_PCM_FORMAT_S24_LE;
646 else
647 data->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
648 }
649 } else if (!strncmp(link->name, "HiFi-ASRC-BE", 12)) {
650
651 link->no_pcm = 1;
652 link->platforms->of_node = NULL;
653 link->platforms->name = "snd-soc-dummy";
654
655 link->be_hw_params_fixup = be_hw_params_fixup;
656 link->ops = &imx_aif_ops_be;
657 } else {
658 link->ops = &imx_aif_ops;
659 }
660
661 if (link->no_pcm || link->dynamic)
662 snd_soc_dai_link_set_capabilities(link);
663
664
665 ret = asoc_simple_parse_daifmt(dev, np, codec,
666 NULL, &link->dai_fmt);
667 if (ret)
668 link->dai_fmt = SND_SOC_DAIFMT_NB_NF |
669 SND_SOC_DAIFMT_CBC_CFC |
670 SND_SOC_DAIFMT_I2S;
671
672
673 snd_soc_of_parse_tdm_slot(np, NULL, NULL,
674 &link_data->slots,
675 &link_data->slot_width);
676
677 if (!link_data->slots)
678 link_data->slots = 2;
679
680 if (!link_data->slot_width)
681 link_data->slot_width = 32;
682
683 link->ignore_pmdown_time = 1;
684 link->stream_name = link->name;
685 link++;
686 link_data++;
687
688 of_node_put(cpu);
689 of_node_put(codec);
690 of_node_put(platform);
691 }
692
693 return 0;
694err:
695 of_node_put(cpu);
696 of_node_put(codec);
697 of_node_put(platform);
698err_put_np:
699 of_node_put(np);
700 return ret;
701}
702
703static int imx_card_probe(struct platform_device *pdev)
704{
705 struct snd_soc_dai_link *link_be = NULL, *link;
706 struct imx_card_plat_data *plat_data;
707 struct imx_card_data *data;
708 int ret, i;
709
710 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
711 if (!data)
712 return -ENOMEM;
713
714 plat_data = devm_kzalloc(&pdev->dev, sizeof(*plat_data), GFP_KERNEL);
715 if (!plat_data)
716 return -ENOMEM;
717
718 data->plat_data = plat_data;
719 data->card.dev = &pdev->dev;
720
721 dev_set_drvdata(&pdev->dev, &data->card);
722 snd_soc_card_set_drvdata(&data->card, data);
723 ret = imx_card_parse_of(data);
724 if (ret)
725 return ret;
726
727 data->num_dapm_routes = plat_data->num_codecs + 1;
728 data->dapm_routes = devm_kcalloc(&pdev->dev, data->num_dapm_routes,
729 sizeof(struct snd_soc_dapm_route),
730 GFP_KERNEL);
731 if (!data->dapm_routes)
732 return -ENOMEM;
733
734
735 switch (plat_data->type) {
736 case CODEC_AK4458:
737 case CODEC_AK4497:
738 if (plat_data->num_codecs == 1) {
739 data->dapm_routes[0].sink = "Playback";
740 data->dapm_routes[0].source = "CPU-Playback";
741 i = 1;
742 } else {
743 for (i = 0; i < plat_data->num_codecs; i++) {
744 data->dapm_routes[i].sink =
745 devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
746 i + 1, "Playback");
747 data->dapm_routes[i].source = "CPU-Playback";
748 }
749 }
750 data->dapm_routes[i].sink = "CPU-Playback";
751 data->dapm_routes[i].source = "ASRC-Playback";
752 break;
753 case CODEC_AK5558:
754 case CODEC_AK5552:
755 if (plat_data->num_codecs == 1) {
756 data->dapm_routes[0].sink = "CPU-Capture";
757 data->dapm_routes[0].source = "Capture";
758 i = 1;
759 } else {
760 for (i = 0; i < plat_data->num_codecs; i++) {
761 data->dapm_routes[i].source =
762 devm_kasprintf(&pdev->dev, GFP_KERNEL, "%d %s",
763 i + 1, "Capture");
764 data->dapm_routes[i].sink = "CPU-Capture";
765 }
766 }
767 data->dapm_routes[i].sink = "ASRC-Capture";
768 data->dapm_routes[i].source = "CPU-Capture";
769 break;
770 default:
771 break;
772 }
773
774
775 if (codec_is_akcodec(plat_data->type)) {
776 plat_data->support_rates = akcodec_rates;
777 plat_data->num_rates = ARRAY_SIZE(akcodec_rates);
778 plat_data->support_tdm_rates = akcodec_tdm_rates;
779 plat_data->num_tdm_rates = ARRAY_SIZE(akcodec_tdm_rates);
780
781 switch (plat_data->type) {
782 case CODEC_AK4458:
783 plat_data->fs_mul = ak4458_fs_mul;
784 plat_data->num_fs_mul = ARRAY_SIZE(ak4458_fs_mul);
785 plat_data->tdm_fs_mul = ak4458_tdm_fs_mul;
786 plat_data->num_tdm_fs_mul = ARRAY_SIZE(ak4458_tdm_fs_mul);
787 plat_data->support_channels = ak4458_channels;
788 plat_data->num_channels = ARRAY_SIZE(ak4458_channels);
789 plat_data->support_tdm_channels = ak4458_tdm_channels;
790 plat_data->num_tdm_channels = ARRAY_SIZE(ak4458_tdm_channels);
791 break;
792 case CODEC_AK4497:
793 plat_data->fs_mul = ak4497_fs_mul;
794 plat_data->num_fs_mul = ARRAY_SIZE(ak4497_fs_mul);
795 plat_data->support_channels = ak4458_channels;
796 plat_data->num_channels = ARRAY_SIZE(ak4458_channels);
797 break;
798 case CODEC_AK5558:
799 case CODEC_AK5552:
800 plat_data->fs_mul = ak5558_fs_mul;
801 plat_data->num_fs_mul = ARRAY_SIZE(ak5558_fs_mul);
802 plat_data->tdm_fs_mul = ak5558_tdm_fs_mul;
803 plat_data->num_tdm_fs_mul = ARRAY_SIZE(ak5558_tdm_fs_mul);
804 plat_data->support_channels = ak5558_channels;
805 plat_data->num_channels = ARRAY_SIZE(ak5558_channels);
806 plat_data->support_tdm_channels = ak5558_tdm_channels;
807 plat_data->num_tdm_channels = ARRAY_SIZE(ak5558_tdm_channels);
808 break;
809 default:
810 break;
811 }
812 }
813
814
815 if (data->card.num_links == 3) {
816 data->card.dapm_routes = data->dapm_routes;
817 data->card.num_dapm_routes = data->num_dapm_routes;
818 for_each_card_prelinks(&data->card, i, link) {
819 if (link->no_pcm == 1)
820 link_be = link;
821 }
822 for_each_card_prelinks(&data->card, i, link) {
823 if (link->dynamic == 1 && link_be) {
824 link->dpcm_playback = link_be->dpcm_playback;
825 link->dpcm_capture = link_be->dpcm_capture;
826 }
827 }
828 }
829
830 ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
831 if (ret)
832 return dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed\n");
833
834 return 0;
835}
836
837static const struct of_device_id imx_card_dt_ids[] = {
838 { .compatible = "fsl,imx-audio-card", },
839 { },
840};
841MODULE_DEVICE_TABLE(of, imx_card_dt_ids);
842
843static struct platform_driver imx_card_driver = {
844 .driver = {
845 .name = "imx-card",
846 .pm = &snd_soc_pm_ops,
847 .of_match_table = imx_card_dt_ids,
848 },
849 .probe = imx_card_probe,
850};
851module_platform_driver(imx_card_driver);
852
853MODULE_DESCRIPTION("Freescale i.MX ASoC Machine Driver");
854MODULE_LICENSE("GPL v2");
855MODULE_ALIAS("platform:imx-card");
856