1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3// Copyright (c) 2018, Linaro Limited
4
5#include <linux/err.h>
6#include <linux/init.h>
7#include <linux/module.h>
8#include <linux/device.h>
9#include <linux/platform_device.h>
10#include <linux/slab.h>
11#include <sound/pcm.h>
12#include <sound/soc.h>
13#include <sound/pcm_params.h>
14#include "q6afe.h"
15
16#define Q6AFE_TDM_PB_DAI(pre, num, did) {				\
17		.playback = {						\
18			.stream_name = pre" TDM"#num" Playback",	\
19			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
20				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
21				SNDRV_PCM_RATE_176400,			\
22			.formats = SNDRV_PCM_FMTBIT_S16_LE |		\
23				   SNDRV_PCM_FMTBIT_S24_LE |		\
24				   SNDRV_PCM_FMTBIT_S32_LE,		\
25			.channels_min = 1,				\
26			.channels_max = 8,				\
27			.rate_min = 8000,				\
28			.rate_max = 176400,				\
29		},							\
30		.name = #did,						\
31		.ops = &q6tdm_ops,					\
32		.id = did,						\
33		.probe = msm_dai_q6_dai_probe,				\
34		.remove = msm_dai_q6_dai_remove,			\
35	}
36
37#define Q6AFE_TDM_CAP_DAI(pre, num, did) {				\
38		.capture = {						\
39			.stream_name = pre" TDM"#num" Capture",		\
40			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
41				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
42				SNDRV_PCM_RATE_176400,			\
43			.formats = SNDRV_PCM_FMTBIT_S16_LE |		\
44				   SNDRV_PCM_FMTBIT_S24_LE |		\
45				   SNDRV_PCM_FMTBIT_S32_LE,		\
46			.channels_min = 1,				\
47			.channels_max = 8,				\
48			.rate_min = 8000,				\
49			.rate_max = 176400,				\
50		},							\
51		.name = #did,						\
52		.ops = &q6tdm_ops,					\
53		.id = did,						\
54		.probe = msm_dai_q6_dai_probe,				\
55		.remove = msm_dai_q6_dai_remove,			\
56	}
57
58#define Q6AFE_CDC_DMA_RX_DAI(did) {				\
59		.playback = {						\
60			.stream_name = #did" Playback",	\
61			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
62				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
63				SNDRV_PCM_RATE_176400,			\
64			.formats = SNDRV_PCM_FMTBIT_S16_LE |		\
65				   SNDRV_PCM_FMTBIT_S24_LE |		\
66				   SNDRV_PCM_FMTBIT_S32_LE,		\
67			.channels_min = 1,				\
68			.channels_max = 8,				\
69			.rate_min = 8000,				\
70			.rate_max = 176400,				\
71		},							\
72		.name = #did,						\
73		.ops = &q6dma_ops,					\
74		.id = did,						\
75		.probe = msm_dai_q6_dai_probe,				\
76		.remove = msm_dai_q6_dai_remove,			\
77	}
78
79#define Q6AFE_CDC_DMA_TX_DAI(did) {				\
80		.capture = {						\
81			.stream_name = #did" Capture",		\
82			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
83				SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
84				SNDRV_PCM_RATE_176400,			\
85			.formats = SNDRV_PCM_FMTBIT_S16_LE |		\
86				   SNDRV_PCM_FMTBIT_S24_LE |		\
87				   SNDRV_PCM_FMTBIT_S32_LE,		\
88			.channels_min = 1,				\
89			.channels_max = 8,				\
90			.rate_min = 8000,				\
91			.rate_max = 176400,				\
92		},							\
93		.name = #did,						\
94		.ops = &q6dma_ops,					\
95		.id = did,						\
96		.probe = msm_dai_q6_dai_probe,				\
97		.remove = msm_dai_q6_dai_remove,			\
98	}
99
100struct q6afe_dai_priv_data {
101	uint32_t sd_line_mask;
102	uint32_t sync_mode;
103	uint32_t sync_src;
104	uint32_t data_out_enable;
105	uint32_t invert_sync;
106	uint32_t data_delay;
107	uint32_t data_align;
108};
109
110struct q6afe_dai_data {
111	struct q6afe_port *port[AFE_PORT_MAX];
112	struct q6afe_port_config port_config[AFE_PORT_MAX];
113	bool is_port_started[AFE_PORT_MAX];
114	struct q6afe_dai_priv_data priv[AFE_PORT_MAX];
115};
116
117static int q6slim_hw_params(struct snd_pcm_substream *substream,
118			    struct snd_pcm_hw_params *params,
119			    struct snd_soc_dai *dai)
120{
121
122	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
123	struct q6afe_slim_cfg *slim = &dai_data->port_config[dai->id].slim;
124
125	slim->sample_rate = params_rate(params);
126
127	switch (params_format(params)) {
128	case SNDRV_PCM_FORMAT_S16_LE:
129	case SNDRV_PCM_FORMAT_SPECIAL:
130		slim->bit_width = 16;
131		break;
132	case SNDRV_PCM_FORMAT_S24_LE:
133		slim->bit_width = 24;
134		break;
135	case SNDRV_PCM_FORMAT_S32_LE:
136		slim->bit_width = 32;
137		break;
138	default:
139		pr_err("%s: format %d\n",
140			__func__, params_format(params));
141		return -EINVAL;
142	}
143
144	return 0;
145}
146
147static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
148				struct snd_pcm_hw_params *params,
149				struct snd_soc_dai *dai)
150{
151	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
152	int channels = params_channels(params);
153	struct q6afe_hdmi_cfg *hdmi = &dai_data->port_config[dai->id].hdmi;
154
155	hdmi->sample_rate = params_rate(params);
156	switch (params_format(params)) {
157	case SNDRV_PCM_FORMAT_S16_LE:
158		hdmi->bit_width = 16;
159		break;
160	case SNDRV_PCM_FORMAT_S24_LE:
161		hdmi->bit_width = 24;
162		break;
163	}
164
165	/* HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4 */
166	switch (channels) {
167	case 2:
168		hdmi->channel_allocation = 0;
169		break;
170	case 3:
171		hdmi->channel_allocation = 0x02;
172		break;
173	case 4:
174		hdmi->channel_allocation = 0x06;
175		break;
176	case 5:
177		hdmi->channel_allocation = 0x0A;
178		break;
179	case 6:
180		hdmi->channel_allocation = 0x0B;
181		break;
182	case 7:
183		hdmi->channel_allocation = 0x12;
184		break;
185	case 8:
186		hdmi->channel_allocation = 0x13;
187		break;
188	default:
189		dev_err(dai->dev, "invalid Channels = %u\n", channels);
190		return -EINVAL;
191	}
192
193	return 0;
194}
195
196static int q6i2s_hw_params(struct snd_pcm_substream *substream,
197			   struct snd_pcm_hw_params *params,
198			   struct snd_soc_dai *dai)
199{
200	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
201	struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg;
202
203	i2s->sample_rate = params_rate(params);
204	i2s->bit_width = params_width(params);
205	i2s->num_channels = params_channels(params);
206	i2s->sd_line_mask = dai_data->priv[dai->id].sd_line_mask;
207
208	return 0;
209}
210
211static int q6i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
212{
213	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
214	struct q6afe_i2s_cfg *i2s = &dai_data->port_config[dai->id].i2s_cfg;
215
216	i2s->fmt = fmt;
217
218	return 0;
219}
220
221static int q6tdm_set_tdm_slot(struct snd_soc_dai *dai,
222				unsigned int tx_mask,
223				unsigned int rx_mask,
224				int slots, int slot_width)
225{
226
227	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
228	struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm;
229	unsigned int cap_mask;
230	int rc = 0;
231
232	/* HW only supports 16 and 32 bit slot width configuration */
233	if ((slot_width != 16) && (slot_width != 32)) {
234		dev_err(dai->dev, "%s: invalid slot_width %d\n",
235			__func__, slot_width);
236		return -EINVAL;
237	}
238
239	/* HW supports 1-32 slots configuration. Typical: 1, 2, 4, 8, 16, 32 */
240	switch (slots) {
241	case 2:
242		cap_mask = 0x03;
243		break;
244	case 4:
245		cap_mask = 0x0F;
246		break;
247	case 8:
248		cap_mask = 0xFF;
249		break;
250	case 16:
251		cap_mask = 0xFFFF;
252		break;
253	default:
254		dev_err(dai->dev, "%s: invalid slots %d\n",
255			__func__, slots);
256		return -EINVAL;
257	}
258
259	switch (dai->id) {
260	case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
261		tdm->nslots_per_frame = slots;
262		tdm->slot_width = slot_width;
263		/* TDM RX dais ids are even and tx are odd */
264		tdm->slot_mask = (dai->id & 0x1 ? tx_mask : rx_mask) & cap_mask;
265		break;
266	default:
267		dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
268			__func__, dai->id);
269		return -EINVAL;
270	}
271
272	return rc;
273}
274
275static int q6tdm_set_channel_map(struct snd_soc_dai *dai,
276				unsigned int tx_num, unsigned int *tx_slot,
277				unsigned int rx_num, unsigned int *rx_slot)
278{
279
280	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
281	struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm;
282	int rc = 0;
283	int i = 0;
284
285	switch (dai->id) {
286	case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
287		if (dai->id & 0x1) {
288			if (!tx_slot) {
289				dev_err(dai->dev, "tx slot not found\n");
290				return -EINVAL;
291			}
292			if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
293				dev_err(dai->dev, "invalid tx num %d\n",
294					tx_num);
295				return -EINVAL;
296			}
297
298			for (i = 0; i < tx_num; i++)
299				tdm->ch_mapping[i] = tx_slot[i];
300
301			for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
302				tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID;
303
304			tdm->num_channels = tx_num;
305		} else {
306			/* rx */
307			if (!rx_slot) {
308				dev_err(dai->dev, "rx slot not found\n");
309				return -EINVAL;
310			}
311			if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
312				dev_err(dai->dev, "invalid rx num %d\n",
313					rx_num);
314				return -EINVAL;
315			}
316
317			for (i = 0; i < rx_num; i++)
318				tdm->ch_mapping[i] = rx_slot[i];
319
320			for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++)
321				tdm->ch_mapping[i] = Q6AFE_CMAP_INVALID;
322
323			tdm->num_channels = rx_num;
324		}
325
326		break;
327	default:
328		dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
329			__func__, dai->id);
330		return -EINVAL;
331	}
332
333	return rc;
334}
335
336static int q6tdm_hw_params(struct snd_pcm_substream *substream,
337			   struct snd_pcm_hw_params *params,
338			   struct snd_soc_dai *dai)
339{
340	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
341	struct q6afe_tdm_cfg *tdm = &dai_data->port_config[dai->id].tdm;
342
343	tdm->bit_width = params_width(params);
344	tdm->sample_rate = params_rate(params);
345	tdm->num_channels = params_channels(params);
346	tdm->data_align_type = dai_data->priv[dai->id].data_align;
347	tdm->sync_src = dai_data->priv[dai->id].sync_src;
348	tdm->sync_mode = dai_data->priv[dai->id].sync_mode;
349
350	return 0;
351}
352
353static int q6dma_set_channel_map(struct snd_soc_dai *dai,
354				 unsigned int tx_num, unsigned int *tx_ch_mask,
355				 unsigned int rx_num, unsigned int *rx_ch_mask)
356{
357
358	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
359	struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg;
360	int ch_mask;
361	int rc = 0;
362
363	switch (dai->id) {
364	case WSA_CODEC_DMA_TX_0:
365	case WSA_CODEC_DMA_TX_1:
366	case WSA_CODEC_DMA_TX_2:
367	case VA_CODEC_DMA_TX_0:
368	case VA_CODEC_DMA_TX_1:
369	case VA_CODEC_DMA_TX_2:
370	case TX_CODEC_DMA_TX_0:
371	case TX_CODEC_DMA_TX_1:
372	case TX_CODEC_DMA_TX_2:
373	case TX_CODEC_DMA_TX_3:
374	case TX_CODEC_DMA_TX_4:
375	case TX_CODEC_DMA_TX_5:
376		if (!tx_ch_mask) {
377			dev_err(dai->dev, "tx slot not found\n");
378			return -EINVAL;
379		}
380
381		if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
382			dev_err(dai->dev, "invalid tx num %d\n",
383				tx_num);
384			return -EINVAL;
385		}
386		ch_mask = *tx_ch_mask;
387
388		break;
389	case WSA_CODEC_DMA_RX_0:
390	case WSA_CODEC_DMA_RX_1:
391	case RX_CODEC_DMA_RX_0:
392	case RX_CODEC_DMA_RX_1:
393	case RX_CODEC_DMA_RX_2:
394	case RX_CODEC_DMA_RX_3:
395	case RX_CODEC_DMA_RX_4:
396	case RX_CODEC_DMA_RX_5:
397	case RX_CODEC_DMA_RX_6:
398	case RX_CODEC_DMA_RX_7:
399		/* rx */
400		if (!rx_ch_mask) {
401			dev_err(dai->dev, "rx slot not found\n");
402			return -EINVAL;
403		}
404		if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
405			dev_err(dai->dev, "invalid rx num %d\n",
406				rx_num);
407			return -EINVAL;
408		}
409		ch_mask = *rx_ch_mask;
410
411		break;
412	default:
413		dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
414			__func__, dai->id);
415		return -EINVAL;
416	}
417
418	cfg->active_channels_mask = ch_mask;
419
420	return rc;
421}
422
423static int q6dma_hw_params(struct snd_pcm_substream *substream,
424			   struct snd_pcm_hw_params *params,
425			   struct snd_soc_dai *dai)
426{
427	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
428	struct q6afe_cdc_dma_cfg *cfg = &dai_data->port_config[dai->id].dma_cfg;
429
430	cfg->bit_width = params_width(params);
431	cfg->sample_rate = params_rate(params);
432	cfg->num_channels = params_channels(params);
433
434	return 0;
435}
436static void q6afe_dai_shutdown(struct snd_pcm_substream *substream,
437				struct snd_soc_dai *dai)
438{
439	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
440	int rc;
441
442	if (!dai_data->is_port_started[dai->id])
443		return;
444
445	rc = q6afe_port_stop(dai_data->port[dai->id]);
446	if (rc < 0)
447		dev_err(dai->dev, "fail to close AFE port (%d)\n", rc);
448
449	dai_data->is_port_started[dai->id] = false;
450
451}
452
453static int q6afe_dai_prepare(struct snd_pcm_substream *substream,
454		struct snd_soc_dai *dai)
455{
456	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
457	int rc;
458
459	if (dai_data->is_port_started[dai->id]) {
460		/* stop the port and restart with new port config */
461		rc = q6afe_port_stop(dai_data->port[dai->id]);
462		if (rc < 0) {
463			dev_err(dai->dev, "fail to close AFE port (%d)\n", rc);
464			return rc;
465		}
466	}
467
468	switch (dai->id) {
469	case HDMI_RX:
470	case DISPLAY_PORT_RX:
471		q6afe_hdmi_port_prepare(dai_data->port[dai->id],
472					&dai_data->port_config[dai->id].hdmi);
473		break;
474	case SLIMBUS_0_RX ... SLIMBUS_6_TX:
475		q6afe_slim_port_prepare(dai_data->port[dai->id],
476					&dai_data->port_config[dai->id].slim);
477		break;
478	case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
479		rc = q6afe_i2s_port_prepare(dai_data->port[dai->id],
480			       &dai_data->port_config[dai->id].i2s_cfg);
481		if (rc < 0) {
482			dev_err(dai->dev, "fail to prepare AFE port %x\n",
483				dai->id);
484			return rc;
485		}
486		break;
487	case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
488		q6afe_tdm_port_prepare(dai_data->port[dai->id],
489					&dai_data->port_config[dai->id].tdm);
490		break;
491	case WSA_CODEC_DMA_RX_0 ... RX_CODEC_DMA_RX_7:
492		q6afe_cdc_dma_port_prepare(dai_data->port[dai->id],
493					   &dai_data->port_config[dai->id].dma_cfg);
494		break;
495	default:
496		return -EINVAL;
497	}
498
499	rc = q6afe_port_start(dai_data->port[dai->id]);
500	if (rc < 0) {
501		dev_err(dai->dev, "fail to start AFE port %x\n", dai->id);
502		return rc;
503	}
504	dai_data->is_port_started[dai->id] = true;
505
506	return 0;
507}
508
509static int q6slim_set_channel_map(struct snd_soc_dai *dai,
510				unsigned int tx_num, unsigned int *tx_slot,
511				unsigned int rx_num, unsigned int *rx_slot)
512{
513	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
514	struct q6afe_port_config *pcfg = &dai_data->port_config[dai->id];
515	int i;
516
517	if (dai->id & 0x1) {
518		/* TX */
519		if (!tx_slot) {
520			pr_err("%s: tx slot not found\n", __func__);
521			return -EINVAL;
522		}
523
524		for (i = 0; i < tx_num; i++)
525			pcfg->slim.ch_mapping[i] = tx_slot[i];
526
527		pcfg->slim.num_channels = tx_num;
528
529
530	} else {
531		if (!rx_slot) {
532			pr_err("%s: rx slot not found\n", __func__);
533			return -EINVAL;
534		}
535
536		for (i = 0; i < rx_num; i++)
537			pcfg->slim.ch_mapping[i] =   rx_slot[i];
538
539		pcfg->slim.num_channels = rx_num;
540
541	}
542
543	return 0;
544}
545
546static int q6afe_mi2s_set_sysclk(struct snd_soc_dai *dai,
547		int clk_id, unsigned int freq, int dir)
548{
549	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
550	struct q6afe_port *port = dai_data->port[dai->id];
551
552	switch (clk_id) {
553	case LPAIF_DIG_CLK:
554		return q6afe_port_set_sysclk(port, clk_id, 0, 5, freq, dir);
555	case LPAIF_BIT_CLK:
556	case LPAIF_OSR_CLK:
557		return q6afe_port_set_sysclk(port, clk_id,
558					     Q6AFE_LPASS_CLK_SRC_INTERNAL,
559					     Q6AFE_LPASS_CLK_ROOT_DEFAULT,
560					     freq, dir);
561	case Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT ... Q6AFE_LPASS_CLK_ID_QUI_MI2S_OSR:
562	case Q6AFE_LPASS_CLK_ID_MCLK_1 ... Q6AFE_LPASS_CLK_ID_INT_MCLK_1:
563	case Q6AFE_LPASS_CLK_ID_WSA_CORE_MCLK ... Q6AFE_LPASS_CLK_ID_VA_CORE_2X_MCLK:
564		return q6afe_port_set_sysclk(port, clk_id,
565					     Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
566					     Q6AFE_LPASS_CLK_ROOT_DEFAULT,
567					     freq, dir);
568	case Q6AFE_LPASS_CLK_ID_PRI_TDM_IBIT ... Q6AFE_LPASS_CLK_ID_QUIN_TDM_EBIT:
569		return q6afe_port_set_sysclk(port, clk_id,
570					     Q6AFE_LPASS_CLK_ATTRIBUTE_INVERT_COUPLE_NO,
571					     Q6AFE_LPASS_CLK_ROOT_DEFAULT,
572					     freq, dir);
573	}
574
575	return 0;
576}
577
578static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
579	{"HDMI Playback", NULL, "HDMI_RX"},
580	{"Display Port Playback", NULL, "DISPLAY_PORT_RX"},
581	{"Slimbus Playback", NULL, "SLIMBUS_0_RX"},
582	{"Slimbus1 Playback", NULL, "SLIMBUS_1_RX"},
583	{"Slimbus2 Playback", NULL, "SLIMBUS_2_RX"},
584	{"Slimbus3 Playback", NULL, "SLIMBUS_3_RX"},
585	{"Slimbus4 Playback", NULL, "SLIMBUS_4_RX"},
586	{"Slimbus5 Playback", NULL, "SLIMBUS_5_RX"},
587	{"Slimbus6 Playback", NULL, "SLIMBUS_6_RX"},
588
589	{"SLIMBUS_0_TX", NULL, "Slimbus Capture"},
590	{"SLIMBUS_1_TX", NULL, "Slimbus1 Capture"},
591	{"SLIMBUS_2_TX", NULL, "Slimbus2 Capture"},
592	{"SLIMBUS_3_TX", NULL, "Slimbus3 Capture"},
593	{"SLIMBUS_4_TX", NULL, "Slimbus4 Capture"},
594	{"SLIMBUS_5_TX", NULL, "Slimbus5 Capture"},
595	{"SLIMBUS_6_TX", NULL, "Slimbus6 Capture"},
596
597	{"Primary MI2S Playback", NULL, "PRI_MI2S_RX"},
598	{"Secondary MI2S Playback", NULL, "SEC_MI2S_RX"},
599	{"Tertiary MI2S Playback", NULL, "TERT_MI2S_RX"},
600	{"Quaternary MI2S Playback", NULL, "QUAT_MI2S_RX"},
601
602	{"Primary TDM0 Playback", NULL, "PRIMARY_TDM_RX_0"},
603	{"Primary TDM1 Playback", NULL, "PRIMARY_TDM_RX_1"},
604	{"Primary TDM2 Playback", NULL, "PRIMARY_TDM_RX_2"},
605	{"Primary TDM3 Playback", NULL, "PRIMARY_TDM_RX_3"},
606	{"Primary TDM4 Playback", NULL, "PRIMARY_TDM_RX_4"},
607	{"Primary TDM5 Playback", NULL, "PRIMARY_TDM_RX_5"},
608	{"Primary TDM6 Playback", NULL, "PRIMARY_TDM_RX_6"},
609	{"Primary TDM7 Playback", NULL, "PRIMARY_TDM_RX_7"},
610
611	{"Secondary TDM0 Playback", NULL, "SEC_TDM_RX_0"},
612	{"Secondary TDM1 Playback", NULL, "SEC_TDM_RX_1"},
613	{"Secondary TDM2 Playback", NULL, "SEC_TDM_RX_2"},
614	{"Secondary TDM3 Playback", NULL, "SEC_TDM_RX_3"},
615	{"Secondary TDM4 Playback", NULL, "SEC_TDM_RX_4"},
616	{"Secondary TDM5 Playback", NULL, "SEC_TDM_RX_5"},
617	{"Secondary TDM6 Playback", NULL, "SEC_TDM_RX_6"},
618	{"Secondary TDM7 Playback", NULL, "SEC_TDM_RX_7"},
619
620	{"Tertiary TDM0 Playback", NULL, "TERT_TDM_RX_0"},
621	{"Tertiary TDM1 Playback", NULL, "TERT_TDM_RX_1"},
622	{"Tertiary TDM2 Playback", NULL, "TERT_TDM_RX_2"},
623	{"Tertiary TDM3 Playback", NULL, "TERT_TDM_RX_3"},
624	{"Tertiary TDM4 Playback", NULL, "TERT_TDM_RX_4"},
625	{"Tertiary TDM5 Playback", NULL, "TERT_TDM_RX_5"},
626	{"Tertiary TDM6 Playback", NULL, "TERT_TDM_RX_6"},
627	{"Tertiary TDM7 Playback", NULL, "TERT_TDM_RX_7"},
628
629	{"Quaternary TDM0 Playback", NULL, "QUAT_TDM_RX_0"},
630	{"Quaternary TDM1 Playback", NULL, "QUAT_TDM_RX_1"},
631	{"Quaternary TDM2 Playback", NULL, "QUAT_TDM_RX_2"},
632	{"Quaternary TDM3 Playback", NULL, "QUAT_TDM_RX_3"},
633	{"Quaternary TDM4 Playback", NULL, "QUAT_TDM_RX_4"},
634	{"Quaternary TDM5 Playback", NULL, "QUAT_TDM_RX_5"},
635	{"Quaternary TDM6 Playback", NULL, "QUAT_TDM_RX_6"},
636	{"Quaternary TDM7 Playback", NULL, "QUAT_TDM_RX_7"},
637
638	{"Quinary TDM0 Playback", NULL, "QUIN_TDM_RX_0"},
639	{"Quinary TDM1 Playback", NULL, "QUIN_TDM_RX_1"},
640	{"Quinary TDM2 Playback", NULL, "QUIN_TDM_RX_2"},
641	{"Quinary TDM3 Playback", NULL, "QUIN_TDM_RX_3"},
642	{"Quinary TDM4 Playback", NULL, "QUIN_TDM_RX_4"},
643	{"Quinary TDM5 Playback", NULL, "QUIN_TDM_RX_5"},
644	{"Quinary TDM6 Playback", NULL, "QUIN_TDM_RX_6"},
645	{"Quinary TDM7 Playback", NULL, "QUIN_TDM_RX_7"},
646
647	{"PRIMARY_TDM_TX_0", NULL, "Primary TDM0 Capture"},
648	{"PRIMARY_TDM_TX_1", NULL, "Primary TDM1 Capture"},
649	{"PRIMARY_TDM_TX_2", NULL, "Primary TDM2 Capture"},
650	{"PRIMARY_TDM_TX_3", NULL, "Primary TDM3 Capture"},
651	{"PRIMARY_TDM_TX_4", NULL, "Primary TDM4 Capture"},
652	{"PRIMARY_TDM_TX_5", NULL, "Primary TDM5 Capture"},
653	{"PRIMARY_TDM_TX_6", NULL, "Primary TDM6 Capture"},
654	{"PRIMARY_TDM_TX_7", NULL, "Primary TDM7 Capture"},
655
656	{"SEC_TDM_TX_0", NULL, "Secondary TDM0 Capture"},
657	{"SEC_TDM_TX_1", NULL, "Secondary TDM1 Capture"},
658	{"SEC_TDM_TX_2", NULL, "Secondary TDM2 Capture"},
659	{"SEC_TDM_TX_3", NULL, "Secondary TDM3 Capture"},
660	{"SEC_TDM_TX_4", NULL, "Secondary TDM4 Capture"},
661	{"SEC_TDM_TX_5", NULL, "Secondary TDM5 Capture"},
662	{"SEC_TDM_TX_6", NULL, "Secondary TDM6 Capture"},
663	{"SEC_TDM_TX_7", NULL, "Secondary TDM7 Capture"},
664
665	{"TERT_TDM_TX_0", NULL, "Tertiary TDM0 Capture"},
666	{"TERT_TDM_TX_1", NULL, "Tertiary TDM1 Capture"},
667	{"TERT_TDM_TX_2", NULL, "Tertiary TDM2 Capture"},
668	{"TERT_TDM_TX_3", NULL, "Tertiary TDM3 Capture"},
669	{"TERT_TDM_TX_4", NULL, "Tertiary TDM4 Capture"},
670	{"TERT_TDM_TX_5", NULL, "Tertiary TDM5 Capture"},
671	{"TERT_TDM_TX_6", NULL, "Tertiary TDM6 Capture"},
672	{"TERT_TDM_TX_7", NULL, "Tertiary TDM7 Capture"},
673
674	{"QUAT_TDM_TX_0", NULL, "Quaternary TDM0 Capture"},
675	{"QUAT_TDM_TX_1", NULL, "Quaternary TDM1 Capture"},
676	{"QUAT_TDM_TX_2", NULL, "Quaternary TDM2 Capture"},
677	{"QUAT_TDM_TX_3", NULL, "Quaternary TDM3 Capture"},
678	{"QUAT_TDM_TX_4", NULL, "Quaternary TDM4 Capture"},
679	{"QUAT_TDM_TX_5", NULL, "Quaternary TDM5 Capture"},
680	{"QUAT_TDM_TX_6", NULL, "Quaternary TDM6 Capture"},
681	{"QUAT_TDM_TX_7", NULL, "Quaternary TDM7 Capture"},
682
683	{"QUIN_TDM_TX_0", NULL, "Quinary TDM0 Capture"},
684	{"QUIN_TDM_TX_1", NULL, "Quinary TDM1 Capture"},
685	{"QUIN_TDM_TX_2", NULL, "Quinary TDM2 Capture"},
686	{"QUIN_TDM_TX_3", NULL, "Quinary TDM3 Capture"},
687	{"QUIN_TDM_TX_4", NULL, "Quinary TDM4 Capture"},
688	{"QUIN_TDM_TX_5", NULL, "Quinary TDM5 Capture"},
689	{"QUIN_TDM_TX_6", NULL, "Quinary TDM6 Capture"},
690	{"QUIN_TDM_TX_7", NULL, "Quinary TDM7 Capture"},
691
692	{"TERT_MI2S_TX", NULL, "Tertiary MI2S Capture"},
693	{"PRI_MI2S_TX", NULL, "Primary MI2S Capture"},
694	{"SEC_MI2S_TX", NULL, "Secondary MI2S Capture"},
695	{"QUAT_MI2S_TX", NULL, "Quaternary MI2S Capture"},
696
697	{"WSA_CODEC_DMA_RX_0 Playback", NULL, "WSA_CODEC_DMA_RX_0"},
698	{"WSA_CODEC_DMA_TX_0", NULL, "WSA_CODEC_DMA_TX_0 Capture"},
699	{"WSA_CODEC_DMA_RX_1 Playback", NULL, "WSA_CODEC_DMA_RX_1"},
700	{"WSA_CODEC_DMA_TX_1", NULL, "WSA_CODEC_DMA_TX_1 Capture"},
701	{"WSA_CODEC_DMA_TX_2", NULL, "WSA_CODEC_DMA_TX_2 Capture"},
702	{"VA_CODEC_DMA_TX_0", NULL, "VA_CODEC_DMA_TX_0 Capture"},
703	{"VA_CODEC_DMA_TX_1", NULL, "VA_CODEC_DMA_TX_1 Capture"},
704	{"VA_CODEC_DMA_TX_2", NULL, "VA_CODEC_DMA_TX_2 Capture"},
705	{"RX_CODEC_DMA_RX_0 Playback", NULL, "RX_CODEC_DMA_RX_0"},
706	{"TX_CODEC_DMA_TX_0", NULL, "TX_CODEC_DMA_TX_0 Capture"},
707	{"RX_CODEC_DMA_RX_1 Playback", NULL, "RX_CODEC_DMA_RX_1"},
708	{"TX_CODEC_DMA_TX_1", NULL, "TX_CODEC_DMA_TX_1 Capture"},
709	{"RX_CODEC_DMA_RX_2 Playback", NULL, "RX_CODEC_DMA_RX_2"},
710	{"TX_CODEC_DMA_TX_2", NULL, "TX_CODEC_DMA_TX_2 Capture"},
711	{"RX_CODEC_DMA_RX_3 Playback", NULL, "RX_CODEC_DMA_RX_3"},
712	{"TX_CODEC_DMA_TX_3", NULL, "TX_CODEC_DMA_TX_3 Capture"},
713	{"RX_CODEC_DMA_RX_4 Playback", NULL, "RX_CODEC_DMA_RX_4"},
714	{"TX_CODEC_DMA_TX_4", NULL, "TX_CODEC_DMA_TX_4 Capture"},
715	{"RX_CODEC_DMA_RX_5 Playback", NULL, "RX_CODEC_DMA_RX_5"},
716	{"TX_CODEC_DMA_TX_5", NULL, "TX_CODEC_DMA_TX_5 Capture"},
717	{"RX_CODEC_DMA_RX_6 Playback", NULL, "RX_CODEC_DMA_RX_6"},
718	{"RX_CODEC_DMA_RX_7 Playback", NULL, "RX_CODEC_DMA_RX_7"},
719};
720
721static const struct snd_soc_dai_ops q6hdmi_ops = {
722	.prepare	= q6afe_dai_prepare,
723	.hw_params	= q6hdmi_hw_params,
724	.shutdown	= q6afe_dai_shutdown,
725};
726
727static const struct snd_soc_dai_ops q6i2s_ops = {
728	.prepare	= q6afe_dai_prepare,
729	.hw_params	= q6i2s_hw_params,
730	.set_fmt	= q6i2s_set_fmt,
731	.shutdown	= q6afe_dai_shutdown,
732	.set_sysclk	= q6afe_mi2s_set_sysclk,
733};
734
735static const struct snd_soc_dai_ops q6slim_ops = {
736	.prepare	= q6afe_dai_prepare,
737	.hw_params	= q6slim_hw_params,
738	.shutdown	= q6afe_dai_shutdown,
739	.set_channel_map = q6slim_set_channel_map,
740};
741
742static const struct snd_soc_dai_ops q6tdm_ops = {
743	.prepare	= q6afe_dai_prepare,
744	.shutdown	= q6afe_dai_shutdown,
745	.set_sysclk	= q6afe_mi2s_set_sysclk,
746	.set_tdm_slot     = q6tdm_set_tdm_slot,
747	.set_channel_map  = q6tdm_set_channel_map,
748	.hw_params        = q6tdm_hw_params,
749};
750
751static const struct snd_soc_dai_ops q6dma_ops = {
752	.prepare	= q6afe_dai_prepare,
753	.shutdown	= q6afe_dai_shutdown,
754	.set_sysclk	= q6afe_mi2s_set_sysclk,
755	.set_channel_map  = q6dma_set_channel_map,
756	.hw_params        = q6dma_hw_params,
757};
758
759static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
760{
761	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
762	struct q6afe_port *port;
763
764	port = q6afe_port_get_from_id(dai->dev, dai->id);
765	if (IS_ERR(port)) {
766		dev_err(dai->dev, "Unable to get afe port\n");
767		return -EINVAL;
768	}
769	dai_data->port[dai->id] = port;
770
771	return 0;
772}
773
774static int msm_dai_q6_dai_remove(struct snd_soc_dai *dai)
775{
776	struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
777
778	q6afe_port_put(dai_data->port[dai->id]);
779	dai_data->port[dai->id] = NULL;
780
781	return 0;
782}
783
784static struct snd_soc_dai_driver q6afe_dais[] = {
785	{
786		.playback = {
787			.stream_name = "HDMI Playback",
788			.rates = SNDRV_PCM_RATE_48000 |
789				 SNDRV_PCM_RATE_96000 |
790				 SNDRV_PCM_RATE_192000,
791			.formats = SNDRV_PCM_FMTBIT_S16_LE |
792				   SNDRV_PCM_FMTBIT_S24_LE,
793			.channels_min = 2,
794			.channels_max = 8,
795			.rate_max =     192000,
796			.rate_min =	48000,
797		},
798		.ops = &q6hdmi_ops,
799		.id = HDMI_RX,
800		.name = "HDMI",
801		.probe = msm_dai_q6_dai_probe,
802		.remove = msm_dai_q6_dai_remove,
803	}, {
804		.name = "SLIMBUS_0_RX",
805		.ops = &q6slim_ops,
806		.id = SLIMBUS_0_RX,
807		.probe = msm_dai_q6_dai_probe,
808		.remove = msm_dai_q6_dai_remove,
809		.playback = {
810			.stream_name = "Slimbus Playback",
811			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
812				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
813				 SNDRV_PCM_RATE_192000,
814			.formats = SNDRV_PCM_FMTBIT_S16_LE |
815				   SNDRV_PCM_FMTBIT_S24_LE,
816			.channels_min = 1,
817			.channels_max = 8,
818			.rate_min = 8000,
819			.rate_max = 192000,
820		},
821	}, {
822		.name = "SLIMBUS_0_TX",
823		.ops = &q6slim_ops,
824		.id = SLIMBUS_0_TX,
825		.probe = msm_dai_q6_dai_probe,
826		.remove = msm_dai_q6_dai_remove,
827		.capture = {
828			.stream_name = "Slimbus Capture",
829			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
830				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
831				 SNDRV_PCM_RATE_192000,
832			.formats = SNDRV_PCM_FMTBIT_S16_LE |
833				   SNDRV_PCM_FMTBIT_S24_LE,
834			.channels_min = 1,
835			.channels_max = 8,
836			.rate_min = 8000,
837			.rate_max = 192000,
838		},
839	}, {
840		.playback = {
841			.stream_name = "Slimbus1 Playback",
842			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
843				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
844				 SNDRV_PCM_RATE_192000,
845			.formats = SNDRV_PCM_FMTBIT_S16_LE |
846				   SNDRV_PCM_FMTBIT_S24_LE,
847			.channels_min = 1,
848			.channels_max = 2,
849			.rate_min = 8000,
850			.rate_max = 192000,
851		},
852		.name = "SLIMBUS_1_RX",
853		.ops = &q6slim_ops,
854		.id = SLIMBUS_1_RX,
855		.probe = msm_dai_q6_dai_probe,
856		.remove = msm_dai_q6_dai_remove,
857	}, {
858		.name = "SLIMBUS_1_TX",
859		.ops = &q6slim_ops,
860		.id = SLIMBUS_1_TX,
861		.probe = msm_dai_q6_dai_probe,
862		.remove = msm_dai_q6_dai_remove,
863		.capture = {
864			.stream_name = "Slimbus1 Capture",
865			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
866				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
867				 SNDRV_PCM_RATE_192000,
868			.formats = SNDRV_PCM_FMTBIT_S16_LE |
869				   SNDRV_PCM_FMTBIT_S24_LE,
870			.channels_min = 1,
871			.channels_max = 8,
872			.rate_min = 8000,
873			.rate_max = 192000,
874		},
875	}, {
876		.playback = {
877			.stream_name = "Slimbus2 Playback",
878			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
879				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
880				 SNDRV_PCM_RATE_192000,
881			.formats = SNDRV_PCM_FMTBIT_S16_LE |
882				   SNDRV_PCM_FMTBIT_S24_LE,
883			.channels_min = 1,
884			.channels_max = 8,
885			.rate_min = 8000,
886			.rate_max = 192000,
887		},
888		.name = "SLIMBUS_2_RX",
889		.ops = &q6slim_ops,
890		.id = SLIMBUS_2_RX,
891		.probe = msm_dai_q6_dai_probe,
892		.remove = msm_dai_q6_dai_remove,
893
894	}, {
895		.name = "SLIMBUS_2_TX",
896		.ops = &q6slim_ops,
897		.id = SLIMBUS_2_TX,
898		.probe = msm_dai_q6_dai_probe,
899		.remove = msm_dai_q6_dai_remove,
900		.capture = {
901			.stream_name = "Slimbus2 Capture",
902			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
903				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
904				 SNDRV_PCM_RATE_192000,
905			.formats = SNDRV_PCM_FMTBIT_S16_LE |
906				   SNDRV_PCM_FMTBIT_S24_LE,
907			.channels_min = 1,
908			.channels_max = 8,
909			.rate_min = 8000,
910			.rate_max = 192000,
911		},
912	}, {
913		.playback = {
914			.stream_name = "Slimbus3 Playback",
915			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
916				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
917				 SNDRV_PCM_RATE_192000,
918			.formats = SNDRV_PCM_FMTBIT_S16_LE |
919				   SNDRV_PCM_FMTBIT_S24_LE,
920			.channels_min = 1,
921			.channels_max = 2,
922			.rate_min = 8000,
923			.rate_max = 192000,
924		},
925		.name = "SLIMBUS_3_RX",
926		.ops = &q6slim_ops,
927		.id = SLIMBUS_3_RX,
928		.probe = msm_dai_q6_dai_probe,
929		.remove = msm_dai_q6_dai_remove,
930
931	}, {
932		.name = "SLIMBUS_3_TX",
933		.ops = &q6slim_ops,
934		.id = SLIMBUS_3_TX,
935		.probe = msm_dai_q6_dai_probe,
936		.remove = msm_dai_q6_dai_remove,
937		.capture = {
938			.stream_name = "Slimbus3 Capture",
939			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
940				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
941				 SNDRV_PCM_RATE_192000,
942			.formats = SNDRV_PCM_FMTBIT_S16_LE |
943				   SNDRV_PCM_FMTBIT_S24_LE,
944			.channels_min = 1,
945			.channels_max = 8,
946			.rate_min = 8000,
947			.rate_max = 192000,
948		},
949	}, {
950		.playback = {
951			.stream_name = "Slimbus4 Playback",
952			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
953				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
954				 SNDRV_PCM_RATE_192000,
955			.formats = SNDRV_PCM_FMTBIT_S16_LE |
956				   SNDRV_PCM_FMTBIT_S24_LE,
957			.channels_min = 1,
958			.channels_max = 2,
959			.rate_min = 8000,
960			.rate_max = 192000,
961		},
962		.name = "SLIMBUS_4_RX",
963		.ops = &q6slim_ops,
964		.id = SLIMBUS_4_RX,
965		.probe = msm_dai_q6_dai_probe,
966		.remove = msm_dai_q6_dai_remove,
967
968	}, {
969		.name = "SLIMBUS_4_TX",
970		.ops = &q6slim_ops,
971		.id = SLIMBUS_4_TX,
972		.probe = msm_dai_q6_dai_probe,
973		.remove = msm_dai_q6_dai_remove,
974		.capture = {
975			.stream_name = "Slimbus4 Capture",
976			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
977				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
978				 SNDRV_PCM_RATE_192000,
979			.formats = SNDRV_PCM_FMTBIT_S16_LE |
980				   SNDRV_PCM_FMTBIT_S24_LE,
981			.channels_min = 1,
982			.channels_max = 8,
983			.rate_min = 8000,
984			.rate_max = 192000,
985		},
986	}, {
987		.playback = {
988			.stream_name = "Slimbus5 Playback",
989			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
990				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
991				 SNDRV_PCM_RATE_192000,
992			.formats = SNDRV_PCM_FMTBIT_S16_LE |
993				   SNDRV_PCM_FMTBIT_S24_LE,
994			.channels_min = 1,
995			.channels_max = 2,
996			.rate_min = 8000,
997			.rate_max = 192000,
998		},
999		.name = "SLIMBUS_5_RX",
1000		.ops = &q6slim_ops,
1001		.id = SLIMBUS_5_RX,
1002		.probe = msm_dai_q6_dai_probe,
1003		.remove = msm_dai_q6_dai_remove,
1004
1005	}, {
1006		.name = "SLIMBUS_5_TX",
1007		.ops = &q6slim_ops,
1008		.id = SLIMBUS_5_TX,
1009		.probe = msm_dai_q6_dai_probe,
1010		.remove = msm_dai_q6_dai_remove,
1011		.capture = {
1012			.stream_name = "Slimbus5 Capture",
1013			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1014				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
1015				 SNDRV_PCM_RATE_192000,
1016			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1017				   SNDRV_PCM_FMTBIT_S24_LE,
1018			.channels_min = 1,
1019			.channels_max = 8,
1020			.rate_min = 8000,
1021			.rate_max = 192000,
1022		},
1023	}, {
1024		.playback = {
1025			.stream_name = "Slimbus6 Playback",
1026			.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
1027				 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
1028				 SNDRV_PCM_RATE_192000,
1029			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1030				   SNDRV_PCM_FMTBIT_S24_LE,
1031			.channels_min = 1,
1032			.channels_max = 2,
1033			.rate_min = 8000,
1034			.rate_max = 192000,
1035		},
1036		.ops = &q6slim_ops,
1037		.name = "SLIMBUS_6_RX",
1038		.id = SLIMBUS_6_RX,
1039		.probe = msm_dai_q6_dai_probe,
1040		.remove = msm_dai_q6_dai_remove,
1041
1042	}, {
1043		.name = "SLIMBUS_6_TX",
1044		.ops = &q6slim_ops,
1045		.id = SLIMBUS_6_TX,
1046		.probe = msm_dai_q6_dai_probe,
1047		.remove = msm_dai_q6_dai_remove,
1048		.capture = {
1049			.stream_name = "Slimbus6 Capture",
1050			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1051				 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
1052				 SNDRV_PCM_RATE_192000,
1053			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1054				   SNDRV_PCM_FMTBIT_S24_LE,
1055			.channels_min = 1,
1056			.channels_max = 8,
1057			.rate_min = 8000,
1058			.rate_max = 192000,
1059		},
1060	}, {
1061		.playback = {
1062			.stream_name = "Primary MI2S Playback",
1063			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1064				 SNDRV_PCM_RATE_16000,
1065			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1066				   SNDRV_PCM_FMTBIT_S24_LE,
1067			.channels_min = 1,
1068			.channels_max = 8,
1069			.rate_min =     8000,
1070			.rate_max =     48000,
1071		},
1072		.id = PRIMARY_MI2S_RX,
1073		.name = "PRI_MI2S_RX",
1074		.ops = &q6i2s_ops,
1075		.probe = msm_dai_q6_dai_probe,
1076		.remove = msm_dai_q6_dai_remove,
1077	}, {
1078		.capture = {
1079			.stream_name = "Primary MI2S Capture",
1080			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1081				 SNDRV_PCM_RATE_16000,
1082			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1083				   SNDRV_PCM_FMTBIT_S24_LE,
1084			.channels_min = 1,
1085			.channels_max = 8,
1086			.rate_min =     8000,
1087			.rate_max =     48000,
1088		},
1089		.id = PRIMARY_MI2S_TX,
1090		.name = "PRI_MI2S_TX",
1091		.ops = &q6i2s_ops,
1092		.probe = msm_dai_q6_dai_probe,
1093		.remove = msm_dai_q6_dai_remove,
1094	}, {
1095		.playback = {
1096			.stream_name = "Secondary MI2S Playback",
1097			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1098				 SNDRV_PCM_RATE_16000,
1099			.formats = SNDRV_PCM_FMTBIT_S16_LE,
1100			.channels_min = 1,
1101			.channels_max = 8,
1102			.rate_min =     8000,
1103			.rate_max =     48000,
1104		},
1105		.name = "SEC_MI2S_RX",
1106		.id = SECONDARY_MI2S_RX,
1107		.ops = &q6i2s_ops,
1108		.probe = msm_dai_q6_dai_probe,
1109		.remove = msm_dai_q6_dai_remove,
1110	}, {
1111		.capture = {
1112			.stream_name = "Secondary MI2S Capture",
1113			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1114				 SNDRV_PCM_RATE_16000,
1115			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1116				   SNDRV_PCM_FMTBIT_S24_LE,
1117			.channels_min = 1,
1118			.channels_max = 8,
1119			.rate_min =     8000,
1120			.rate_max =     48000,
1121		},
1122		.id = SECONDARY_MI2S_TX,
1123		.name = "SEC_MI2S_TX",
1124		.ops = &q6i2s_ops,
1125		.probe = msm_dai_q6_dai_probe,
1126		.remove = msm_dai_q6_dai_remove,
1127	}, {
1128		.playback = {
1129			.stream_name = "Tertiary MI2S Playback",
1130			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1131				 SNDRV_PCM_RATE_16000,
1132			.formats = SNDRV_PCM_FMTBIT_S16_LE,
1133			.channels_min = 1,
1134			.channels_max = 8,
1135			.rate_min =     8000,
1136			.rate_max =     48000,
1137		},
1138		.name = "TERT_MI2S_RX",
1139		.id = TERTIARY_MI2S_RX,
1140		.ops = &q6i2s_ops,
1141		.probe = msm_dai_q6_dai_probe,
1142		.remove = msm_dai_q6_dai_remove,
1143	}, {
1144		.capture = {
1145			.stream_name = "Tertiary MI2S Capture",
1146			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1147				 SNDRV_PCM_RATE_16000,
1148			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1149				   SNDRV_PCM_FMTBIT_S24_LE,
1150			.channels_min = 1,
1151			.channels_max = 8,
1152			.rate_min =     8000,
1153			.rate_max =     48000,
1154		},
1155		.id = TERTIARY_MI2S_TX,
1156		.name = "TERT_MI2S_TX",
1157		.ops = &q6i2s_ops,
1158		.probe = msm_dai_q6_dai_probe,
1159		.remove = msm_dai_q6_dai_remove,
1160	}, {
1161		.playback = {
1162			.stream_name = "Quaternary MI2S Playback",
1163			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1164				 SNDRV_PCM_RATE_16000,
1165			.formats = SNDRV_PCM_FMTBIT_S16_LE,
1166			.channels_min = 1,
1167			.channels_max = 8,
1168			.rate_min =     8000,
1169			.rate_max =     48000,
1170		},
1171		.name = "QUAT_MI2S_RX",
1172		.id = QUATERNARY_MI2S_RX,
1173		.ops = &q6i2s_ops,
1174		.probe = msm_dai_q6_dai_probe,
1175		.remove = msm_dai_q6_dai_remove,
1176	}, {
1177		.capture = {
1178			.stream_name = "Quaternary MI2S Capture",
1179			.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
1180				 SNDRV_PCM_RATE_16000,
1181			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1182				   SNDRV_PCM_FMTBIT_S24_LE,
1183			.channels_min = 1,
1184			.channels_max = 8,
1185			.rate_min =     8000,
1186			.rate_max =     48000,
1187		},
1188		.id = QUATERNARY_MI2S_TX,
1189		.name = "QUAT_MI2S_TX",
1190		.ops = &q6i2s_ops,
1191		.probe = msm_dai_q6_dai_probe,
1192		.remove = msm_dai_q6_dai_remove,
1193	},
1194	Q6AFE_TDM_PB_DAI("Primary", 0, PRIMARY_TDM_RX_0),
1195	Q6AFE_TDM_PB_DAI("Primary", 1, PRIMARY_TDM_RX_1),
1196	Q6AFE_TDM_PB_DAI("Primary", 2, PRIMARY_TDM_RX_2),
1197	Q6AFE_TDM_PB_DAI("Primary", 3, PRIMARY_TDM_RX_3),
1198	Q6AFE_TDM_PB_DAI("Primary", 4, PRIMARY_TDM_RX_4),
1199	Q6AFE_TDM_PB_DAI("Primary", 5, PRIMARY_TDM_RX_5),
1200	Q6AFE_TDM_PB_DAI("Primary", 6, PRIMARY_TDM_RX_6),
1201	Q6AFE_TDM_PB_DAI("Primary", 7, PRIMARY_TDM_RX_7),
1202	Q6AFE_TDM_CAP_DAI("Primary", 0, PRIMARY_TDM_TX_0),
1203	Q6AFE_TDM_CAP_DAI("Primary", 1, PRIMARY_TDM_TX_1),
1204	Q6AFE_TDM_CAP_DAI("Primary", 2, PRIMARY_TDM_TX_2),
1205	Q6AFE_TDM_CAP_DAI("Primary", 3, PRIMARY_TDM_TX_3),
1206	Q6AFE_TDM_CAP_DAI("Primary", 4, PRIMARY_TDM_TX_4),
1207	Q6AFE_TDM_CAP_DAI("Primary", 5, PRIMARY_TDM_TX_5),
1208	Q6AFE_TDM_CAP_DAI("Primary", 6, PRIMARY_TDM_TX_6),
1209	Q6AFE_TDM_CAP_DAI("Primary", 7, PRIMARY_TDM_TX_7),
1210	Q6AFE_TDM_PB_DAI("Secondary", 0, SECONDARY_TDM_RX_0),
1211	Q6AFE_TDM_PB_DAI("Secondary", 1, SECONDARY_TDM_RX_1),
1212	Q6AFE_TDM_PB_DAI("Secondary", 2, SECONDARY_TDM_RX_2),
1213	Q6AFE_TDM_PB_DAI("Secondary", 3, SECONDARY_TDM_RX_3),
1214	Q6AFE_TDM_PB_DAI("Secondary", 4, SECONDARY_TDM_RX_4),
1215	Q6AFE_TDM_PB_DAI("Secondary", 5, SECONDARY_TDM_RX_5),
1216	Q6AFE_TDM_PB_DAI("Secondary", 6, SECONDARY_TDM_RX_6),
1217	Q6AFE_TDM_PB_DAI("Secondary", 7, SECONDARY_TDM_RX_7),
1218	Q6AFE_TDM_CAP_DAI("Secondary", 0, SECONDARY_TDM_TX_0),
1219	Q6AFE_TDM_CAP_DAI("Secondary", 1, SECONDARY_TDM_TX_1),
1220	Q6AFE_TDM_CAP_DAI("Secondary", 2, SECONDARY_TDM_TX_2),
1221	Q6AFE_TDM_CAP_DAI("Secondary", 3, SECONDARY_TDM_TX_3),
1222	Q6AFE_TDM_CAP_DAI("Secondary", 4, SECONDARY_TDM_TX_4),
1223	Q6AFE_TDM_CAP_DAI("Secondary", 5, SECONDARY_TDM_TX_5),
1224	Q6AFE_TDM_CAP_DAI("Secondary", 6, SECONDARY_TDM_TX_6),
1225	Q6AFE_TDM_CAP_DAI("Secondary", 7, SECONDARY_TDM_TX_7),
1226	Q6AFE_TDM_PB_DAI("Tertiary", 0, TERTIARY_TDM_RX_0),
1227	Q6AFE_TDM_PB_DAI("Tertiary", 1, TERTIARY_TDM_RX_1),
1228	Q6AFE_TDM_PB_DAI("Tertiary", 2, TERTIARY_TDM_RX_2),
1229	Q6AFE_TDM_PB_DAI("Tertiary", 3, TERTIARY_TDM_RX_3),
1230	Q6AFE_TDM_PB_DAI("Tertiary", 4, TERTIARY_TDM_RX_4),
1231	Q6AFE_TDM_PB_DAI("Tertiary", 5, TERTIARY_TDM_RX_5),
1232	Q6AFE_TDM_PB_DAI("Tertiary", 6, TERTIARY_TDM_RX_6),
1233	Q6AFE_TDM_PB_DAI("Tertiary", 7, TERTIARY_TDM_RX_7),
1234	Q6AFE_TDM_CAP_DAI("Tertiary", 0, TERTIARY_TDM_TX_0),
1235	Q6AFE_TDM_CAP_DAI("Tertiary", 1, TERTIARY_TDM_TX_1),
1236	Q6AFE_TDM_CAP_DAI("Tertiary", 2, TERTIARY_TDM_TX_2),
1237	Q6AFE_TDM_CAP_DAI("Tertiary", 3, TERTIARY_TDM_TX_3),
1238	Q6AFE_TDM_CAP_DAI("Tertiary", 4, TERTIARY_TDM_TX_4),
1239	Q6AFE_TDM_CAP_DAI("Tertiary", 5, TERTIARY_TDM_TX_5),
1240	Q6AFE_TDM_CAP_DAI("Tertiary", 6, TERTIARY_TDM_TX_6),
1241	Q6AFE_TDM_CAP_DAI("Tertiary", 7, TERTIARY_TDM_TX_7),
1242	Q6AFE_TDM_PB_DAI("Quaternary", 0, QUATERNARY_TDM_RX_0),
1243	Q6AFE_TDM_PB_DAI("Quaternary", 1, QUATERNARY_TDM_RX_1),
1244	Q6AFE_TDM_PB_DAI("Quaternary", 2, QUATERNARY_TDM_RX_2),
1245	Q6AFE_TDM_PB_DAI("Quaternary", 3, QUATERNARY_TDM_RX_3),
1246	Q6AFE_TDM_PB_DAI("Quaternary", 4, QUATERNARY_TDM_RX_4),
1247	Q6AFE_TDM_PB_DAI("Quaternary", 5, QUATERNARY_TDM_RX_5),
1248	Q6AFE_TDM_PB_DAI("Quaternary", 6, QUATERNARY_TDM_RX_6),
1249	Q6AFE_TDM_PB_DAI("Quaternary", 7, QUATERNARY_TDM_RX_7),
1250	Q6AFE_TDM_CAP_DAI("Quaternary", 0, QUATERNARY_TDM_TX_0),
1251	Q6AFE_TDM_CAP_DAI("Quaternary", 1, QUATERNARY_TDM_TX_1),
1252	Q6AFE_TDM_CAP_DAI("Quaternary", 2, QUATERNARY_TDM_TX_2),
1253	Q6AFE_TDM_CAP_DAI("Quaternary", 3, QUATERNARY_TDM_TX_3),
1254	Q6AFE_TDM_CAP_DAI("Quaternary", 4, QUATERNARY_TDM_TX_4),
1255	Q6AFE_TDM_CAP_DAI("Quaternary", 5, QUATERNARY_TDM_TX_5),
1256	Q6AFE_TDM_CAP_DAI("Quaternary", 6, QUATERNARY_TDM_TX_6),
1257	Q6AFE_TDM_CAP_DAI("Quaternary", 7, QUATERNARY_TDM_TX_7),
1258	Q6AFE_TDM_PB_DAI("Quinary", 0, QUINARY_TDM_RX_0),
1259	Q6AFE_TDM_PB_DAI("Quinary", 1, QUINARY_TDM_RX_1),
1260	Q6AFE_TDM_PB_DAI("Quinary", 2, QUINARY_TDM_RX_2),
1261	Q6AFE_TDM_PB_DAI("Quinary", 3, QUINARY_TDM_RX_3),
1262	Q6AFE_TDM_PB_DAI("Quinary", 4, QUINARY_TDM_RX_4),
1263	Q6AFE_TDM_PB_DAI("Quinary", 5, QUINARY_TDM_RX_5),
1264	Q6AFE_TDM_PB_DAI("Quinary", 6, QUINARY_TDM_RX_6),
1265	Q6AFE_TDM_PB_DAI("Quinary", 7, QUINARY_TDM_RX_7),
1266	Q6AFE_TDM_CAP_DAI("Quinary", 0, QUINARY_TDM_TX_0),
1267	Q6AFE_TDM_CAP_DAI("Quinary", 1, QUINARY_TDM_TX_1),
1268	Q6AFE_TDM_CAP_DAI("Quinary", 2, QUINARY_TDM_TX_2),
1269	Q6AFE_TDM_CAP_DAI("Quinary", 3, QUINARY_TDM_TX_3),
1270	Q6AFE_TDM_CAP_DAI("Quinary", 4, QUINARY_TDM_TX_4),
1271	Q6AFE_TDM_CAP_DAI("Quinary", 5, QUINARY_TDM_TX_5),
1272	Q6AFE_TDM_CAP_DAI("Quinary", 6, QUINARY_TDM_TX_6),
1273	Q6AFE_TDM_CAP_DAI("Quinary", 7, QUINARY_TDM_TX_7),
1274	{
1275		.playback = {
1276			.stream_name = "Display Port Playback",
1277			.rates = SNDRV_PCM_RATE_48000 |
1278				 SNDRV_PCM_RATE_96000 |
1279				 SNDRV_PCM_RATE_192000,
1280			.formats = SNDRV_PCM_FMTBIT_S16_LE |
1281				   SNDRV_PCM_FMTBIT_S24_LE,
1282			.channels_min = 2,
1283			.channels_max = 8,
1284			.rate_max =     192000,
1285			.rate_min =	48000,
1286		},
1287		.ops = &q6hdmi_ops,
1288		.id = DISPLAY_PORT_RX,
1289		.name = "DISPLAY_PORT",
1290		.probe = msm_dai_q6_dai_probe,
1291		.remove = msm_dai_q6_dai_remove,
1292	},
1293	Q6AFE_CDC_DMA_RX_DAI(WSA_CODEC_DMA_RX_0),
1294	Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_0),
1295	Q6AFE_CDC_DMA_RX_DAI(WSA_CODEC_DMA_RX_1),
1296	Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_1),
1297	Q6AFE_CDC_DMA_TX_DAI(WSA_CODEC_DMA_TX_2),
1298	Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_0),
1299	Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_1),
1300	Q6AFE_CDC_DMA_TX_DAI(VA_CODEC_DMA_TX_2),
1301	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_0),
1302	Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_0),
1303	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_1),
1304	Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_1),
1305	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_2),
1306	Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_2),
1307	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_3),
1308	Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_3),
1309	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_4),
1310	Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_4),
1311	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_5),
1312	Q6AFE_CDC_DMA_TX_DAI(TX_CODEC_DMA_TX_5),
1313	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_6),
1314	Q6AFE_CDC_DMA_RX_DAI(RX_CODEC_DMA_RX_7),
1315};
1316
1317static int q6afe_of_xlate_dai_name(struct snd_soc_component *component,
1318				   struct of_phandle_args *args,
1319				   const char **dai_name)
1320{
1321	int id = args->args[0];
1322	int ret = -EINVAL;
1323	int i;
1324
1325	for (i = 0; i  < ARRAY_SIZE(q6afe_dais); i++) {
1326		if (q6afe_dais[i].id == id) {
1327			*dai_name = q6afe_dais[i].name;
1328			ret = 0;
1329			break;
1330		}
1331	}
1332
1333	return ret;
1334}
1335
1336static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = {
1337	SND_SOC_DAPM_AIF_IN("HDMI_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1338	SND_SOC_DAPM_AIF_IN("SLIMBUS_0_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1339	SND_SOC_DAPM_AIF_IN("SLIMBUS_1_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1340	SND_SOC_DAPM_AIF_IN("SLIMBUS_2_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1341	SND_SOC_DAPM_AIF_IN("SLIMBUS_3_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1342	SND_SOC_DAPM_AIF_IN("SLIMBUS_4_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1343	SND_SOC_DAPM_AIF_IN("SLIMBUS_5_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1344	SND_SOC_DAPM_AIF_IN("SLIMBUS_6_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
1345	SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1346	SND_SOC_DAPM_AIF_OUT("SLIMBUS_1_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1347	SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1348	SND_SOC_DAPM_AIF_OUT("SLIMBUS_3_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1349	SND_SOC_DAPM_AIF_OUT("SLIMBUS_4_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1350	SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1351	SND_SOC_DAPM_AIF_OUT("SLIMBUS_6_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
1352	SND_SOC_DAPM_AIF_IN("QUAT_MI2S_RX", NULL,
1353						0, SND_SOC_NOPM, 0, 0),
1354	SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_TX", NULL,
1355						0, SND_SOC_NOPM, 0, 0),
1356	SND_SOC_DAPM_AIF_IN("TERT_MI2S_RX", NULL,
1357						0, SND_SOC_NOPM, 0, 0),
1358	SND_SOC_DAPM_AIF_OUT("TERT_MI2S_TX", NULL,
1359						0, SND_SOC_NOPM, 0, 0),
1360	SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX", NULL,
1361			     0, SND_SOC_NOPM, 0, 0),
1362	SND_SOC_DAPM_AIF_OUT("SEC_MI2S_TX", NULL,
1363						0, SND_SOC_NOPM, 0, 0),
1364	SND_SOC_DAPM_AIF_IN("SEC_MI2S_RX_SD1",
1365			"Secondary MI2S Playback SD1",
1366			0, SND_SOC_NOPM, 0, 0),
1367	SND_SOC_DAPM_AIF_IN("PRI_MI2S_RX", NULL,
1368			     0, SND_SOC_NOPM, 0, 0),
1369	SND_SOC_DAPM_AIF_OUT("PRI_MI2S_TX", NULL,
1370						0, SND_SOC_NOPM, 0, 0),
1371
1372	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_0", NULL,
1373			     0, SND_SOC_NOPM, 0, 0),
1374	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_1", NULL,
1375			     0, SND_SOC_NOPM, 0, 0),
1376	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_2", NULL,
1377			     0, SND_SOC_NOPM, 0, 0),
1378	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_3", NULL,
1379			     0, SND_SOC_NOPM, 0, 0),
1380	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_4", NULL,
1381			     0, SND_SOC_NOPM, 0, 0),
1382	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_5", NULL,
1383			     0, SND_SOC_NOPM, 0, 0),
1384	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_6", NULL,
1385			     0, SND_SOC_NOPM, 0, 0),
1386	SND_SOC_DAPM_AIF_IN("PRIMARY_TDM_RX_7", NULL,
1387			     0, SND_SOC_NOPM, 0, 0),
1388	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_0", NULL,
1389						0, SND_SOC_NOPM, 0, 0),
1390	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_1", NULL,
1391						0, SND_SOC_NOPM, 0, 0),
1392	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_2", NULL,
1393						0, SND_SOC_NOPM, 0, 0),
1394	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_3", NULL,
1395						0, SND_SOC_NOPM, 0, 0),
1396	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_4", NULL,
1397						0, SND_SOC_NOPM, 0, 0),
1398	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_5", NULL,
1399						0, SND_SOC_NOPM, 0, 0),
1400	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_6", NULL,
1401						0, SND_SOC_NOPM, 0, 0),
1402	SND_SOC_DAPM_AIF_OUT("PRIMARY_TDM_TX_7", NULL,
1403						0, SND_SOC_NOPM, 0, 0),
1404
1405	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_0", NULL,
1406			     0, SND_SOC_NOPM, 0, 0),
1407	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_1", NULL,
1408			     0, SND_SOC_NOPM, 0, 0),
1409	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_2", NULL,
1410			     0, SND_SOC_NOPM, 0, 0),
1411	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_3", NULL,
1412			     0, SND_SOC_NOPM, 0, 0),
1413	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_4", NULL,
1414			     0, SND_SOC_NOPM, 0, 0),
1415	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_5", NULL,
1416			     0, SND_SOC_NOPM, 0, 0),
1417	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_6", NULL,
1418			     0, SND_SOC_NOPM, 0, 0),
1419	SND_SOC_DAPM_AIF_IN("SEC_TDM_RX_7", NULL,
1420			     0, SND_SOC_NOPM, 0, 0),
1421	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_0", NULL,
1422						0, SND_SOC_NOPM, 0, 0),
1423	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_1", NULL,
1424						0, SND_SOC_NOPM, 0, 0),
1425	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_2", NULL,
1426						0, SND_SOC_NOPM, 0, 0),
1427	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_3", NULL,
1428						0, SND_SOC_NOPM, 0, 0),
1429	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_4", NULL,
1430						0, SND_SOC_NOPM, 0, 0),
1431	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_5", NULL,
1432						0, SND_SOC_NOPM, 0, 0),
1433	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_6", NULL,
1434						0, SND_SOC_NOPM, 0, 0),
1435	SND_SOC_DAPM_AIF_OUT("SEC_TDM_TX_7", NULL,
1436						0, SND_SOC_NOPM, 0, 0),
1437
1438	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_0", NULL,
1439			     0, SND_SOC_NOPM, 0, 0),
1440	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_1", NULL,
1441			     0, SND_SOC_NOPM, 0, 0),
1442	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_2", NULL,
1443			     0, SND_SOC_NOPM, 0, 0),
1444	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_3", NULL,
1445			     0, SND_SOC_NOPM, 0, 0),
1446	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_4", NULL,
1447			     0, SND_SOC_NOPM, 0, 0),
1448	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_5", NULL,
1449			     0, SND_SOC_NOPM, 0, 0),
1450	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_6", NULL,
1451			     0, SND_SOC_NOPM, 0, 0),
1452	SND_SOC_DAPM_AIF_IN("TERT_TDM_RX_7", NULL,
1453			     0, SND_SOC_NOPM, 0, 0),
1454	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_0", NULL,
1455						0, SND_SOC_NOPM, 0, 0),
1456	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_1", NULL,
1457						0, SND_SOC_NOPM, 0, 0),
1458	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_2", NULL,
1459						0, SND_SOC_NOPM, 0, 0),
1460	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_3", NULL,
1461						0, SND_SOC_NOPM, 0, 0),
1462	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_4", NULL,
1463						0, SND_SOC_NOPM, 0, 0),
1464	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_5", NULL,
1465						0, SND_SOC_NOPM, 0, 0),
1466	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_6", NULL,
1467						0, SND_SOC_NOPM, 0, 0),
1468	SND_SOC_DAPM_AIF_OUT("TERT_TDM_TX_7", NULL,
1469						0, SND_SOC_NOPM, 0, 0),
1470
1471	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_0", NULL,
1472			     0, SND_SOC_NOPM, 0, 0),
1473	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_1", NULL,
1474			     0, SND_SOC_NOPM, 0, 0),
1475	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_2", NULL,
1476			     0, SND_SOC_NOPM, 0, 0),
1477	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_3", NULL,
1478			     0, SND_SOC_NOPM, 0, 0),
1479	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_4", NULL,
1480			     0, SND_SOC_NOPM, 0, 0),
1481	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_5", NULL,
1482			     0, SND_SOC_NOPM, 0, 0),
1483	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_6", NULL,
1484			     0, SND_SOC_NOPM, 0, 0),
1485	SND_SOC_DAPM_AIF_IN("QUAT_TDM_RX_7", NULL,
1486			     0, SND_SOC_NOPM, 0, 0),
1487	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_0", NULL,
1488						0, SND_SOC_NOPM, 0, 0),
1489	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_1", NULL,
1490						0, SND_SOC_NOPM, 0, 0),
1491	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_2", NULL,
1492						0, SND_SOC_NOPM, 0, 0),
1493	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_3", NULL,
1494						0, SND_SOC_NOPM, 0, 0),
1495	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_4", NULL,
1496						0, SND_SOC_NOPM, 0, 0),
1497	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_5", NULL,
1498						0, SND_SOC_NOPM, 0, 0),
1499	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_6", NULL,
1500						0, SND_SOC_NOPM, 0, 0),
1501	SND_SOC_DAPM_AIF_OUT("QUAT_TDM_TX_7", NULL,
1502						0, SND_SOC_NOPM, 0, 0),
1503
1504	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_0", NULL,
1505			     0, SND_SOC_NOPM, 0, 0),
1506	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_1", NULL,
1507			     0, SND_SOC_NOPM, 0, 0),
1508	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_2", NULL,
1509			     0, SND_SOC_NOPM, 0, 0),
1510	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_3", NULL,
1511			     0, SND_SOC_NOPM, 0, 0),
1512	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_4", NULL,
1513			     0, SND_SOC_NOPM, 0, 0),
1514	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_5", NULL,
1515			     0, SND_SOC_NOPM, 0, 0),
1516	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_6", NULL,
1517			     0, SND_SOC_NOPM, 0, 0),
1518	SND_SOC_DAPM_AIF_IN("QUIN_TDM_RX_7", NULL,
1519			     0, SND_SOC_NOPM, 0, 0),
1520	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_0", NULL,
1521						0, SND_SOC_NOPM, 0, 0),
1522	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_1", NULL,
1523						0, SND_SOC_NOPM, 0, 0),
1524	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_2", NULL,
1525						0, SND_SOC_NOPM, 0, 0),
1526	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_3", NULL,
1527						0, SND_SOC_NOPM, 0, 0),
1528	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_4", NULL,
1529						0, SND_SOC_NOPM, 0, 0),
1530	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_5", NULL,
1531						0, SND_SOC_NOPM, 0, 0),
1532	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_6", NULL,
1533						0, SND_SOC_NOPM, 0, 0),
1534	SND_SOC_DAPM_AIF_OUT("QUIN_TDM_TX_7", NULL,
1535						0, SND_SOC_NOPM, 0, 0),
1536	SND_SOC_DAPM_AIF_OUT("DISPLAY_PORT_RX", "NULL", 0, SND_SOC_NOPM, 0, 0),
1537
1538	SND_SOC_DAPM_AIF_IN("WSA_CODEC_DMA_RX_0", "NULL",
1539		0, SND_SOC_NOPM, 0, 0),
1540	SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_0", "NULL",
1541		 0, SND_SOC_NOPM, 0, 0),
1542	SND_SOC_DAPM_AIF_IN("WSA_CODEC_DMA_RX_1", "NULL",
1543		0, SND_SOC_NOPM, 0, 0),
1544	SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_1", "NULL",
1545		 0, SND_SOC_NOPM, 0, 0),
1546	SND_SOC_DAPM_AIF_OUT("WSA_CODEC_DMA_TX_2", "NULL",
1547		 0, SND_SOC_NOPM, 0, 0),
1548	SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_0", "NULL",
1549		 0, SND_SOC_NOPM, 0, 0),
1550	SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_1", "NULL",
1551		 0, SND_SOC_NOPM, 0, 0),
1552	SND_SOC_DAPM_AIF_OUT("VA_CODEC_DMA_TX_2", "NULL",
1553		 0, SND_SOC_NOPM, 0, 0),
1554	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_0", "NULL",
1555		0, SND_SOC_NOPM, 0, 0),
1556	SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_0", "NULL",
1557		 0, SND_SOC_NOPM, 0, 0),
1558	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_1", "NULL",
1559		0, SND_SOC_NOPM, 0, 0),
1560	SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_1", "NULL",
1561		 0, SND_SOC_NOPM, 0, 0),
1562	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_2", "NULL",
1563		0, SND_SOC_NOPM, 0, 0),
1564	SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_2", "NULL",
1565		 0, SND_SOC_NOPM, 0, 0),
1566	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_3", "NULL",
1567		0, SND_SOC_NOPM, 0, 0),
1568	SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_3", "NULL",
1569		 0, SND_SOC_NOPM, 0, 0),
1570	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_4", "NULL",
1571		0, SND_SOC_NOPM, 0, 0),
1572	SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_4", "NULL",
1573		 0, SND_SOC_NOPM, 0, 0),
1574	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_5", "NULL",
1575		0, SND_SOC_NOPM, 0, 0),
1576	SND_SOC_DAPM_AIF_OUT("TX_CODEC_DMA_TX_5", "NULL",
1577		 0, SND_SOC_NOPM, 0, 0),
1578	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_6", "NULL",
1579		0, SND_SOC_NOPM, 0, 0),
1580	SND_SOC_DAPM_AIF_IN("RX_CODEC_DMA_RX_7", "NULL",
1581		0, SND_SOC_NOPM, 0, 0),
1582};
1583
1584static const struct snd_soc_component_driver q6afe_dai_component = {
1585	.name		= "q6afe-dai-component",
1586	.dapm_widgets = q6afe_dai_widgets,
1587	.num_dapm_widgets = ARRAY_SIZE(q6afe_dai_widgets),
1588	.dapm_routes = q6afe_dapm_routes,
1589	.num_dapm_routes = ARRAY_SIZE(q6afe_dapm_routes),
1590	.of_xlate_dai_name = q6afe_of_xlate_dai_name,
1591
1592};
1593
1594static void of_q6afe_parse_dai_data(struct device *dev,
1595				    struct q6afe_dai_data *data)
1596{
1597	struct device_node *node;
1598	int ret;
1599
1600	for_each_child_of_node(dev->of_node, node) {
1601		unsigned int lines[Q6AFE_MAX_MI2S_LINES];
1602		struct q6afe_dai_priv_data *priv;
1603		int id, i, num_lines;
1604
1605		ret = of_property_read_u32(node, "reg", &id);
1606		if (ret || id < 0 || id >= AFE_PORT_MAX) {
1607			dev_err(dev, "valid dai id not found:%d\n", ret);
1608			continue;
1609		}
1610
1611		switch (id) {
1612		/* MI2S specific properties */
1613		case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
1614			priv = &data->priv[id];
1615			ret = of_property_read_variable_u32_array(node,
1616							"qcom,sd-lines",
1617							lines, 0,
1618							Q6AFE_MAX_MI2S_LINES);
1619			if (ret < 0)
1620				num_lines = 0;
1621			else
1622				num_lines = ret;
1623
1624			priv->sd_line_mask = 0;
1625
1626			for (i = 0; i < num_lines; i++)
1627				priv->sd_line_mask |= BIT(lines[i]);
1628
1629			break;
1630		case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
1631			priv = &data->priv[id];
1632			ret = of_property_read_u32(node, "qcom,tdm-sync-mode",
1633						   &priv->sync_mode);
1634			if (ret) {
1635				dev_err(dev, "No Sync mode from DT\n");
1636				break;
1637			}
1638			ret = of_property_read_u32(node, "qcom,tdm-sync-src",
1639						   &priv->sync_src);
1640			if (ret) {
1641				dev_err(dev, "No Sync Src from DT\n");
1642				break;
1643			}
1644			ret = of_property_read_u32(node, "qcom,tdm-data-out",
1645						   &priv->data_out_enable);
1646			if (ret) {
1647				dev_err(dev, "No Data out enable from DT\n");
1648				break;
1649			}
1650			ret = of_property_read_u32(node, "qcom,tdm-invert-sync",
1651						   &priv->invert_sync);
1652			if (ret) {
1653				dev_err(dev, "No Invert sync from DT\n");
1654				break;
1655			}
1656			ret = of_property_read_u32(node, "qcom,tdm-data-delay",
1657						   &priv->data_delay);
1658			if (ret) {
1659				dev_err(dev, "No Data Delay from DT\n");
1660				break;
1661			}
1662			ret = of_property_read_u32(node, "qcom,tdm-data-align",
1663						   &priv->data_align);
1664			if (ret) {
1665				dev_err(dev, "No Data align from DT\n");
1666				break;
1667			}
1668			break;
1669		default:
1670			break;
1671		}
1672	}
1673}
1674
1675static int q6afe_dai_dev_probe(struct platform_device *pdev)
1676{
1677	struct q6afe_dai_data *dai_data;
1678	struct device *dev = &pdev->dev;
1679
1680	dai_data = devm_kzalloc(dev, sizeof(*dai_data), GFP_KERNEL);
1681	if (!dai_data)
1682		return -ENOMEM;
1683
1684	dev_set_drvdata(dev, dai_data);
1685
1686	of_q6afe_parse_dai_data(dev, dai_data);
1687
1688	return devm_snd_soc_register_component(dev, &q6afe_dai_component,
1689					  q6afe_dais, ARRAY_SIZE(q6afe_dais));
1690}
1691
1692#ifdef CONFIG_OF
1693static const struct of_device_id q6afe_dai_device_id[] = {
1694	{ .compatible = "qcom,q6afe-dais" },
1695	{},
1696};
1697MODULE_DEVICE_TABLE(of, q6afe_dai_device_id);
1698#endif
1699
1700static struct platform_driver q6afe_dai_platform_driver = {
1701	.driver = {
1702		.name = "q6afe-dai",
1703		.of_match_table = of_match_ptr(q6afe_dai_device_id),
1704	},
1705	.probe = q6afe_dai_dev_probe,
1706};
1707module_platform_driver(q6afe_dai_platform_driver);
1708
1709MODULE_DESCRIPTION("Q6 Audio Fronend dai driver");
1710MODULE_LICENSE("GPL v2");
1711