File Index
Files and directories
Sign in
FILE

imx-card.c

File preview with syntax highlighting.

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