1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright 2017-2021 NXP
4 #include <linux/module.h>
5 #include <linux/init.h>
6 #include <linux/slab.h>
7 #include <linux/gpio/consumer.h>
10 #include <linux/clk.h>
11 #include <sound/soc.h>
12 #include <sound/pcm_params.h>
13 #include <sound/pcm.h>
14 #include <sound/soc-dapm.h>
15 #include <sound/simple_card_utils.h>
19 #define IMX_CARD_MCLK_22P5792MHZ 22579200
20 #define IMX_CARD_MCLK_24P576MHZ 24576000
32 * Mapping LRCK fs and frame width, table 3 & 4 in datasheet
35 * @wmin: min frame ratio
36 * @wmax: max frame ratio
38 struct imx_akcodec_fs_mul
{
46 * Mapping TDM mode and frame width
48 struct imx_akcodec_tdm_fs_mul
{
55 * struct imx_card_plat_data - specific info for codecs
57 * @fs_mul: ratio of mclk/fs for normal mode
58 * @tdm_fs_mul: ratio of mclk/fs for tdm mode
59 * @support_rates: supported sample rate
60 * @support_tdm_rates: supported sample rate for tdm mode
61 * @support_channels: supported channels
62 * @support_tdm_channels: supported channels for tdm mode
63 * @num_fs_mul: ARRAY_SIZE of fs_mul
64 * @num_tdm_fs_mul: ARRAY_SIZE of tdm_fs_mul
65 * @num_rates: ARRAY_SIZE of support_rates
66 * @num_tdm_rates: ARRAY_SIZE of support_tdm_rates
67 * @num_channels: ARRAY_SIZE of support_channels
68 * @num_tdm_channels: ARRAY_SIZE of support_tdm_channels
71 struct imx_card_plat_data
{
72 struct imx_akcodec_fs_mul
*fs_mul
;
73 struct imx_akcodec_tdm_fs_mul
*tdm_fs_mul
;
74 const u32
*support_rates
;
75 const u32
*support_tdm_rates
;
76 const u32
*support_channels
;
77 const u32
*support_tdm_channels
;
78 unsigned int num_fs_mul
;
79 unsigned int num_tdm_fs_mul
;
80 unsigned int num_rates
;
81 unsigned int num_tdm_rates
;
82 unsigned int num_channels
;
83 unsigned int num_tdm_channels
;
84 unsigned int num_codecs
;
89 * struct dai_link_data - specific info for dai link
92 * @slot_width: slot width value
93 * @cpu_sysclk_id: sysclk id for cpu dai
94 * @one2one_ratio: true if mclk equal to bclk
96 struct dai_link_data
{
98 unsigned int slot_width
;
99 unsigned int cpu_sysclk_id
;
104 * struct imx_card_data - platform device data
106 * @plat_data: pointer of imx_card_plat_data
107 * @dapm_routes: pointer of dapm_routes
108 * @link_data: private data for dai link
109 * @card: card instance
110 * @num_dapm_routes: number of dapm_routes
111 * @asrc_rate: asrc rates
112 * @asrc_format: asrc format
114 struct imx_card_data
{
115 struct imx_card_plat_data
*plat_data
;
116 struct snd_soc_dapm_route
*dapm_routes
;
117 struct dai_link_data
*link_data
;
118 struct snd_soc_card card
;
121 snd_pcm_format_t asrc_format
;
124 static struct imx_akcodec_fs_mul ak4458_fs_mul
[] = {
125 /* Normal, < 32kHz */
126 { .rmin
= 8000, .rmax
= 24000, .wmin
= 256, .wmax
= 1024, },
128 { .rmin
= 32000, .rmax
= 32000, .wmin
= 256, .wmax
= 1024, },
130 { .rmin
= 44100, .rmax
= 48000, .wmin
= 256, .wmax
= 768, },
132 { .rmin
= 88200, .rmax
= 96000, .wmin
= 256, .wmax
= 512, },
134 { .rmin
= 176400, .rmax
= 192000, .wmin
= 128, .wmax
= 256, },
136 { .rmin
= 352800, .rmax
= 384000, .wmin
= 32, .wmax
= 128, },
138 { .rmin
= 705600, .rmax
= 768000, .wmin
= 16, .wmax
= 64, },
141 static struct imx_akcodec_tdm_fs_mul ak4458_tdm_fs_mul
[] = {
143 * Table 13 - Audio Interface Format
144 * For TDM mode, MCLK should is set to
145 * obtained from 2 * slots * slot_width
147 { .min
= 128, .max
= 128, .mul
= 256 }, /* TDM128 */
148 { .min
= 256, .max
= 256, .mul
= 512 }, /* TDM256 */
149 { .min
= 512, .max
= 512, .mul
= 1024 }, /* TDM512 */
152 static struct imx_akcodec_fs_mul ak4497_fs_mul
[] = {
154 * Table 7 - mapping multiplier and speed mode
155 * Tables 8 & 9 - mapping speed mode and LRCK fs
157 { .rmin
= 8000, .rmax
= 32000, .wmin
= 256, .wmax
= 1024, }, /* Normal, <= 32kHz */
158 { .rmin
= 44100, .rmax
= 48000, .wmin
= 256, .wmax
= 512, }, /* Normal */
159 { .rmin
= 88200, .rmax
= 96000, .wmin
= 256, .wmax
= 256, }, /* Double */
160 { .rmin
= 176400, .rmax
= 192000, .wmin
= 128, .wmax
= 128, }, /* Quad */
161 { .rmin
= 352800, .rmax
= 384000, .wmin
= 128, .wmax
= 128, }, /* Oct */
162 { .rmin
= 705600, .rmax
= 768000, .wmin
= 64, .wmax
= 64, }, /* Hex */
166 * Auto MCLK selection based on LRCK for Normal Mode
167 * (Table 4 from datasheet)
169 static struct imx_akcodec_fs_mul ak5558_fs_mul
[] = {
170 { .rmin
= 8000, .rmax
= 32000, .wmin
= 512, .wmax
= 1024, },
171 { .rmin
= 44100, .rmax
= 48000, .wmin
= 512, .wmax
= 512, },
172 { .rmin
= 88200, .rmax
= 96000, .wmin
= 256, .wmax
= 256, },
173 { .rmin
= 176400, .rmax
= 192000, .wmin
= 128, .wmax
= 128, },
174 { .rmin
= 352800, .rmax
= 384000, .wmin
= 64, .wmax
= 64, },
175 { .rmin
= 705600, .rmax
= 768000, .wmin
= 32, .wmax
= 32, },
179 * MCLK and BCLK selection based on TDM mode
180 * because of SAI we also add the restriction: MCLK >= 2 * BCLK
181 * (Table 9 from datasheet)
183 static struct imx_akcodec_tdm_fs_mul ak5558_tdm_fs_mul
[] = {
184 { .min
= 128, .max
= 128, .mul
= 256 },
185 { .min
= 256, .max
= 256, .mul
= 512 },
186 { .min
= 512, .max
= 512, .mul
= 1024 },
189 static struct imx_akcodec_fs_mul cs42888_fs_mul
[] = {
190 { .rmin
= 8000, .rmax
= 48000, .wmin
= 256, .wmax
= 1024, },
191 { .rmin
= 64000, .rmax
= 96000, .wmin
= 128, .wmax
= 512, },
192 { .rmin
= 176400, .rmax
= 192000, .wmin
= 64, .wmax
= 256, },
195 static struct imx_akcodec_tdm_fs_mul cs42888_tdm_fs_mul
[] = {
196 { .min
= 256, .max
= 256, .mul
= 256 },
199 static const u32 akcodec_rates
[] = {
200 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
201 96000, 176400, 192000, 352800, 384000, 705600, 768000,
204 static const u32 akcodec_tdm_rates
[] = {
205 8000, 16000, 32000, 48000, 96000,
208 static const u32 ak4458_channels
[] = {
209 1, 2, 4, 6, 8, 10, 12, 14, 16,
212 static const u32 ak4458_tdm_channels
[] = {
213 1, 2, 3, 4, 5, 6, 7, 8, 16,
216 static const u32 ak5558_channels
[] = {
220 static const u32 ak5558_tdm_channels
[] = {
221 1, 2, 3, 4, 5, 6, 7, 8,
224 static const u32 cs42888_channels
[] = {
228 static const u32 cs42888_tdm_channels
[] = {
229 1, 2, 3, 4, 5, 6, 7, 8,
232 static bool format_is_dsd(struct snd_pcm_hw_params
*params
)
234 snd_pcm_format_t format
= params_format(params
);
237 case SNDRV_PCM_FORMAT_DSD_U8
:
238 case SNDRV_PCM_FORMAT_DSD_U16_LE
:
239 case SNDRV_PCM_FORMAT_DSD_U16_BE
:
240 case SNDRV_PCM_FORMAT_DSD_U32_LE
:
241 case SNDRV_PCM_FORMAT_DSD_U32_BE
:
248 static bool format_is_tdm(struct dai_link_data
*link_data
)
250 if (link_data
->slots
> 2)
256 static bool codec_is_akcodec(unsigned int type
)
271 static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream
*substream
,
272 struct snd_pcm_hw_params
*params
,
273 int slots
, int slot_width
)
275 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
276 struct imx_card_data
*data
= snd_soc_card_get_drvdata(rtd
->card
);
277 const struct imx_card_plat_data
*plat_data
= data
->plat_data
;
278 struct dai_link_data
*link_data
= &data
->link_data
[rtd
->id
];
279 unsigned int width
= slots
* slot_width
;
280 unsigned int rate
= params_rate(params
);
283 if (format_is_tdm(link_data
)) {
284 for (i
= 0; i
< plat_data
->num_tdm_fs_mul
; i
++) {
285 /* min = max = slots * slots_width */
286 if (width
!= plat_data
->tdm_fs_mul
[i
].min
)
288 return rate
* plat_data
->tdm_fs_mul
[i
].mul
;
291 for (i
= 0; i
< plat_data
->num_fs_mul
; i
++) {
292 if (rate
>= plat_data
->fs_mul
[i
].rmin
&&
293 rate
<= plat_data
->fs_mul
[i
].rmax
) {
294 width
= max(width
, plat_data
->fs_mul
[i
].wmin
);
295 width
= min(width
, plat_data
->fs_mul
[i
].wmax
);
297 /* Adjust SAI bclk:mclk ratio */
298 width
*= link_data
->one2one_ratio
? 1 : 2;
305 /* Let DAI manage clk frequency by default */
309 static int imx_aif_hw_params(struct snd_pcm_substream
*substream
,
310 struct snd_pcm_hw_params
*params
)
312 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
313 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
314 struct snd_soc_card
*card
= rtd
->card
;
315 struct imx_card_data
*data
= snd_soc_card_get_drvdata(card
);
316 struct dai_link_data
*link_data
= &data
->link_data
[rtd
->id
];
317 struct imx_card_plat_data
*plat_data
= data
->plat_data
;
318 struct device
*dev
= card
->dev
;
319 struct snd_soc_dai
*codec_dai
;
320 unsigned long mclk_freq
;
321 unsigned int fmt
= rtd
->dai_link
->dai_fmt
;
322 unsigned int slots
, slot_width
;
325 slots
= link_data
->slots
;
326 slot_width
= link_data
->slot_width
;
328 if (!format_is_tdm(link_data
)) {
329 if (format_is_dsd(params
)) {
331 slot_width
= params_width(params
);
332 fmt
= (rtd
->dai_link
->dai_fmt
& ~SND_SOC_DAIFMT_FORMAT_MASK
) |
336 slot_width
= params_physical_width(params
);
337 fmt
= (rtd
->dai_link
->dai_fmt
& ~SND_SOC_DAIFMT_FORMAT_MASK
) |
342 ret
= snd_soc_dai_set_fmt(cpu_dai
, snd_soc_daifmt_clock_provider_flipped(fmt
));
343 if (ret
&& ret
!= -ENOTSUPP
) {
344 dev_err(dev
, "failed to set cpu dai fmt: %d\n", ret
);
347 ret
= snd_soc_dai_set_tdm_slot(cpu_dai
,
351 if (ret
&& ret
!= -ENOTSUPP
) {
352 dev_err(dev
, "failed to set cpu dai tdm slot: %d\n", ret
);
356 for_each_rtd_codec_dais(rtd
, i
, codec_dai
) {
357 ret
= snd_soc_dai_set_fmt(codec_dai
, fmt
);
358 if (ret
&& ret
!= -ENOTSUPP
) {
359 dev_err(dev
, "failed to set codec dai[%d] fmt: %d\n", i
, ret
);
363 if (format_is_tdm(link_data
)) {
364 ret
= snd_soc_dai_set_tdm_slot(codec_dai
,
368 if (ret
&& ret
!= -ENOTSUPP
) {
369 dev_err(dev
, "failed to set codec dai[%d] tdm slot: %d\n", i
, ret
);
376 if (codec_is_akcodec(plat_data
->type
))
377 mclk_freq
= akcodec_get_mclk_rate(substream
, params
, slots
, slot_width
);
379 mclk_freq
= params_rate(params
) * slots
* slot_width
;
381 if (format_is_dsd(params
)) {
382 /* Use the maximum freq from DSD512 (512*44100 = 22579200) */
383 if (!(params_rate(params
) % 11025))
384 mclk_freq
= IMX_CARD_MCLK_22P5792MHZ
;
386 mclk_freq
= IMX_CARD_MCLK_24P576MHZ
;
389 ret
= snd_soc_dai_set_sysclk(cpu_dai
, link_data
->cpu_sysclk_id
, mclk_freq
,
391 if (ret
&& ret
!= -ENOTSUPP
) {
392 dev_err(dev
, "failed to set cpui dai mclk1 rate (%lu): %d\n", mclk_freq
, ret
);
395 ret
= snd_soc_dai_set_sysclk(codec_dai
, 0, mclk_freq
, SND_SOC_CLOCK_IN
);
396 if (ret
&& ret
!= -ENOTSUPP
) {
397 dev_err(dev
, "failed to set codec dai mclk rate (%lu): %d\n", mclk_freq
, ret
);
404 static int ak5558_hw_rule_rate(struct snd_pcm_hw_params
*p
, struct snd_pcm_hw_rule
*r
)
406 struct dai_link_data
*link_data
= r
->private;
407 struct snd_interval t
= { .min
= 8000, .max
= 8000, };
408 unsigned long mclk_freq
;
412 fs
= hw_param_interval(p
, SNDRV_PCM_HW_PARAM_SAMPLE_BITS
)->min
;
413 fs
*= link_data
->slots
;
415 /* Identify maximum supported rate */
416 for (i
= 0; i
< ARRAY_SIZE(akcodec_rates
); i
++) {
417 mclk_freq
= fs
* akcodec_rates
[i
];
418 /* Adjust SAI bclk:mclk ratio */
419 mclk_freq
*= link_data
->one2one_ratio
? 1 : 2;
421 /* Skip rates for which MCLK is beyond supported value */
422 if (mclk_freq
> 36864000)
425 if (t
.max
< akcodec_rates
[i
])
426 t
.max
= akcodec_rates
[i
];
429 return snd_interval_refine(hw_param_interval(p
, r
->var
), &t
);
432 static int imx_aif_startup(struct snd_pcm_substream
*substream
)
434 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
435 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
436 struct snd_soc_card
*card
= rtd
->card
;
437 struct imx_card_data
*data
= snd_soc_card_get_drvdata(card
);
438 struct dai_link_data
*link_data
= &data
->link_data
[rtd
->id
];
439 static struct snd_pcm_hw_constraint_list constraint_rates
;
440 static struct snd_pcm_hw_constraint_list constraint_channels
;
443 if (format_is_tdm(link_data
)) {
444 constraint_channels
.list
= data
->plat_data
->support_tdm_channels
;
445 constraint_channels
.count
= data
->plat_data
->num_tdm_channels
;
446 constraint_rates
.list
= data
->plat_data
->support_tdm_rates
;
447 constraint_rates
.count
= data
->plat_data
->num_tdm_rates
;
449 constraint_channels
.list
= data
->plat_data
->support_channels
;
450 constraint_channels
.count
= data
->plat_data
->num_channels
;
451 constraint_rates
.list
= data
->plat_data
->support_rates
;
452 constraint_rates
.count
= data
->plat_data
->num_rates
;
455 if (constraint_channels
.count
) {
456 ret
= snd_pcm_hw_constraint_list(runtime
, 0,
457 SNDRV_PCM_HW_PARAM_CHANNELS
,
458 &constraint_channels
);
463 if (constraint_rates
.count
) {
464 ret
= snd_pcm_hw_constraint_list(runtime
, 0,
465 SNDRV_PCM_HW_PARAM_RATE
,
471 if (data
->plat_data
->type
== CODEC_AK5558
)
472 ret
= snd_pcm_hw_rule_add(substream
->runtime
, 0,
473 SNDRV_PCM_HW_PARAM_RATE
,
474 ak5558_hw_rule_rate
, link_data
,
475 SNDRV_PCM_HW_PARAM_SAMPLE_BITS
, -1);
480 static const struct snd_soc_ops imx_aif_ops
= {
481 .hw_params
= imx_aif_hw_params
,
482 .startup
= imx_aif_startup
,
485 static const struct snd_soc_ops imx_aif_ops_be
= {
486 .hw_params
= imx_aif_hw_params
,
489 static int be_hw_params_fixup(struct snd_soc_pcm_runtime
*rtd
,
490 struct snd_pcm_hw_params
*params
)
492 struct snd_soc_card
*card
= rtd
->card
;
493 struct imx_card_data
*data
= snd_soc_card_get_drvdata(card
);
494 struct snd_interval
*rate
;
495 struct snd_mask
*mask
;
497 rate
= hw_param_interval(params
, SNDRV_PCM_HW_PARAM_RATE
);
498 rate
->max
= data
->asrc_rate
;
499 rate
->min
= data
->asrc_rate
;
501 mask
= hw_param_mask(params
, SNDRV_PCM_HW_PARAM_FORMAT
);
503 snd_mask_set(mask
, (__force
unsigned int)data
->asrc_format
);
508 static int imx_card_parse_of(struct imx_card_data
*data
)
510 struct imx_card_plat_data
*plat_data
= data
->plat_data
;
511 struct snd_soc_card
*card
= &data
->card
;
512 struct snd_soc_dai_link_component
*dlc
;
513 struct device_node
*platform
= NULL
;
514 struct device_node
*codec
= NULL
;
515 struct device_node
*cpu
= NULL
;
516 struct device_node
*np
;
517 struct device
*dev
= card
->dev
;
518 struct snd_soc_dai_link
*link
;
519 struct dai_link_data
*link_data
;
520 struct of_phandle_args args
;
525 ret
= snd_soc_of_parse_card_name(card
, "model");
527 dev_err(dev
, "Error parsing card name: %d\n", ret
);
532 if (of_property_read_bool(dev
->of_node
, "audio-routing")) {
533 ret
= snd_soc_of_parse_audio_routing(card
, "audio-routing");
539 num_links
= of_get_child_count(dev
->of_node
);
541 /* Allocate the DAI link array */
542 card
->dai_link
= devm_kcalloc(dev
, num_links
, sizeof(*link
), GFP_KERNEL
);
546 data
->link_data
= devm_kcalloc(dev
, num_links
, sizeof(*link
), GFP_KERNEL
);
547 if (!data
->link_data
)
550 card
->num_links
= num_links
;
551 link
= card
->dai_link
;
552 link_data
= data
->link_data
;
554 for_each_child_of_node(dev
->of_node
, np
) {
555 dlc
= devm_kzalloc(dev
, 2 * sizeof(*dlc
), GFP_KERNEL
);
561 link
->cpus
= &dlc
[0];
562 link
->platforms
= &dlc
[1];
565 link
->num_platforms
= 1;
567 ret
= of_property_read_string(np
, "link-name", &link
->name
);
569 dev_err(card
->dev
, "error getting codec dai_link name\n");
573 cpu
= of_get_child_by_name(np
, "cpu");
575 dev_err(dev
, "%s: Can't find cpu DT node\n", link
->name
);
580 ret
= snd_soc_of_get_dlc(cpu
, &args
, link
->cpus
, 0);
582 dev_err_probe(card
->dev
, ret
,
583 "%s: error getting cpu dai info\n", link
->name
);
587 if (of_node_name_eq(args
.np
, "sai")) {
589 link_data
->cpu_sysclk_id
= FSL_SAI_CLK_MAST1
;
591 /* sai may support mclk/bclk = 1 */
592 if (of_property_read_bool(np
, "fsl,mclk-equal-bclk")) {
593 link_data
->one2one_ratio
= true;
598 * i.MX8MQ don't support one2one ratio, then
599 * with ak4497 only 16bit case is supported.
601 for (i
= 0; i
< ARRAY_SIZE(ak4497_fs_mul
); i
++) {
602 if (ak4497_fs_mul
[i
].rmin
== 705600 &&
603 ak4497_fs_mul
[i
].rmax
== 768000) {
604 ak4497_fs_mul
[i
].wmin
= 32;
605 ak4497_fs_mul
[i
].wmax
= 32;
611 link
->platforms
->of_node
= link
->cpus
->of_node
;
612 link
->id
= args
.args
[0];
614 codec
= of_get_child_by_name(np
, "codec");
616 ret
= snd_soc_of_get_dai_link_codecs(dev
, codec
, link
);
618 dev_err_probe(dev
, ret
, "%s: codec dai not found\n",
623 plat_data
->num_codecs
= link
->num_codecs
;
625 /* Check the akcodec type */
626 if (!strcmp(link
->codecs
->dai_name
, "ak4458-aif"))
627 plat_data
->type
= CODEC_AK4458
;
628 else if (!strcmp(link
->codecs
->dai_name
, "ak4497-aif"))
629 plat_data
->type
= CODEC_AK4497
;
630 else if (!strcmp(link
->codecs
->dai_name
, "ak5558-aif"))
631 plat_data
->type
= CODEC_AK5558
;
632 else if (!strcmp(link
->codecs
->dai_name
, "ak5552-aif"))
633 plat_data
->type
= CODEC_AK5552
;
634 else if (!strcmp(link
->codecs
->dai_name
, "cs42888"))
635 plat_data
->type
= CODEC_CS42888
;
638 link
->codecs
= &snd_soc_dummy_dlc
;
639 link
->num_codecs
= 1;
642 if (!strncmp(link
->name
, "HiFi-ASRC-FE", 12)) {
645 link
->dpcm_merged_chan
= 1;
647 ret
= of_property_read_u32(args
.np
, "fsl,asrc-rate", &data
->asrc_rate
);
649 dev_err(dev
, "failed to get output rate\n");
654 ret
= of_property_read_u32(args
.np
, "fsl,asrc-format", &asrc_fmt
);
655 data
->asrc_format
= (__force snd_pcm_format_t
)asrc_fmt
;
657 /* Fallback to old binding; translate to asrc_format */
658 ret
= of_property_read_u32(args
.np
, "fsl,asrc-width", &width
);
661 "failed to decide output format\n");
666 data
->asrc_format
= SNDRV_PCM_FORMAT_S24_LE
;
668 data
->asrc_format
= SNDRV_PCM_FORMAT_S16_LE
;
670 } else if (!strncmp(link
->name
, "HiFi-ASRC-BE", 12)) {
673 link
->platforms
->of_node
= NULL
;
674 link
->platforms
->name
= "snd-soc-dummy";
676 link
->be_hw_params_fixup
= be_hw_params_fixup
;
677 link
->ops
= &imx_aif_ops_be
;
679 link
->ops
= &imx_aif_ops
;
683 ret
= simple_util_parse_daifmt(dev
, np
, codec
,
684 NULL
, &link
->dai_fmt
);
686 link
->dai_fmt
= SND_SOC_DAIFMT_NB_NF
|
687 SND_SOC_DAIFMT_CBC_CFC
|
691 snd_soc_of_parse_tdm_slot(np
, NULL
, NULL
,
693 &link_data
->slot_width
);
695 if (!link_data
->slots
)
696 link_data
->slots
= 2;
698 if (!link_data
->slot_width
)
699 link_data
->slot_width
= 32;
701 link
->ignore_pmdown_time
= 1;
702 link
->stream_name
= link
->name
;
708 of_node_put(platform
);
719 of_node_put(platform
);
725 static int imx_card_probe(struct platform_device
*pdev
)
727 struct snd_soc_dai_link
*link_be
= NULL
, *link
;
728 struct imx_card_plat_data
*plat_data
;
729 struct imx_card_data
*data
;
732 data
= devm_kzalloc(&pdev
->dev
, sizeof(*data
), GFP_KERNEL
);
736 plat_data
= devm_kzalloc(&pdev
->dev
, sizeof(*plat_data
), GFP_KERNEL
);
740 data
->plat_data
= plat_data
;
741 data
->card
.dev
= &pdev
->dev
;
742 data
->card
.owner
= THIS_MODULE
;
744 dev_set_drvdata(&pdev
->dev
, &data
->card
);
745 snd_soc_card_set_drvdata(&data
->card
, data
);
746 ret
= imx_card_parse_of(data
);
750 data
->num_dapm_routes
= plat_data
->num_codecs
+ 1;
751 data
->dapm_routes
= devm_kcalloc(&pdev
->dev
, data
->num_dapm_routes
,
752 sizeof(struct snd_soc_dapm_route
),
754 if (!data
->dapm_routes
)
757 /* configure the dapm routes */
758 switch (plat_data
->type
) {
761 if (plat_data
->num_codecs
== 1) {
762 data
->dapm_routes
[0].sink
= "Playback";
763 data
->dapm_routes
[0].source
= "CPU-Playback";
766 for (i
= 0; i
< plat_data
->num_codecs
; i
++) {
767 data
->dapm_routes
[i
].sink
=
768 devm_kasprintf(&pdev
->dev
, GFP_KERNEL
, "%d %s",
770 data
->dapm_routes
[i
].source
= "CPU-Playback";
773 data
->dapm_routes
[i
].sink
= "CPU-Playback";
774 data
->dapm_routes
[i
].source
= "ASRC-Playback";
778 if (plat_data
->num_codecs
== 1) {
779 data
->dapm_routes
[0].sink
= "CPU-Capture";
780 data
->dapm_routes
[0].source
= "Capture";
783 for (i
= 0; i
< plat_data
->num_codecs
; i
++) {
784 data
->dapm_routes
[i
].source
=
785 devm_kasprintf(&pdev
->dev
, GFP_KERNEL
, "%d %s",
787 data
->dapm_routes
[i
].sink
= "CPU-Capture";
790 data
->dapm_routes
[i
].sink
= "ASRC-Capture";
791 data
->dapm_routes
[i
].source
= "CPU-Capture";
794 data
->dapm_routes
[0].sink
= "Playback";
795 data
->dapm_routes
[0].source
= "CPU-Playback";
796 data
->dapm_routes
[1].sink
= "CPU-Capture";
797 data
->dapm_routes
[1].source
= "Capture";
803 /* default platform data for akcodecs */
804 if (codec_is_akcodec(plat_data
->type
)) {
805 plat_data
->support_rates
= akcodec_rates
;
806 plat_data
->num_rates
= ARRAY_SIZE(akcodec_rates
);
807 plat_data
->support_tdm_rates
= akcodec_tdm_rates
;
808 plat_data
->num_tdm_rates
= ARRAY_SIZE(akcodec_tdm_rates
);
810 switch (plat_data
->type
) {
812 plat_data
->fs_mul
= ak4458_fs_mul
;
813 plat_data
->num_fs_mul
= ARRAY_SIZE(ak4458_fs_mul
);
814 plat_data
->tdm_fs_mul
= ak4458_tdm_fs_mul
;
815 plat_data
->num_tdm_fs_mul
= ARRAY_SIZE(ak4458_tdm_fs_mul
);
816 plat_data
->support_channels
= ak4458_channels
;
817 plat_data
->num_channels
= ARRAY_SIZE(ak4458_channels
);
818 plat_data
->support_tdm_channels
= ak4458_tdm_channels
;
819 plat_data
->num_tdm_channels
= ARRAY_SIZE(ak4458_tdm_channels
);
822 plat_data
->fs_mul
= ak4497_fs_mul
;
823 plat_data
->num_fs_mul
= ARRAY_SIZE(ak4497_fs_mul
);
824 plat_data
->support_channels
= ak4458_channels
;
825 plat_data
->num_channels
= ARRAY_SIZE(ak4458_channels
);
829 plat_data
->fs_mul
= ak5558_fs_mul
;
830 plat_data
->num_fs_mul
= ARRAY_SIZE(ak5558_fs_mul
);
831 plat_data
->tdm_fs_mul
= ak5558_tdm_fs_mul
;
832 plat_data
->num_tdm_fs_mul
= ARRAY_SIZE(ak5558_tdm_fs_mul
);
833 plat_data
->support_channels
= ak5558_channels
;
834 plat_data
->num_channels
= ARRAY_SIZE(ak5558_channels
);
835 plat_data
->support_tdm_channels
= ak5558_tdm_channels
;
836 plat_data
->num_tdm_channels
= ARRAY_SIZE(ak5558_tdm_channels
);
839 plat_data
->fs_mul
= cs42888_fs_mul
;
840 plat_data
->num_fs_mul
= ARRAY_SIZE(cs42888_fs_mul
);
841 plat_data
->tdm_fs_mul
= cs42888_tdm_fs_mul
;
842 plat_data
->num_tdm_fs_mul
= ARRAY_SIZE(cs42888_tdm_fs_mul
);
843 plat_data
->support_channels
= cs42888_channels
;
844 plat_data
->num_channels
= ARRAY_SIZE(cs42888_channels
);
845 plat_data
->support_tdm_channels
= cs42888_tdm_channels
;
846 plat_data
->num_tdm_channels
= ARRAY_SIZE(cs42888_tdm_channels
);
853 /* with asrc as front end */
854 if (data
->card
.num_links
== 3) {
855 data
->card
.dapm_routes
= data
->dapm_routes
;
856 data
->card
.num_dapm_routes
= data
->num_dapm_routes
;
857 for_each_card_prelinks(&data
->card
, i
, link
) {
858 if (link
->no_pcm
== 1)
861 for_each_card_prelinks(&data
->card
, i
, link
) {
862 if (link
->dynamic
== 1 && link_be
) {
863 link
->playback_only
= link_be
->playback_only
;
864 link
->capture_only
= link_be
->capture_only
;
869 ret
= devm_snd_soc_register_card(&pdev
->dev
, &data
->card
);
871 return dev_err_probe(&pdev
->dev
, ret
, "snd_soc_register_card failed\n");
876 static const struct of_device_id imx_card_dt_ids
[] = {
877 { .compatible
= "fsl,imx-audio-card", },
880 MODULE_DEVICE_TABLE(of
, imx_card_dt_ids
);
882 static struct platform_driver imx_card_driver
= {
885 .pm
= &snd_soc_pm_ops
,
886 .of_match_table
= imx_card_dt_ids
,
888 .probe
= imx_card_probe
,
890 module_platform_driver(imx_card_driver
);
892 MODULE_DESCRIPTION("Freescale i.MX ASoC Machine Driver");
893 MODULE_LICENSE("GPL v2");
894 MODULE_ALIAS("platform:imx-card");