xref: /linux/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c (revision b3dff59e57a2d7c319590afe127a541917a06e1f)
13a280ed1SRyder Lee // SPDX-License-Identifier: GPL-2.0
243a6a7e7SGarlic Tseng /*
343a6a7e7SGarlic Tseng  * Mediatek ALSA SoC AFE platform driver for 2701
443a6a7e7SGarlic Tseng  *
543a6a7e7SGarlic Tseng  * Copyright (c) 2016 MediaTek Inc.
643a6a7e7SGarlic Tseng  * Author: Garlic Tseng <garlic.tseng@mediatek.com>
743a6a7e7SGarlic Tseng  *	   Ir Lian <ir.lian@mediatek.com>
8cf870273SRyder Lee  *	   Ryder Lee <ryder.lee@mediatek.com>
943a6a7e7SGarlic Tseng  */
1043a6a7e7SGarlic Tseng 
1143a6a7e7SGarlic Tseng #include <linux/delay.h>
1243a6a7e7SGarlic Tseng #include <linux/module.h>
13dfa3cbb8SRyder Lee #include <linux/mfd/syscon.h>
1443a6a7e7SGarlic Tseng #include <linux/of.h>
1543a6a7e7SGarlic Tseng #include <linux/of_address.h>
16bfdc56e5SRyder Lee #include <linux/of_device.h>
1743a6a7e7SGarlic Tseng #include <linux/pm_runtime.h>
1843a6a7e7SGarlic Tseng 
1943a6a7e7SGarlic Tseng #include "mt2701-afe-common.h"
2043a6a7e7SGarlic Tseng #include "mt2701-afe-clock-ctrl.h"
2143a6a7e7SGarlic Tseng #include "../common/mtk-afe-platform-driver.h"
2243a6a7e7SGarlic Tseng #include "../common/mtk-afe-fe-dai.h"
2343a6a7e7SGarlic Tseng 
2443a6a7e7SGarlic Tseng static const struct snd_pcm_hardware mt2701_afe_hardware = {
2543a6a7e7SGarlic Tseng 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
2643a6a7e7SGarlic Tseng 		| SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
2743a6a7e7SGarlic Tseng 	.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
2843a6a7e7SGarlic Tseng 		   | SNDRV_PCM_FMTBIT_S32_LE,
2943a6a7e7SGarlic Tseng 	.period_bytes_min = 1024,
3043a6a7e7SGarlic Tseng 	.period_bytes_max = 1024 * 256,
3143a6a7e7SGarlic Tseng 	.periods_min = 4,
3243a6a7e7SGarlic Tseng 	.periods_max = 1024,
33bfdc56e5SRyder Lee 	.buffer_bytes_max = 1024 * 1024,
3443a6a7e7SGarlic Tseng 	.fifo_size = 0,
3543a6a7e7SGarlic Tseng };
3643a6a7e7SGarlic Tseng 
3743a6a7e7SGarlic Tseng struct mt2701_afe_rate {
3843a6a7e7SGarlic Tseng 	unsigned int rate;
3943a6a7e7SGarlic Tseng 	unsigned int regvalue;
4043a6a7e7SGarlic Tseng };
4143a6a7e7SGarlic Tseng 
4243a6a7e7SGarlic Tseng static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
4343a6a7e7SGarlic Tseng 	{ .rate = 8000, .regvalue = 0 },
4443a6a7e7SGarlic Tseng 	{ .rate = 12000, .regvalue = 1 },
4543a6a7e7SGarlic Tseng 	{ .rate = 16000, .regvalue = 2 },
4643a6a7e7SGarlic Tseng 	{ .rate = 24000, .regvalue = 3 },
4743a6a7e7SGarlic Tseng 	{ .rate = 32000, .regvalue = 4 },
4843a6a7e7SGarlic Tseng 	{ .rate = 48000, .regvalue = 5 },
4943a6a7e7SGarlic Tseng 	{ .rate = 96000, .regvalue = 6 },
5043a6a7e7SGarlic Tseng 	{ .rate = 192000, .regvalue = 7 },
5143a6a7e7SGarlic Tseng 	{ .rate = 384000, .regvalue = 8 },
5243a6a7e7SGarlic Tseng 	{ .rate = 7350, .regvalue = 16 },
5343a6a7e7SGarlic Tseng 	{ .rate = 11025, .regvalue = 17 },
5443a6a7e7SGarlic Tseng 	{ .rate = 14700, .regvalue = 18 },
5543a6a7e7SGarlic Tseng 	{ .rate = 22050, .regvalue = 19 },
5643a6a7e7SGarlic Tseng 	{ .rate = 29400, .regvalue = 20 },
5743a6a7e7SGarlic Tseng 	{ .rate = 44100, .regvalue = 21 },
5843a6a7e7SGarlic Tseng 	{ .rate = 88200, .regvalue = 22 },
5943a6a7e7SGarlic Tseng 	{ .rate = 176400, .regvalue = 23 },
6043a6a7e7SGarlic Tseng 	{ .rate = 352800, .regvalue = 24 },
6143a6a7e7SGarlic Tseng };
6243a6a7e7SGarlic Tseng 
6397aad5ceSYueHaibing static const unsigned int mt2701_afe_backup_list[] = {
6497aad5ceSYueHaibing 	AUDIO_TOP_CON0,
6597aad5ceSYueHaibing 	AUDIO_TOP_CON4,
6697aad5ceSYueHaibing 	AUDIO_TOP_CON5,
6797aad5ceSYueHaibing 	ASYS_TOP_CON,
6897aad5ceSYueHaibing 	AFE_CONN0,
6997aad5ceSYueHaibing 	AFE_CONN1,
7097aad5ceSYueHaibing 	AFE_CONN2,
7197aad5ceSYueHaibing 	AFE_CONN3,
7297aad5ceSYueHaibing 	AFE_CONN15,
7397aad5ceSYueHaibing 	AFE_CONN16,
7497aad5ceSYueHaibing 	AFE_CONN17,
7597aad5ceSYueHaibing 	AFE_CONN18,
7697aad5ceSYueHaibing 	AFE_CONN19,
7797aad5ceSYueHaibing 	AFE_CONN20,
7897aad5ceSYueHaibing 	AFE_CONN21,
7997aad5ceSYueHaibing 	AFE_CONN22,
8097aad5ceSYueHaibing 	AFE_DAC_CON0,
8197aad5ceSYueHaibing 	AFE_MEMIF_PBUF_SIZE,
8297aad5ceSYueHaibing };
8397aad5ceSYueHaibing 
8425d01dc6SWei Yongjun static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
8543a6a7e7SGarlic Tseng {
86bfdc56e5SRyder Lee 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
8743a6a7e7SGarlic Tseng 	int val = num - MT2701_IO_I2S;
8843a6a7e7SGarlic Tseng 
89bfdc56e5SRyder Lee 	if (val < 0 || val >= afe_priv->soc->i2s_num) {
9043a6a7e7SGarlic Tseng 		dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
9143a6a7e7SGarlic Tseng 			__func__, num, val);
9243a6a7e7SGarlic Tseng 		return -EINVAL;
9343a6a7e7SGarlic Tseng 	}
9443a6a7e7SGarlic Tseng 	return val;
9543a6a7e7SGarlic Tseng }
9643a6a7e7SGarlic Tseng 
9743a6a7e7SGarlic Tseng static int mt2701_afe_i2s_fs(unsigned int sample_rate)
9843a6a7e7SGarlic Tseng {
9943a6a7e7SGarlic Tseng 	int i;
10043a6a7e7SGarlic Tseng 
10143a6a7e7SGarlic Tseng 	for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)
10243a6a7e7SGarlic Tseng 		if (mt2701_afe_i2s_rates[i].rate == sample_rate)
10343a6a7e7SGarlic Tseng 			return mt2701_afe_i2s_rates[i].regvalue;
10443a6a7e7SGarlic Tseng 
10543a6a7e7SGarlic Tseng 	return -EINVAL;
10643a6a7e7SGarlic Tseng }
10743a6a7e7SGarlic Tseng 
10843a6a7e7SGarlic Tseng static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
10943a6a7e7SGarlic Tseng 				  struct snd_soc_dai *dai)
11043a6a7e7SGarlic Tseng {
111e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
112bfdc56e5SRyder Lee 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
11343a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
114bfdc56e5SRyder Lee 	bool mode = afe_priv->soc->has_one_heart_mode;
11543a6a7e7SGarlic Tseng 
11643a6a7e7SGarlic Tseng 	if (i2s_num < 0)
11743a6a7e7SGarlic Tseng 		return i2s_num;
11843a6a7e7SGarlic Tseng 
119bfdc56e5SRyder Lee 	return mt2701_afe_enable_mclk(afe, mode ? 1 : i2s_num);
12043a6a7e7SGarlic Tseng }
12143a6a7e7SGarlic Tseng 
122cf870273SRyder Lee static int mt2701_afe_i2s_path_disable(struct mtk_base_afe *afe,
123cf870273SRyder Lee 				       struct mt2701_i2s_path *i2s_path,
124cf870273SRyder Lee 				       int stream_dir)
12543a6a7e7SGarlic Tseng {
126cf870273SRyder Lee 	const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];
12743a6a7e7SGarlic Tseng 
128cf870273SRyder Lee 	if (--i2s_path->on[stream_dir] < 0)
12943a6a7e7SGarlic Tseng 		i2s_path->on[stream_dir] = 0;
130cf870273SRyder Lee 
13143a6a7e7SGarlic Tseng 	if (i2s_path->on[stream_dir])
13243a6a7e7SGarlic Tseng 		return 0;
13343a6a7e7SGarlic Tseng 
13443a6a7e7SGarlic Tseng 	/* disable i2s */
13543a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
13643a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_I2S_EN, 0);
137d8d99d8eSRyder Lee 
138cf870273SRyder Lee 	mt2701_afe_disable_i2s(afe, i2s_path, stream_dir);
139d8d99d8eSRyder Lee 
14043a6a7e7SGarlic Tseng 	return 0;
14143a6a7e7SGarlic Tseng }
14243a6a7e7SGarlic Tseng 
14343a6a7e7SGarlic Tseng static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
14443a6a7e7SGarlic Tseng 				    struct snd_soc_dai *dai)
14543a6a7e7SGarlic Tseng {
146e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
14743a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
14843a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
14943a6a7e7SGarlic Tseng 	struct mt2701_i2s_path *i2s_path;
150bfdc56e5SRyder Lee 	bool mode = afe_priv->soc->has_one_heart_mode;
15143a6a7e7SGarlic Tseng 
15243a6a7e7SGarlic Tseng 	if (i2s_num < 0)
15343a6a7e7SGarlic Tseng 		return;
15443a6a7e7SGarlic Tseng 
15543a6a7e7SGarlic Tseng 	i2s_path = &afe_priv->i2s_path[i2s_num];
15643a6a7e7SGarlic Tseng 
15743a6a7e7SGarlic Tseng 	if (i2s_path->occupied[substream->stream])
15843a6a7e7SGarlic Tseng 		i2s_path->occupied[substream->stream] = 0;
15943a6a7e7SGarlic Tseng 	else
160cf870273SRyder Lee 		goto exit;
16143a6a7e7SGarlic Tseng 
162cf870273SRyder Lee 	mt2701_afe_i2s_path_disable(afe, i2s_path, substream->stream);
16343a6a7e7SGarlic Tseng 
16443a6a7e7SGarlic Tseng 	/* need to disable i2s-out path when disable i2s-in */
16543a6a7e7SGarlic Tseng 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
166cf870273SRyder Lee 		mt2701_afe_i2s_path_disable(afe, i2s_path, !substream->stream);
16743a6a7e7SGarlic Tseng 
168cf870273SRyder Lee exit:
16943a6a7e7SGarlic Tseng 	/* disable mclk */
170bfdc56e5SRyder Lee 	mt2701_afe_disable_mclk(afe, mode ? 1 : i2s_num);
17143a6a7e7SGarlic Tseng }
17243a6a7e7SGarlic Tseng 
173cf870273SRyder Lee static int mt2701_i2s_path_enable(struct mtk_base_afe *afe,
174cf870273SRyder Lee 				  struct mt2701_i2s_path *i2s_path,
175cf870273SRyder Lee 				  int stream_dir, int rate)
17643a6a7e7SGarlic Tseng {
177cf870273SRyder Lee 	const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];
178bfdc56e5SRyder Lee 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
17943a6a7e7SGarlic Tseng 	int reg, fs, w_len = 1; /* now we support bck 64bits only */
180e4b31b81SRyder Lee 	unsigned int mask, val;
18143a6a7e7SGarlic Tseng 
18243a6a7e7SGarlic Tseng 	/* no need to enable if already done */
183cf870273SRyder Lee 	if (++i2s_path->on[stream_dir] != 1)
18443a6a7e7SGarlic Tseng 		return 0;
18543a6a7e7SGarlic Tseng 
186cf870273SRyder Lee 	fs = mt2701_afe_i2s_fs(rate);
18743a6a7e7SGarlic Tseng 
18843a6a7e7SGarlic Tseng 	mask = ASYS_I2S_CON_FS |
18943a6a7e7SGarlic Tseng 	       ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */
19043a6a7e7SGarlic Tseng 	       ASYS_I2S_CON_I2S_MODE |
19143a6a7e7SGarlic Tseng 	       ASYS_I2S_CON_WIDE_MODE;
19243a6a7e7SGarlic Tseng 
19343a6a7e7SGarlic Tseng 	val = ASYS_I2S_CON_FS_SET(fs) |
19443a6a7e7SGarlic Tseng 	      ASYS_I2S_CON_I2S_MODE |
19543a6a7e7SGarlic Tseng 	      ASYS_I2S_CON_WIDE_MODE_SET(w_len);
19643a6a7e7SGarlic Tseng 
19743a6a7e7SGarlic Tseng 	if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) {
19843a6a7e7SGarlic Tseng 		mask |= ASYS_I2S_IN_PHASE_FIX;
19943a6a7e7SGarlic Tseng 		val |= ASYS_I2S_IN_PHASE_FIX;
200cf870273SRyder Lee 		reg = ASMI_TIMING_CON1;
201cf870273SRyder Lee 	} else {
202bfdc56e5SRyder Lee 		if (afe_priv->soc->has_one_heart_mode) {
203bfdc56e5SRyder Lee 			mask |= ASYS_I2S_CON_ONE_HEART_MODE;
204bfdc56e5SRyder Lee 			val |= ASYS_I2S_CON_ONE_HEART_MODE;
205bfdc56e5SRyder Lee 		}
206cf870273SRyder Lee 		reg = ASMO_TIMING_CON1;
20743a6a7e7SGarlic Tseng 	}
20843a6a7e7SGarlic Tseng 
20943a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val);
21043a6a7e7SGarlic Tseng 
21143a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, reg,
21243a6a7e7SGarlic Tseng 			   i2s_data->i2s_asrc_fs_mask
21343a6a7e7SGarlic Tseng 			   << i2s_data->i2s_asrc_fs_shift,
21443a6a7e7SGarlic Tseng 			   fs << i2s_data->i2s_asrc_fs_shift);
21543a6a7e7SGarlic Tseng 
21643a6a7e7SGarlic Tseng 	/* enable i2s */
217cf870273SRyder Lee 	mt2701_afe_enable_i2s(afe, i2s_path, stream_dir);
21843a6a7e7SGarlic Tseng 
21943a6a7e7SGarlic Tseng 	/* reset i2s hw status before enable */
22043a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
22143a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET);
22243a6a7e7SGarlic Tseng 	udelay(1);
22343a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
22443a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_RESET, 0);
22543a6a7e7SGarlic Tseng 	udelay(1);
22643a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
22743a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN);
22843a6a7e7SGarlic Tseng 	return 0;
22943a6a7e7SGarlic Tseng }
23043a6a7e7SGarlic Tseng 
23143a6a7e7SGarlic Tseng static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
23243a6a7e7SGarlic Tseng 				  struct snd_soc_dai *dai)
23343a6a7e7SGarlic Tseng {
234e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
23543a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
236cf870273SRyder Lee 	int ret, i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
23743a6a7e7SGarlic Tseng 	struct mt2701_i2s_path *i2s_path;
238bfdc56e5SRyder Lee 	bool mode = afe_priv->soc->has_one_heart_mode;
23943a6a7e7SGarlic Tseng 
24043a6a7e7SGarlic Tseng 	if (i2s_num < 0)
24143a6a7e7SGarlic Tseng 		return i2s_num;
24243a6a7e7SGarlic Tseng 
24343a6a7e7SGarlic Tseng 	i2s_path = &afe_priv->i2s_path[i2s_num];
24443a6a7e7SGarlic Tseng 
24543a6a7e7SGarlic Tseng 	if (i2s_path->occupied[substream->stream])
24643a6a7e7SGarlic Tseng 		return -EBUSY;
247cf870273SRyder Lee 
248bfdc56e5SRyder Lee 	ret = mt2701_mclk_configuration(afe, mode ? 1 : i2s_num);
249cf870273SRyder Lee 	if (ret)
250cf870273SRyder Lee 		return ret;
251cf870273SRyder Lee 
25243a6a7e7SGarlic Tseng 	i2s_path->occupied[substream->stream] = 1;
25343a6a7e7SGarlic Tseng 
25443a6a7e7SGarlic Tseng 	/* need to enable i2s-out path when enable i2s-in */
255cf870273SRyder Lee 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
256cf870273SRyder Lee 		mt2701_i2s_path_enable(afe, i2s_path, !substream->stream,
257cf870273SRyder Lee 				       substream->runtime->rate);
258cf870273SRyder Lee 
259cf870273SRyder Lee 	mt2701_i2s_path_enable(afe, i2s_path, substream->stream,
260cf870273SRyder Lee 			       substream->runtime->rate);
26143a6a7e7SGarlic Tseng 
26243a6a7e7SGarlic Tseng 	return 0;
26343a6a7e7SGarlic Tseng }
26443a6a7e7SGarlic Tseng 
26543a6a7e7SGarlic Tseng static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
26643a6a7e7SGarlic Tseng 				     unsigned int freq, int dir)
26743a6a7e7SGarlic Tseng {
268e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
26943a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
27043a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
271bfdc56e5SRyder Lee 	bool mode = afe_priv->soc->has_one_heart_mode;
27243a6a7e7SGarlic Tseng 
27343a6a7e7SGarlic Tseng 	if (i2s_num < 0)
27443a6a7e7SGarlic Tseng 		return i2s_num;
27543a6a7e7SGarlic Tseng 
27643a6a7e7SGarlic Tseng 	/* mclk */
27743a6a7e7SGarlic Tseng 	if (dir == SND_SOC_CLOCK_IN) {
278bfdc56e5SRyder Lee 		dev_warn(dai->dev, "The SoCs doesn't support mclk input\n");
27943a6a7e7SGarlic Tseng 		return -EINVAL;
28043a6a7e7SGarlic Tseng 	}
281e4b31b81SRyder Lee 
282bfdc56e5SRyder Lee 	afe_priv->i2s_path[mode ? 1 : i2s_num].mclk_rate = freq;
283e4b31b81SRyder Lee 
28443a6a7e7SGarlic Tseng 	return 0;
28543a6a7e7SGarlic Tseng }
28643a6a7e7SGarlic Tseng 
2874bdc8d45SGarlic Tseng static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
2884bdc8d45SGarlic Tseng 				struct snd_soc_dai *dai)
2894bdc8d45SGarlic Tseng {
290e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
2914bdc8d45SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
292d8d99d8eSRyder Lee 	int ret;
2934bdc8d45SGarlic Tseng 
294d8d99d8eSRyder Lee 	ret = mt2701_enable_btmrg_clk(afe);
295d8d99d8eSRyder Lee 	if (ret)
296d8d99d8eSRyder Lee 		return ret;
2974bdc8d45SGarlic Tseng 
2984bdc8d45SGarlic Tseng 	afe_priv->mrg_enable[substream->stream] = 1;
299e4b31b81SRyder Lee 
3004bdc8d45SGarlic Tseng 	return 0;
3014bdc8d45SGarlic Tseng }
3024bdc8d45SGarlic Tseng 
3034bdc8d45SGarlic Tseng static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
3044bdc8d45SGarlic Tseng 				  struct snd_pcm_hw_params *params,
3054bdc8d45SGarlic Tseng 				  struct snd_soc_dai *dai)
3064bdc8d45SGarlic Tseng {
307e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
3084bdc8d45SGarlic Tseng 	int stream_fs;
3094bdc8d45SGarlic Tseng 	u32 val, msk;
3104bdc8d45SGarlic Tseng 
3114bdc8d45SGarlic Tseng 	stream_fs = params_rate(params);
3124bdc8d45SGarlic Tseng 
313e4b31b81SRyder Lee 	if (stream_fs != 8000 && stream_fs != 16000) {
314e4b31b81SRyder Lee 		dev_err(afe->dev, "unsupported rate %d\n", stream_fs);
3154bdc8d45SGarlic Tseng 		return -EINVAL;
3164bdc8d45SGarlic Tseng 	}
3174bdc8d45SGarlic Tseng 
3184bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3194bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_I2S_MODE_MASK,
3204bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_I2S_MODE_32K);
3214bdc8d45SGarlic Tseng 
3224bdc8d45SGarlic Tseng 	val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY
3234bdc8d45SGarlic Tseng 	      | AFE_DAIBT_CON0_MRG_USE;
3244bdc8d45SGarlic Tseng 	msk = val;
3254bdc8d45SGarlic Tseng 
3264bdc8d45SGarlic Tseng 	if (stream_fs == 16000)
3274bdc8d45SGarlic Tseng 		val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
3284bdc8d45SGarlic Tseng 
3294bdc8d45SGarlic Tseng 	msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
3304bdc8d45SGarlic Tseng 
3314bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);
3324bdc8d45SGarlic Tseng 
3334bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
3344bdc8d45SGarlic Tseng 			   AFE_DAIBT_CON0_DAIBT_EN,
3354bdc8d45SGarlic Tseng 			   AFE_DAIBT_CON0_DAIBT_EN);
3364bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3374bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_I2S_EN,
3384bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_I2S_EN);
3394bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3404bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_EN,
3414bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_EN);
3424bdc8d45SGarlic Tseng 	return 0;
3434bdc8d45SGarlic Tseng }
3444bdc8d45SGarlic Tseng 
3454bdc8d45SGarlic Tseng static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
3464bdc8d45SGarlic Tseng 				  struct snd_soc_dai *dai)
3474bdc8d45SGarlic Tseng {
348e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
3494bdc8d45SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
3504bdc8d45SGarlic Tseng 
3514bdc8d45SGarlic Tseng 	/* if the other direction stream is not occupied */
3524bdc8d45SGarlic Tseng 	if (!afe_priv->mrg_enable[!substream->stream]) {
3534bdc8d45SGarlic Tseng 		regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
3544bdc8d45SGarlic Tseng 				   AFE_DAIBT_CON0_DAIBT_EN, 0);
3554bdc8d45SGarlic Tseng 		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3564bdc8d45SGarlic Tseng 				   AFE_MRGIF_CON_MRG_EN, 0);
3574bdc8d45SGarlic Tseng 		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3584bdc8d45SGarlic Tseng 				   AFE_MRGIF_CON_MRG_I2S_EN, 0);
359d8d99d8eSRyder Lee 		mt2701_disable_btmrg_clk(afe);
3604bdc8d45SGarlic Tseng 	}
361e4b31b81SRyder Lee 
3624bdc8d45SGarlic Tseng 	afe_priv->mrg_enable[substream->stream] = 0;
3634bdc8d45SGarlic Tseng }
3644bdc8d45SGarlic Tseng 
36543a6a7e7SGarlic Tseng static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
36643a6a7e7SGarlic Tseng 				    struct snd_soc_dai *dai)
36743a6a7e7SGarlic Tseng {
368e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
36943a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif_tmp;
370e4b31b81SRyder Lee 	int stream_dir = substream->stream;
37143a6a7e7SGarlic Tseng 
37243a6a7e7SGarlic Tseng 	/* can't run single DL & DLM at the same time */
37343a6a7e7SGarlic Tseng 	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
37443a6a7e7SGarlic Tseng 		memif_tmp = &afe->memif[MT2701_MEMIF_DLM];
37543a6a7e7SGarlic Tseng 		if (memif_tmp->substream) {
376e4b31b81SRyder Lee 			dev_warn(afe->dev, "memif is not available");
37743a6a7e7SGarlic Tseng 			return -EBUSY;
37843a6a7e7SGarlic Tseng 		}
37943a6a7e7SGarlic Tseng 	}
380e4b31b81SRyder Lee 
38143a6a7e7SGarlic Tseng 	return mtk_afe_fe_startup(substream, dai);
38243a6a7e7SGarlic Tseng }
38343a6a7e7SGarlic Tseng 
38443a6a7e7SGarlic Tseng static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
38543a6a7e7SGarlic Tseng 				      struct snd_pcm_hw_params *params,
38643a6a7e7SGarlic Tseng 				      struct snd_soc_dai *dai)
38743a6a7e7SGarlic Tseng {
388e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
38943a6a7e7SGarlic Tseng 	int stream_dir = substream->stream;
39043a6a7e7SGarlic Tseng 
39143a6a7e7SGarlic Tseng 	/* single DL use PAIR_INTERLEAVE */
392e4b31b81SRyder Lee 	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
39343a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap,
39443a6a7e7SGarlic Tseng 				   AFE_MEMIF_PBUF_SIZE,
39543a6a7e7SGarlic Tseng 				   AFE_MEMIF_PBUF_SIZE_DLM_MASK,
39643a6a7e7SGarlic Tseng 				   AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE);
397e4b31b81SRyder Lee 
39843a6a7e7SGarlic Tseng 	return mtk_afe_fe_hw_params(substream, params, dai);
39943a6a7e7SGarlic Tseng }
40043a6a7e7SGarlic Tseng 
40143a6a7e7SGarlic Tseng static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
40243a6a7e7SGarlic Tseng 				 struct snd_soc_dai *dai)
40343a6a7e7SGarlic Tseng {
404e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
40543a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif_tmp;
40643a6a7e7SGarlic Tseng 	const struct mtk_base_memif_data *memif_data;
40743a6a7e7SGarlic Tseng 	int i;
40843a6a7e7SGarlic Tseng 
40943a6a7e7SGarlic Tseng 	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
41043a6a7e7SGarlic Tseng 		memif_tmp = &afe->memif[i];
41143a6a7e7SGarlic Tseng 		if (memif_tmp->substream)
41243a6a7e7SGarlic Tseng 			return -EBUSY;
41343a6a7e7SGarlic Tseng 	}
41443a6a7e7SGarlic Tseng 
41543a6a7e7SGarlic Tseng 	/* enable agent for all signal DL (due to hw design) */
41643a6a7e7SGarlic Tseng 	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
41743a6a7e7SGarlic Tseng 		memif_data = afe->memif[i].data;
41843a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap,
41943a6a7e7SGarlic Tseng 				   memif_data->agent_disable_reg,
42043a6a7e7SGarlic Tseng 				   1 << memif_data->agent_disable_shift,
42143a6a7e7SGarlic Tseng 				   0 << memif_data->agent_disable_shift);
42243a6a7e7SGarlic Tseng 	}
42343a6a7e7SGarlic Tseng 
42443a6a7e7SGarlic Tseng 	return mtk_afe_fe_startup(substream, dai);
42543a6a7e7SGarlic Tseng }
42643a6a7e7SGarlic Tseng 
42743a6a7e7SGarlic Tseng static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
42843a6a7e7SGarlic Tseng 				   struct snd_soc_dai *dai)
42943a6a7e7SGarlic Tseng {
430e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
43143a6a7e7SGarlic Tseng 	const struct mtk_base_memif_data *memif_data;
43243a6a7e7SGarlic Tseng 	int i;
43343a6a7e7SGarlic Tseng 
43443a6a7e7SGarlic Tseng 	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
43543a6a7e7SGarlic Tseng 		memif_data = afe->memif[i].data;
43643a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap,
43743a6a7e7SGarlic Tseng 				   memif_data->agent_disable_reg,
43843a6a7e7SGarlic Tseng 				   1 << memif_data->agent_disable_shift,
43943a6a7e7SGarlic Tseng 				   1 << memif_data->agent_disable_shift);
44043a6a7e7SGarlic Tseng 	}
441e4b31b81SRyder Lee 
44243a6a7e7SGarlic Tseng 	return mtk_afe_fe_shutdown(substream, dai);
44343a6a7e7SGarlic Tseng }
44443a6a7e7SGarlic Tseng 
44543a6a7e7SGarlic Tseng static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
44643a6a7e7SGarlic Tseng 				   struct snd_pcm_hw_params *params,
44743a6a7e7SGarlic Tseng 				   struct snd_soc_dai *dai)
44843a6a7e7SGarlic Tseng {
449e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
45043a6a7e7SGarlic Tseng 	int channels = params_channels(params);
45143a6a7e7SGarlic Tseng 
45243a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap,
45343a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE,
45443a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_MASK,
45543a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE);
45643a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap,
45743a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE,
45843a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK,
45943a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_32BYTES);
46043a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap,
46143a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE,
46243a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK,
46343a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_CH(channels));
46443a6a7e7SGarlic Tseng 
46543a6a7e7SGarlic Tseng 	return mtk_afe_fe_hw_params(substream, params, dai);
46643a6a7e7SGarlic Tseng }
46743a6a7e7SGarlic Tseng 
46843a6a7e7SGarlic Tseng static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
46943a6a7e7SGarlic Tseng 				 int cmd, struct snd_soc_dai *dai)
47043a6a7e7SGarlic Tseng {
471e4b31b81SRyder Lee 	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
47243a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
47343a6a7e7SGarlic Tseng 
47443a6a7e7SGarlic Tseng 	switch (cmd) {
47543a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_START:
47643a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_RESUME:
47743a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
47843a6a7e7SGarlic Tseng 				   1 << memif_tmp->data->enable_shift,
47943a6a7e7SGarlic Tseng 				   1 << memif_tmp->data->enable_shift);
48043a6a7e7SGarlic Tseng 		mtk_afe_fe_trigger(substream, cmd, dai);
48143a6a7e7SGarlic Tseng 		return 0;
48243a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_STOP:
48343a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_SUSPEND:
48443a6a7e7SGarlic Tseng 		mtk_afe_fe_trigger(substream, cmd, dai);
48543a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
48643a6a7e7SGarlic Tseng 				   1 << memif_tmp->data->enable_shift, 0);
48743a6a7e7SGarlic Tseng 
48843a6a7e7SGarlic Tseng 		return 0;
48943a6a7e7SGarlic Tseng 	default:
49043a6a7e7SGarlic Tseng 		return -EINVAL;
49143a6a7e7SGarlic Tseng 	}
49243a6a7e7SGarlic Tseng }
49343a6a7e7SGarlic Tseng 
49443a6a7e7SGarlic Tseng static int mt2701_memif_fs(struct snd_pcm_substream *substream,
49543a6a7e7SGarlic Tseng 			   unsigned int rate)
49643a6a7e7SGarlic Tseng {
4970cd08b10SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
49843a6a7e7SGarlic Tseng 	int fs;
49943a6a7e7SGarlic Tseng 
500c8ac8212SKuninori Morimoto 	if (asoc_rtd_to_cpu(rtd, 0)->id != MT2701_MEMIF_ULBT)
50143a6a7e7SGarlic Tseng 		fs = mt2701_afe_i2s_fs(rate);
50243a6a7e7SGarlic Tseng 	else
50343a6a7e7SGarlic Tseng 		fs = (rate == 16000 ? 1 : 0);
504e4b31b81SRyder Lee 
50543a6a7e7SGarlic Tseng 	return fs;
50643a6a7e7SGarlic Tseng }
50743a6a7e7SGarlic Tseng 
50843a6a7e7SGarlic Tseng static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
50943a6a7e7SGarlic Tseng {
51043a6a7e7SGarlic Tseng 	return mt2701_afe_i2s_fs(rate);
51143a6a7e7SGarlic Tseng }
51243a6a7e7SGarlic Tseng 
51343a6a7e7SGarlic Tseng /* FE DAIs */
51443a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = {
51543a6a7e7SGarlic Tseng 	.startup	= mt2701_simple_fe_startup,
51643a6a7e7SGarlic Tseng 	.shutdown	= mtk_afe_fe_shutdown,
51743a6a7e7SGarlic Tseng 	.hw_params	= mt2701_simple_fe_hw_params,
51843a6a7e7SGarlic Tseng 	.hw_free	= mtk_afe_fe_hw_free,
51943a6a7e7SGarlic Tseng 	.prepare	= mtk_afe_fe_prepare,
52043a6a7e7SGarlic Tseng 	.trigger	= mtk_afe_fe_trigger,
52143a6a7e7SGarlic Tseng };
52243a6a7e7SGarlic Tseng 
52343a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = {
52443a6a7e7SGarlic Tseng 	.startup	= mt2701_dlm_fe_startup,
52543a6a7e7SGarlic Tseng 	.shutdown	= mt2701_dlm_fe_shutdown,
52643a6a7e7SGarlic Tseng 	.hw_params	= mt2701_dlm_fe_hw_params,
52743a6a7e7SGarlic Tseng 	.hw_free	= mtk_afe_fe_hw_free,
52843a6a7e7SGarlic Tseng 	.prepare	= mtk_afe_fe_prepare,
52943a6a7e7SGarlic Tseng 	.trigger	= mt2701_dlm_fe_trigger,
53043a6a7e7SGarlic Tseng };
53143a6a7e7SGarlic Tseng 
53243a6a7e7SGarlic Tseng /* I2S BE DAIs */
53343a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {
53443a6a7e7SGarlic Tseng 	.startup	= mt2701_afe_i2s_startup,
53543a6a7e7SGarlic Tseng 	.shutdown	= mt2701_afe_i2s_shutdown,
53643a6a7e7SGarlic Tseng 	.prepare	= mt2701_afe_i2s_prepare,
53743a6a7e7SGarlic Tseng 	.set_sysclk	= mt2701_afe_i2s_set_sysclk,
53843a6a7e7SGarlic Tseng };
53943a6a7e7SGarlic Tseng 
5404bdc8d45SGarlic Tseng /* MRG BE DAIs */
541549acff9SGustavo A. R. Silva static const struct snd_soc_dai_ops mt2701_btmrg_ops = {
5424bdc8d45SGarlic Tseng 	.startup = mt2701_btmrg_startup,
5434bdc8d45SGarlic Tseng 	.shutdown = mt2701_btmrg_shutdown,
5444bdc8d45SGarlic Tseng 	.hw_params = mt2701_btmrg_hw_params,
5454bdc8d45SGarlic Tseng };
5464bdc8d45SGarlic Tseng 
54743a6a7e7SGarlic Tseng static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
54843a6a7e7SGarlic Tseng 	/* FE DAIs: memory intefaces to CPU */
54943a6a7e7SGarlic Tseng 	{
5508625c1dbSRyder Lee 		.name = "PCMO0",
5518625c1dbSRyder Lee 		.id = MT2701_MEMIF_DL1,
5528625c1dbSRyder Lee 		.playback = {
5538625c1dbSRyder Lee 			.stream_name = "DL1",
5548625c1dbSRyder Lee 			.channels_min = 1,
5558625c1dbSRyder Lee 			.channels_max = 2,
5568625c1dbSRyder Lee 			.rates = SNDRV_PCM_RATE_8000_192000,
5578625c1dbSRyder Lee 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
5588625c1dbSRyder Lee 				| SNDRV_PCM_FMTBIT_S24_LE
5598625c1dbSRyder Lee 				| SNDRV_PCM_FMTBIT_S32_LE)
5608625c1dbSRyder Lee 		},
5618625c1dbSRyder Lee 		.ops = &mt2701_single_memif_dai_ops,
5628625c1dbSRyder Lee 	},
5638625c1dbSRyder Lee 	{
56443a6a7e7SGarlic Tseng 		.name = "PCM_multi",
56543a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DLM,
56643a6a7e7SGarlic Tseng 		.playback = {
56743a6a7e7SGarlic Tseng 			.stream_name = "DLM",
56843a6a7e7SGarlic Tseng 			.channels_min = 1,
56943a6a7e7SGarlic Tseng 			.channels_max = 8,
57043a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
57143a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
57243a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
57343a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
57443a6a7e7SGarlic Tseng 
57543a6a7e7SGarlic Tseng 		},
57643a6a7e7SGarlic Tseng 		.ops = &mt2701_dlm_memif_dai_ops,
57743a6a7e7SGarlic Tseng 	},
57843a6a7e7SGarlic Tseng 	{
57943a6a7e7SGarlic Tseng 		.name = "PCM0",
58043a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL1,
58143a6a7e7SGarlic Tseng 		.capture = {
58243a6a7e7SGarlic Tseng 			.stream_name = "UL1",
58343a6a7e7SGarlic Tseng 			.channels_min = 1,
58443a6a7e7SGarlic Tseng 			.channels_max = 2,
58543a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_48000,
58643a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
58743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
58843a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
58943a6a7e7SGarlic Tseng 		},
59043a6a7e7SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
59143a6a7e7SGarlic Tseng 	},
59243a6a7e7SGarlic Tseng 	{
59343a6a7e7SGarlic Tseng 		.name = "PCM1",
59443a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL2,
59543a6a7e7SGarlic Tseng 		.capture = {
59643a6a7e7SGarlic Tseng 			.stream_name = "UL2",
59743a6a7e7SGarlic Tseng 			.channels_min = 1,
59843a6a7e7SGarlic Tseng 			.channels_max = 2,
59943a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
60043a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
60143a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
60243a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
60343a6a7e7SGarlic Tseng 
60443a6a7e7SGarlic Tseng 		},
60543a6a7e7SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
60643a6a7e7SGarlic Tseng 	},
6074bdc8d45SGarlic Tseng 	{
6084bdc8d45SGarlic Tseng 		.name = "PCM_BT_DL",
6094bdc8d45SGarlic Tseng 		.id = MT2701_MEMIF_DLBT,
6104bdc8d45SGarlic Tseng 		.playback = {
6114bdc8d45SGarlic Tseng 			.stream_name = "DLBT",
6124bdc8d45SGarlic Tseng 			.channels_min = 1,
6134bdc8d45SGarlic Tseng 			.channels_max = 1,
6144bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
6154bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
6164bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
6174bdc8d45SGarlic Tseng 		},
6184bdc8d45SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
6194bdc8d45SGarlic Tseng 	},
6204bdc8d45SGarlic Tseng 	{
6214bdc8d45SGarlic Tseng 		.name = "PCM_BT_UL",
6224bdc8d45SGarlic Tseng 		.id = MT2701_MEMIF_ULBT,
6234bdc8d45SGarlic Tseng 		.capture = {
6244bdc8d45SGarlic Tseng 			.stream_name = "ULBT",
6254bdc8d45SGarlic Tseng 			.channels_min = 1,
6264bdc8d45SGarlic Tseng 			.channels_max = 1,
6274bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
6284bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
6294bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
6304bdc8d45SGarlic Tseng 		},
6314bdc8d45SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
6324bdc8d45SGarlic Tseng 	},
63343a6a7e7SGarlic Tseng 	/* BE DAIs */
63443a6a7e7SGarlic Tseng 	{
63543a6a7e7SGarlic Tseng 		.name = "I2S0",
63643a6a7e7SGarlic Tseng 		.id = MT2701_IO_I2S,
63743a6a7e7SGarlic Tseng 		.playback = {
63843a6a7e7SGarlic Tseng 			.stream_name = "I2S0 Playback",
63943a6a7e7SGarlic Tseng 			.channels_min = 1,
64043a6a7e7SGarlic Tseng 			.channels_max = 2,
64143a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
64243a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
64343a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
64443a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
64543a6a7e7SGarlic Tseng 
64643a6a7e7SGarlic Tseng 		},
64743a6a7e7SGarlic Tseng 		.capture = {
64843a6a7e7SGarlic Tseng 			.stream_name = "I2S0 Capture",
64943a6a7e7SGarlic Tseng 			.channels_min = 1,
65043a6a7e7SGarlic Tseng 			.channels_max = 2,
65143a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
65243a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
65343a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
65443a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
65543a6a7e7SGarlic Tseng 
65643a6a7e7SGarlic Tseng 		},
65743a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
6584b7ead03SKuninori Morimoto 		.symmetric_rate = 1,
65943a6a7e7SGarlic Tseng 	},
66043a6a7e7SGarlic Tseng 	{
66143a6a7e7SGarlic Tseng 		.name = "I2S1",
66243a6a7e7SGarlic Tseng 		.id = MT2701_IO_2ND_I2S,
66343a6a7e7SGarlic Tseng 		.playback = {
66443a6a7e7SGarlic Tseng 			.stream_name = "I2S1 Playback",
66543a6a7e7SGarlic Tseng 			.channels_min = 1,
66643a6a7e7SGarlic Tseng 			.channels_max = 2,
66743a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
66843a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
66943a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
67043a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
67143a6a7e7SGarlic Tseng 			},
67243a6a7e7SGarlic Tseng 		.capture = {
67343a6a7e7SGarlic Tseng 			.stream_name = "I2S1 Capture",
67443a6a7e7SGarlic Tseng 			.channels_min = 1,
67543a6a7e7SGarlic Tseng 			.channels_max = 2,
67643a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
67743a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
67843a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
67943a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
68043a6a7e7SGarlic Tseng 			},
68143a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
6824b7ead03SKuninori Morimoto 		.symmetric_rate = 1,
68343a6a7e7SGarlic Tseng 	},
68443a6a7e7SGarlic Tseng 	{
68543a6a7e7SGarlic Tseng 		.name = "I2S2",
68643a6a7e7SGarlic Tseng 		.id = MT2701_IO_3RD_I2S,
68743a6a7e7SGarlic Tseng 		.playback = {
68843a6a7e7SGarlic Tseng 			.stream_name = "I2S2 Playback",
68943a6a7e7SGarlic Tseng 			.channels_min = 1,
69043a6a7e7SGarlic Tseng 			.channels_max = 2,
69143a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
69243a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
69343a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
69443a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
69543a6a7e7SGarlic Tseng 			},
69643a6a7e7SGarlic Tseng 		.capture = {
69743a6a7e7SGarlic Tseng 			.stream_name = "I2S2 Capture",
69843a6a7e7SGarlic Tseng 			.channels_min = 1,
69943a6a7e7SGarlic Tseng 			.channels_max = 2,
70043a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
70143a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
70243a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
70343a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
70443a6a7e7SGarlic Tseng 			},
70543a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
7064b7ead03SKuninori Morimoto 		.symmetric_rate = 1,
70743a6a7e7SGarlic Tseng 	},
70843a6a7e7SGarlic Tseng 	{
70943a6a7e7SGarlic Tseng 		.name = "I2S3",
71043a6a7e7SGarlic Tseng 		.id = MT2701_IO_4TH_I2S,
71143a6a7e7SGarlic Tseng 		.playback = {
71243a6a7e7SGarlic Tseng 			.stream_name = "I2S3 Playback",
71343a6a7e7SGarlic Tseng 			.channels_min = 1,
71443a6a7e7SGarlic Tseng 			.channels_max = 2,
71543a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
71643a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
71743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
71843a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
71943a6a7e7SGarlic Tseng 			},
72043a6a7e7SGarlic Tseng 		.capture = {
72143a6a7e7SGarlic Tseng 			.stream_name = "I2S3 Capture",
72243a6a7e7SGarlic Tseng 			.channels_min = 1,
72343a6a7e7SGarlic Tseng 			.channels_max = 2,
72443a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
72543a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
72643a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
72743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
72843a6a7e7SGarlic Tseng 			},
72943a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
7304b7ead03SKuninori Morimoto 		.symmetric_rate = 1,
73143a6a7e7SGarlic Tseng 	},
7324bdc8d45SGarlic Tseng 	{
7334bdc8d45SGarlic Tseng 		.name = "MRG BT",
7344bdc8d45SGarlic Tseng 		.id = MT2701_IO_MRG,
7354bdc8d45SGarlic Tseng 		.playback = {
7364bdc8d45SGarlic Tseng 			.stream_name = "BT Playback",
7374bdc8d45SGarlic Tseng 			.channels_min = 1,
7384bdc8d45SGarlic Tseng 			.channels_max = 1,
7394bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
7404bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
7414bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
7424bdc8d45SGarlic Tseng 		},
7434bdc8d45SGarlic Tseng 		.capture = {
7444bdc8d45SGarlic Tseng 			.stream_name = "BT Capture",
7454bdc8d45SGarlic Tseng 			.channels_min = 1,
7464bdc8d45SGarlic Tseng 			.channels_max = 1,
7474bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
7484bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
7494bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
7504bdc8d45SGarlic Tseng 		},
7514bdc8d45SGarlic Tseng 		.ops = &mt2701_btmrg_ops,
7524b7ead03SKuninori Morimoto 		.symmetric_rate = 1,
7534bdc8d45SGarlic Tseng 	}
75443a6a7e7SGarlic Tseng };
75543a6a7e7SGarlic Tseng 
75643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = {
75743a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0),
75843a6a7e7SGarlic Tseng };
75943a6a7e7SGarlic Tseng 
76043a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o01_mix[] = {
76143a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0),
76243a6a7e7SGarlic Tseng };
76343a6a7e7SGarlic Tseng 
76443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o02_mix[] = {
76543a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0),
76643a6a7e7SGarlic Tseng };
76743a6a7e7SGarlic Tseng 
76843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o03_mix[] = {
76943a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0),
77043a6a7e7SGarlic Tseng };
77143a6a7e7SGarlic Tseng 
77243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o14_mix[] = {
77343a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0),
77443a6a7e7SGarlic Tseng };
77543a6a7e7SGarlic Tseng 
77643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o15_mix[] = {
77743a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0),
77843a6a7e7SGarlic Tseng };
77943a6a7e7SGarlic Tseng 
78043a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o16_mix[] = {
78143a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0),
78243a6a7e7SGarlic Tseng };
78343a6a7e7SGarlic Tseng 
78443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o17_mix[] = {
78543a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0),
78643a6a7e7SGarlic Tseng };
78743a6a7e7SGarlic Tseng 
78843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o18_mix[] = {
78943a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0),
79043a6a7e7SGarlic Tseng };
79143a6a7e7SGarlic Tseng 
79243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o19_mix[] = {
79343a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0),
79443a6a7e7SGarlic Tseng };
79543a6a7e7SGarlic Tseng 
79643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o20_mix[] = {
79743a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0),
79843a6a7e7SGarlic Tseng };
79943a6a7e7SGarlic Tseng 
80043a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o21_mix[] = {
80143a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0),
80243a6a7e7SGarlic Tseng };
80343a6a7e7SGarlic Tseng 
80443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = {
80543a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),
80643a6a7e7SGarlic Tseng };
80743a6a7e7SGarlic Tseng 
80843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = {
80943a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0),
81043a6a7e7SGarlic Tseng };
81143a6a7e7SGarlic Tseng 
81243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_i02_mix[] = {
81343a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0),
81443a6a7e7SGarlic Tseng };
81543a6a7e7SGarlic Tseng 
81643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = {
81743a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch",
81843a6a7e7SGarlic Tseng 				    ASYS_I2SO1_CON, 26, 1, 0),
81943a6a7e7SGarlic Tseng };
82043a6a7e7SGarlic Tseng 
82143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = {
82243a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch",
82343a6a7e7SGarlic Tseng 				    ASYS_I2SO2_CON, 26, 1, 0),
82443a6a7e7SGarlic Tseng };
82543a6a7e7SGarlic Tseng 
82643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = {
82743a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch",
82843a6a7e7SGarlic Tseng 				    PWR2_TOP_CON, 17, 1, 0),
82943a6a7e7SGarlic Tseng };
83043a6a7e7SGarlic Tseng 
83143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = {
83243a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch",
83343a6a7e7SGarlic Tseng 				    PWR2_TOP_CON, 18, 1, 0),
83443a6a7e7SGarlic Tseng };
83543a6a7e7SGarlic Tseng 
83643a6a7e7SGarlic Tseng static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
83743a6a7e7SGarlic Tseng 	/* inter-connections */
83843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),
83943a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0),
84043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix,
84143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_i02_mix)),
84243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
84343a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0),
84443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0),
84543a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0),
84643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0),
84743a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0),
84843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
84943a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),
85043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0),
85143a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0),
85243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0),
85343a6a7e7SGarlic Tseng 
85443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix,
85543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o00_mix)),
85643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix,
85743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o01_mix)),
85843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix,
85943a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o02_mix)),
86043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix,
86143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o03_mix)),
86243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix,
86343a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o14_mix)),
86443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix,
86543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o15_mix)),
86643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix,
86743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o16_mix)),
86843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix,
86943a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o17_mix)),
87043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix,
87143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o18_mix)),
87243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix,
87343a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o19_mix)),
87443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix,
87543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o20_mix)),
87643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix,
87743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o21_mix)),
87843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix,
87943a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o22_mix)),
88043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix,
88143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o31_mix)),
88243a6a7e7SGarlic Tseng 
88343a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0,
88443a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s0,
88543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)),
88643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0,
88743a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s1,
88843a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)),
88943a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0,
89043a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s2,
89143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)),
89243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0,
89343a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s3,
89443a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)),
89543a6a7e7SGarlic Tseng };
89643a6a7e7SGarlic Tseng 
89743a6a7e7SGarlic Tseng static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
89843a6a7e7SGarlic Tseng 	{"I12", NULL, "DL1"},
89943a6a7e7SGarlic Tseng 	{"I13", NULL, "DL1"},
90043a6a7e7SGarlic Tseng 	{"I35", NULL, "DLBT"},
90143a6a7e7SGarlic Tseng 
90243a6a7e7SGarlic Tseng 	{"I2S0 Playback", NULL, "O15"},
90343a6a7e7SGarlic Tseng 	{"I2S0 Playback", NULL, "O16"},
90443a6a7e7SGarlic Tseng 	{"I2S1 Playback", NULL, "O17"},
90543a6a7e7SGarlic Tseng 	{"I2S1 Playback", NULL, "O18"},
90643a6a7e7SGarlic Tseng 	{"I2S2 Playback", NULL, "O19"},
90743a6a7e7SGarlic Tseng 	{"I2S2 Playback", NULL, "O20"},
90843a6a7e7SGarlic Tseng 	{"I2S3 Playback", NULL, "O21"},
90943a6a7e7SGarlic Tseng 	{"I2S3 Playback", NULL, "O22"},
91043a6a7e7SGarlic Tseng 	{"BT Playback", NULL, "O31"},
91143a6a7e7SGarlic Tseng 
91243a6a7e7SGarlic Tseng 	{"UL1", NULL, "O00"},
91343a6a7e7SGarlic Tseng 	{"UL1", NULL, "O01"},
91443a6a7e7SGarlic Tseng 	{"UL2", NULL, "O02"},
91543a6a7e7SGarlic Tseng 	{"UL2", NULL, "O03"},
91643a6a7e7SGarlic Tseng 	{"ULBT", NULL, "O14"},
91743a6a7e7SGarlic Tseng 
91843a6a7e7SGarlic Tseng 	{"I00", NULL, "I2S0 Capture"},
91943a6a7e7SGarlic Tseng 	{"I01", NULL, "I2S0 Capture"},
92043a6a7e7SGarlic Tseng 	{"I02", NULL, "I2S1 Capture"},
92143a6a7e7SGarlic Tseng 	{"I03", NULL, "I2S1 Capture"},
92243a6a7e7SGarlic Tseng 	/* I02,03 link to UL2, also need to open I2S0 */
92343a6a7e7SGarlic Tseng 	{"I02", "I2S0 Switch", "I2S0 Capture"},
92443a6a7e7SGarlic Tseng 
92543a6a7e7SGarlic Tseng 	{"I26", NULL, "BT Capture"},
92643a6a7e7SGarlic Tseng 
927600b2fd4SRyder Lee 	{"I12I13", "Multich I2S0 Out Switch", "DLM"},
928600b2fd4SRyder Lee 	{"I14I15", "Multich I2S1 Out Switch", "DLM"},
929600b2fd4SRyder Lee 	{"I16I17", "Multich I2S2 Out Switch", "DLM"},
930600b2fd4SRyder Lee 	{"I18I19", "Multich I2S3 Out Switch", "DLM"},
93143a6a7e7SGarlic Tseng 
93243a6a7e7SGarlic Tseng 	{ "I12", NULL, "I12I13" },
93343a6a7e7SGarlic Tseng 	{ "I13", NULL, "I12I13" },
93443a6a7e7SGarlic Tseng 	{ "I14", NULL, "I14I15" },
93543a6a7e7SGarlic Tseng 	{ "I15", NULL, "I14I15" },
93643a6a7e7SGarlic Tseng 	{ "I16", NULL, "I16I17" },
93743a6a7e7SGarlic Tseng 	{ "I17", NULL, "I16I17" },
93843a6a7e7SGarlic Tseng 	{ "I18", NULL, "I18I19" },
93943a6a7e7SGarlic Tseng 	{ "I19", NULL, "I18I19" },
94043a6a7e7SGarlic Tseng 
94143a6a7e7SGarlic Tseng 	{ "O00", "I00 Switch", "I00" },
94243a6a7e7SGarlic Tseng 	{ "O01", "I01 Switch", "I01" },
94343a6a7e7SGarlic Tseng 	{ "O02", "I02 Switch", "I02" },
94443a6a7e7SGarlic Tseng 	{ "O03", "I03 Switch", "I03" },
94543a6a7e7SGarlic Tseng 	{ "O14", "I26 Switch", "I26" },
94643a6a7e7SGarlic Tseng 	{ "O15", "I12 Switch", "I12" },
94743a6a7e7SGarlic Tseng 	{ "O16", "I13 Switch", "I13" },
94843a6a7e7SGarlic Tseng 	{ "O17", "I14 Switch", "I14" },
94943a6a7e7SGarlic Tseng 	{ "O18", "I15 Switch", "I15" },
95043a6a7e7SGarlic Tseng 	{ "O19", "I16 Switch", "I16" },
95143a6a7e7SGarlic Tseng 	{ "O20", "I17 Switch", "I17" },
95243a6a7e7SGarlic Tseng 	{ "O21", "I18 Switch", "I18" },
95343a6a7e7SGarlic Tseng 	{ "O22", "I19 Switch", "I19" },
95443a6a7e7SGarlic Tseng 	{ "O31", "I35 Switch", "I35" },
95543a6a7e7SGarlic Tseng };
95643a6a7e7SGarlic Tseng 
95710abdc7cSRyder Lee static int mt2701_afe_pcm_probe(struct snd_soc_component *component)
95810abdc7cSRyder Lee {
95910abdc7cSRyder Lee 	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
96010abdc7cSRyder Lee 
96110abdc7cSRyder Lee 	snd_soc_component_init_regmap(component, afe->regmap);
96210abdc7cSRyder Lee 
96310abdc7cSRyder Lee 	return 0;
96410abdc7cSRyder Lee }
96510abdc7cSRyder Lee 
96643a6a7e7SGarlic Tseng static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {
96710abdc7cSRyder Lee 	.probe = mt2701_afe_pcm_probe,
96843a6a7e7SGarlic Tseng 	.name = "mt2701-afe-pcm-dai",
96943a6a7e7SGarlic Tseng 	.dapm_widgets = mt2701_afe_pcm_widgets,
97043a6a7e7SGarlic Tseng 	.num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets),
97143a6a7e7SGarlic Tseng 	.dapm_routes = mt2701_afe_pcm_routes,
97243a6a7e7SGarlic Tseng 	.num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes),
9737ec6b431SKuninori Morimoto 	.suspend = mtk_afe_suspend,
9747ec6b431SKuninori Morimoto 	.resume = mtk_afe_resume,
97543a6a7e7SGarlic Tseng };
97643a6a7e7SGarlic Tseng 
977d9cdc133SPierre-Louis Bossart static const struct mtk_base_memif_data memif_data_array[MT2701_MEMIF_NUM] = {
97843a6a7e7SGarlic Tseng 	{
97943a6a7e7SGarlic Tseng 		.name = "DL1",
98043a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL1,
98143a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL1_BASE,
98243a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL1_CUR,
98343a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
98443a6a7e7SGarlic Tseng 		.fs_shift = 0,
98543a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
98643a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
98743a6a7e7SGarlic Tseng 		.mono_shift = 16,
98843a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
98943a6a7e7SGarlic Tseng 		.enable_shift = 1,
99043a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
99143a6a7e7SGarlic Tseng 		.hd_shift = 0,
99243a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
99343a6a7e7SGarlic Tseng 		.agent_disable_shift = 6,
99443a6a7e7SGarlic Tseng 		.msb_reg = -1,
99543a6a7e7SGarlic Tseng 	},
99643a6a7e7SGarlic Tseng 	{
99743a6a7e7SGarlic Tseng 		.name = "DL2",
99843a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL2,
99943a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL2_BASE,
100043a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL2_CUR,
100143a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
100243a6a7e7SGarlic Tseng 		.fs_shift = 5,
100343a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
100443a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
100543a6a7e7SGarlic Tseng 		.mono_shift = 17,
100643a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
100743a6a7e7SGarlic Tseng 		.enable_shift = 2,
100843a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
100943a6a7e7SGarlic Tseng 		.hd_shift = 2,
101043a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
101143a6a7e7SGarlic Tseng 		.agent_disable_shift = 7,
101243a6a7e7SGarlic Tseng 		.msb_reg = -1,
101343a6a7e7SGarlic Tseng 	},
101443a6a7e7SGarlic Tseng 	{
101543a6a7e7SGarlic Tseng 		.name = "DL3",
101643a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL3,
101743a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL3_BASE,
101843a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL3_CUR,
101943a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
102043a6a7e7SGarlic Tseng 		.fs_shift = 10,
102143a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
102243a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
102343a6a7e7SGarlic Tseng 		.mono_shift = 18,
102443a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
102543a6a7e7SGarlic Tseng 		.enable_shift = 3,
102643a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
102743a6a7e7SGarlic Tseng 		.hd_shift = 4,
102843a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
102943a6a7e7SGarlic Tseng 		.agent_disable_shift = 8,
103043a6a7e7SGarlic Tseng 		.msb_reg = -1,
103143a6a7e7SGarlic Tseng 	},
103243a6a7e7SGarlic Tseng 	{
103343a6a7e7SGarlic Tseng 		.name = "DL4",
103443a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL4,
103543a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL4_BASE,
103643a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL4_CUR,
103743a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
103843a6a7e7SGarlic Tseng 		.fs_shift = 15,
103943a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
104043a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
104143a6a7e7SGarlic Tseng 		.mono_shift = 19,
104243a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
104343a6a7e7SGarlic Tseng 		.enable_shift = 4,
104443a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
104543a6a7e7SGarlic Tseng 		.hd_shift = 6,
104643a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
104743a6a7e7SGarlic Tseng 		.agent_disable_shift = 9,
104843a6a7e7SGarlic Tseng 		.msb_reg = -1,
104943a6a7e7SGarlic Tseng 	},
105043a6a7e7SGarlic Tseng 	{
105143a6a7e7SGarlic Tseng 		.name = "DL5",
105243a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL5,
105343a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL5_BASE,
105443a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL5_CUR,
105543a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
105643a6a7e7SGarlic Tseng 		.fs_shift = 20,
105743a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
105843a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
105943a6a7e7SGarlic Tseng 		.mono_shift = 20,
106043a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
106143a6a7e7SGarlic Tseng 		.enable_shift = 5,
106243a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
106343a6a7e7SGarlic Tseng 		.hd_shift = 8,
106443a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
106543a6a7e7SGarlic Tseng 		.agent_disable_shift = 10,
106643a6a7e7SGarlic Tseng 		.msb_reg = -1,
106743a6a7e7SGarlic Tseng 	},
106843a6a7e7SGarlic Tseng 	{
106943a6a7e7SGarlic Tseng 		.name = "DLM",
107043a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DLM,
107143a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DLMCH_BASE,
107243a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DLMCH_CUR,
107343a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
107443a6a7e7SGarlic Tseng 		.fs_shift = 0,
107543a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
107643a6a7e7SGarlic Tseng 		.mono_reg = -1,
107743a6a7e7SGarlic Tseng 		.mono_shift = -1,
107843a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
107943a6a7e7SGarlic Tseng 		.enable_shift = 7,
108043a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_PBUF_SIZE,
108143a6a7e7SGarlic Tseng 		.hd_shift = 28,
108243a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
108343a6a7e7SGarlic Tseng 		.agent_disable_shift = 12,
108443a6a7e7SGarlic Tseng 		.msb_reg = -1,
108543a6a7e7SGarlic Tseng 	},
108643a6a7e7SGarlic Tseng 	{
108743a6a7e7SGarlic Tseng 		.name = "UL1",
108843a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL1,
108943a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_VUL_BASE,
109043a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_VUL_CUR,
109143a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
109243a6a7e7SGarlic Tseng 		.fs_shift = 0,
109343a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
109443a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
109543a6a7e7SGarlic Tseng 		.mono_shift = 0,
109643a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
109743a6a7e7SGarlic Tseng 		.enable_shift = 10,
109843a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON1,
109943a6a7e7SGarlic Tseng 		.hd_shift = 0,
110043a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
110143a6a7e7SGarlic Tseng 		.agent_disable_shift = 0,
110243a6a7e7SGarlic Tseng 		.msb_reg = -1,
110343a6a7e7SGarlic Tseng 	},
110443a6a7e7SGarlic Tseng 	{
110543a6a7e7SGarlic Tseng 		.name = "UL2",
110643a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL2,
110743a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL2_BASE,
110843a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL2_CUR,
110943a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
111043a6a7e7SGarlic Tseng 		.fs_shift = 5,
111143a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
111243a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
111343a6a7e7SGarlic Tseng 		.mono_shift = 2,
111443a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
111543a6a7e7SGarlic Tseng 		.enable_shift = 11,
111643a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON1,
111743a6a7e7SGarlic Tseng 		.hd_shift = 2,
111843a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
111943a6a7e7SGarlic Tseng 		.agent_disable_shift = 1,
112043a6a7e7SGarlic Tseng 		.msb_reg = -1,
112143a6a7e7SGarlic Tseng 	},
112243a6a7e7SGarlic Tseng 	{
112343a6a7e7SGarlic Tseng 		.name = "UL3",
112443a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL3,
112543a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL3_BASE,
112643a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL3_CUR,
112743a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
112843a6a7e7SGarlic Tseng 		.fs_shift = 10,
112943a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
113043a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
113143a6a7e7SGarlic Tseng 		.mono_shift = 4,
113243a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
113343a6a7e7SGarlic Tseng 		.enable_shift = 12,
113443a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
113543a6a7e7SGarlic Tseng 		.hd_shift = 0,
113643a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
113743a6a7e7SGarlic Tseng 		.agent_disable_shift = 2,
113843a6a7e7SGarlic Tseng 		.msb_reg = -1,
113943a6a7e7SGarlic Tseng 	},
114043a6a7e7SGarlic Tseng 	{
114143a6a7e7SGarlic Tseng 		.name = "UL4",
114243a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL4,
114343a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL4_BASE,
114443a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL4_CUR,
114543a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
114643a6a7e7SGarlic Tseng 		.fs_shift = 15,
114743a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
114843a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
114943a6a7e7SGarlic Tseng 		.mono_shift = 6,
115043a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
115143a6a7e7SGarlic Tseng 		.enable_shift = 13,
115243a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
115343a6a7e7SGarlic Tseng 		.hd_shift = 6,
115443a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
115543a6a7e7SGarlic Tseng 		.agent_disable_shift = 3,
115643a6a7e7SGarlic Tseng 		.msb_reg = -1,
115743a6a7e7SGarlic Tseng 	},
115843a6a7e7SGarlic Tseng 	{
115943a6a7e7SGarlic Tseng 		.name = "UL5",
116043a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL5,
116143a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL5_BASE,
116243a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL5_CUR,
116343a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
116443a6a7e7SGarlic Tseng 		.fs_shift = 20,
116543a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
116643a6a7e7SGarlic Tseng 		.mono_shift = 8,
116743a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
116843a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
116943a6a7e7SGarlic Tseng 		.enable_shift = 14,
117043a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
117143a6a7e7SGarlic Tseng 		.hd_shift = 8,
117243a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
117343a6a7e7SGarlic Tseng 		.agent_disable_shift = 4,
117443a6a7e7SGarlic Tseng 		.msb_reg = -1,
117543a6a7e7SGarlic Tseng 	},
117643a6a7e7SGarlic Tseng 	{
117743a6a7e7SGarlic Tseng 		.name = "DLBT",
117843a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DLBT,
117943a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_ARB1_BASE,
118043a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_ARB1_CUR,
118143a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON3,
118243a6a7e7SGarlic Tseng 		.fs_shift = 10,
118343a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
118443a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
118543a6a7e7SGarlic Tseng 		.mono_shift = 22,
118643a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
118743a6a7e7SGarlic Tseng 		.enable_shift = 8,
118843a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
118943a6a7e7SGarlic Tseng 		.hd_shift = 14,
119043a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
119143a6a7e7SGarlic Tseng 		.agent_disable_shift = 13,
119243a6a7e7SGarlic Tseng 		.msb_reg = -1,
119343a6a7e7SGarlic Tseng 	},
119443a6a7e7SGarlic Tseng 	{
119543a6a7e7SGarlic Tseng 		.name = "ULBT",
119643a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_ULBT,
119743a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DAI_BASE,
119843a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DAI_CUR,
119943a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
120043a6a7e7SGarlic Tseng 		.fs_shift = 30,
120143a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1,
120243a6a7e7SGarlic Tseng 		.mono_reg = -1,
120343a6a7e7SGarlic Tseng 		.mono_shift = -1,
120443a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
120543a6a7e7SGarlic Tseng 		.enable_shift = 17,
120643a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON1,
120743a6a7e7SGarlic Tseng 		.hd_shift = 20,
120843a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
120943a6a7e7SGarlic Tseng 		.agent_disable_shift = 16,
121043a6a7e7SGarlic Tseng 		.msb_reg = -1,
121143a6a7e7SGarlic Tseng 	},
121243a6a7e7SGarlic Tseng };
121343a6a7e7SGarlic Tseng 
121443a6a7e7SGarlic Tseng static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {
121543a6a7e7SGarlic Tseng 	{
121643a6a7e7SGarlic Tseng 		.id = MT2701_IRQ_ASYS_IRQ1,
121743a6a7e7SGarlic Tseng 		.irq_cnt_reg = ASYS_IRQ1_CON,
121843a6a7e7SGarlic Tseng 		.irq_cnt_shift = 0,
121943a6a7e7SGarlic Tseng 		.irq_cnt_maskbit = 0xffffff,
122043a6a7e7SGarlic Tseng 		.irq_fs_reg = ASYS_IRQ1_CON,
122143a6a7e7SGarlic Tseng 		.irq_fs_shift = 24,
122243a6a7e7SGarlic Tseng 		.irq_fs_maskbit = 0x1f,
122343a6a7e7SGarlic Tseng 		.irq_en_reg = ASYS_IRQ1_CON,
122443a6a7e7SGarlic Tseng 		.irq_en_shift = 31,
122543a6a7e7SGarlic Tseng 		.irq_clr_reg = ASYS_IRQ_CLR,
122643a6a7e7SGarlic Tseng 		.irq_clr_shift = 0,
122743a6a7e7SGarlic Tseng 	},
122843a6a7e7SGarlic Tseng 	{
122943a6a7e7SGarlic Tseng 		.id = MT2701_IRQ_ASYS_IRQ2,
123043a6a7e7SGarlic Tseng 		.irq_cnt_reg = ASYS_IRQ2_CON,
123143a6a7e7SGarlic Tseng 		.irq_cnt_shift = 0,
123243a6a7e7SGarlic Tseng 		.irq_cnt_maskbit = 0xffffff,
123343a6a7e7SGarlic Tseng 		.irq_fs_reg = ASYS_IRQ2_CON,
123443a6a7e7SGarlic Tseng 		.irq_fs_shift = 24,
123543a6a7e7SGarlic Tseng 		.irq_fs_maskbit = 0x1f,
123643a6a7e7SGarlic Tseng 		.irq_en_reg = ASYS_IRQ2_CON,
123743a6a7e7SGarlic Tseng 		.irq_en_shift = 31,
123843a6a7e7SGarlic Tseng 		.irq_clr_reg = ASYS_IRQ_CLR,
123943a6a7e7SGarlic Tseng 		.irq_clr_shift = 1,
124043a6a7e7SGarlic Tseng 	},
124143a6a7e7SGarlic Tseng 	{
124243a6a7e7SGarlic Tseng 		.id = MT2701_IRQ_ASYS_IRQ3,
124343a6a7e7SGarlic Tseng 		.irq_cnt_reg = ASYS_IRQ3_CON,
124443a6a7e7SGarlic Tseng 		.irq_cnt_shift = 0,
124543a6a7e7SGarlic Tseng 		.irq_cnt_maskbit = 0xffffff,
124643a6a7e7SGarlic Tseng 		.irq_fs_reg = ASYS_IRQ3_CON,
124743a6a7e7SGarlic Tseng 		.irq_fs_shift = 24,
124843a6a7e7SGarlic Tseng 		.irq_fs_maskbit = 0x1f,
124943a6a7e7SGarlic Tseng 		.irq_en_reg = ASYS_IRQ3_CON,
125043a6a7e7SGarlic Tseng 		.irq_en_shift = 31,
125143a6a7e7SGarlic Tseng 		.irq_clr_reg = ASYS_IRQ_CLR,
125243a6a7e7SGarlic Tseng 		.irq_clr_shift = 2,
125343a6a7e7SGarlic Tseng 	}
125443a6a7e7SGarlic Tseng };
125543a6a7e7SGarlic Tseng 
1256ab7b4ee9SRyder Lee static const struct mt2701_i2s_data mt2701_i2s_data[][2] = {
125743a6a7e7SGarlic Tseng 	{
1258ab7b4ee9SRyder Lee 		{ ASYS_I2SO1_CON, 0, 0x1f },
1259ab7b4ee9SRyder Lee 		{ ASYS_I2SIN1_CON, 0, 0x1f },
126043a6a7e7SGarlic Tseng 	},
126143a6a7e7SGarlic Tseng 	{
1262ab7b4ee9SRyder Lee 		{ ASYS_I2SO2_CON, 5, 0x1f },
1263ab7b4ee9SRyder Lee 		{ ASYS_I2SIN2_CON, 5, 0x1f },
126443a6a7e7SGarlic Tseng 	},
126543a6a7e7SGarlic Tseng 	{
1266ab7b4ee9SRyder Lee 		{ ASYS_I2SO3_CON, 10, 0x1f },
1267ab7b4ee9SRyder Lee 		{ ASYS_I2SIN3_CON, 10, 0x1f },
126843a6a7e7SGarlic Tseng 	},
126943a6a7e7SGarlic Tseng 	{
1270ab7b4ee9SRyder Lee 		{ ASYS_I2SO4_CON, 15, 0x1f },
1271ab7b4ee9SRyder Lee 		{ ASYS_I2SIN4_CON, 15, 0x1f },
127243a6a7e7SGarlic Tseng 	},
1273ab7b4ee9SRyder Lee 	/* TODO - extend control registers supported by newer SoCs */
127443a6a7e7SGarlic Tseng };
127543a6a7e7SGarlic Tseng 
127643a6a7e7SGarlic Tseng static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
127743a6a7e7SGarlic Tseng {
127843a6a7e7SGarlic Tseng 	int id;
127943a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev;
128043a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif;
128143a6a7e7SGarlic Tseng 	struct mtk_base_afe_irq *irq;
128243a6a7e7SGarlic Tseng 	u32 status;
128343a6a7e7SGarlic Tseng 
128443a6a7e7SGarlic Tseng 	regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status);
128543a6a7e7SGarlic Tseng 	regmap_write(afe->regmap, ASYS_IRQ_CLR, status);
128643a6a7e7SGarlic Tseng 
128743a6a7e7SGarlic Tseng 	for (id = 0; id < MT2701_MEMIF_NUM; ++id) {
128843a6a7e7SGarlic Tseng 		memif = &afe->memif[id];
128943a6a7e7SGarlic Tseng 		if (memif->irq_usage < 0)
129043a6a7e7SGarlic Tseng 			continue;
1291e4b31b81SRyder Lee 
129243a6a7e7SGarlic Tseng 		irq = &afe->irqs[memif->irq_usage];
1293e4b31b81SRyder Lee 		if (status & 1 << irq->irq_data->irq_clr_shift)
129443a6a7e7SGarlic Tseng 			snd_pcm_period_elapsed(memif->substream);
129543a6a7e7SGarlic Tseng 	}
1296e4b31b81SRyder Lee 
129743a6a7e7SGarlic Tseng 	return IRQ_HANDLED;
129843a6a7e7SGarlic Tseng }
129943a6a7e7SGarlic Tseng 
130043a6a7e7SGarlic Tseng static int mt2701_afe_runtime_suspend(struct device *dev)
130143a6a7e7SGarlic Tseng {
130243a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev_get_drvdata(dev);
130343a6a7e7SGarlic Tseng 
1304d8d99d8eSRyder Lee 	return mt2701_afe_disable_clock(afe);
130543a6a7e7SGarlic Tseng }
130643a6a7e7SGarlic Tseng 
130743a6a7e7SGarlic Tseng static int mt2701_afe_runtime_resume(struct device *dev)
130843a6a7e7SGarlic Tseng {
130943a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev_get_drvdata(dev);
131043a6a7e7SGarlic Tseng 
131143a6a7e7SGarlic Tseng 	return mt2701_afe_enable_clock(afe);
131243a6a7e7SGarlic Tseng }
131343a6a7e7SGarlic Tseng 
1314dc2a17f4SRyder Lee static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1315dc2a17f4SRyder Lee {
131643a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe;
131743a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv;
131843a6a7e7SGarlic Tseng 	struct device *dev;
1319f6c1626eSRyder Lee 	int i, irq_id, ret;
132043a6a7e7SGarlic Tseng 
132143a6a7e7SGarlic Tseng 	afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
132243a6a7e7SGarlic Tseng 	if (!afe)
132343a6a7e7SGarlic Tseng 		return -ENOMEM;
1324600b2fd4SRyder Lee 
1325b02c5cc7SDan Carpenter 	afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
1326b02c5cc7SDan Carpenter 					  GFP_KERNEL);
1327b02c5cc7SDan Carpenter 	if (!afe->platform_priv)
1328b02c5cc7SDan Carpenter 		return -ENOMEM;
132943a6a7e7SGarlic Tseng 
1330600b2fd4SRyder Lee 	afe_priv = afe->platform_priv;
1331bfdc56e5SRyder Lee 	afe_priv->soc = of_device_get_match_data(&pdev->dev);
133243a6a7e7SGarlic Tseng 	afe->dev = &pdev->dev;
133343a6a7e7SGarlic Tseng 	dev = afe->dev;
133443a6a7e7SGarlic Tseng 
1335a86854d0SKees Cook 	afe_priv->i2s_path = devm_kcalloc(dev,
1336a86854d0SKees Cook 					  afe_priv->soc->i2s_num,
1337bfdc56e5SRyder Lee 					  sizeof(struct mt2701_i2s_path),
1338bfdc56e5SRyder Lee 					  GFP_KERNEL);
1339bfdc56e5SRyder Lee 	if (!afe_priv->i2s_path)
1340bfdc56e5SRyder Lee 		return -ENOMEM;
1341bfdc56e5SRyder Lee 
1342f6c1626eSRyder Lee 	irq_id = platform_get_irq_byname(pdev, "asys");
1343cf9441adSStephen Boyd 	if (irq_id < 0)
1344f6c1626eSRyder Lee 		return irq_id;
1345f6c1626eSRyder Lee 
134643a6a7e7SGarlic Tseng 	ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
134743a6a7e7SGarlic Tseng 			       IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
134843a6a7e7SGarlic Tseng 	if (ret) {
134943a6a7e7SGarlic Tseng 		dev_err(dev, "could not request_irq for asys-isr\n");
135043a6a7e7SGarlic Tseng 		return ret;
135143a6a7e7SGarlic Tseng 	}
135243a6a7e7SGarlic Tseng 
1353dfa3cbb8SRyder Lee 	afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
13543e8052d9SWei Yongjun 	if (IS_ERR(afe->regmap)) {
1355dfa3cbb8SRyder Lee 		dev_err(dev, "could not get regmap from parent\n");
13563e8052d9SWei Yongjun 		return PTR_ERR(afe->regmap);
1357dfa3cbb8SRyder Lee 	}
135843a6a7e7SGarlic Tseng 
135943a6a7e7SGarlic Tseng 	mutex_init(&afe->irq_alloc_lock);
136043a6a7e7SGarlic Tseng 
136143a6a7e7SGarlic Tseng 	/* memif initialize */
136243a6a7e7SGarlic Tseng 	afe->memif_size = MT2701_MEMIF_NUM;
136343a6a7e7SGarlic Tseng 	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
136443a6a7e7SGarlic Tseng 				  GFP_KERNEL);
136543a6a7e7SGarlic Tseng 	if (!afe->memif)
136643a6a7e7SGarlic Tseng 		return -ENOMEM;
136743a6a7e7SGarlic Tseng 
136843a6a7e7SGarlic Tseng 	for (i = 0; i < afe->memif_size; i++) {
1369d9cdc133SPierre-Louis Bossart 		afe->memif[i].data = &memif_data_array[i];
137043a6a7e7SGarlic Tseng 		afe->memif[i].irq_usage = -1;
137143a6a7e7SGarlic Tseng 	}
137243a6a7e7SGarlic Tseng 
137343a6a7e7SGarlic Tseng 	/* irq initialize */
137443a6a7e7SGarlic Tseng 	afe->irqs_size = MT2701_IRQ_ASYS_END;
137543a6a7e7SGarlic Tseng 	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
137643a6a7e7SGarlic Tseng 				 GFP_KERNEL);
137743a6a7e7SGarlic Tseng 	if (!afe->irqs)
137843a6a7e7SGarlic Tseng 		return -ENOMEM;
137943a6a7e7SGarlic Tseng 
138043a6a7e7SGarlic Tseng 	for (i = 0; i < afe->irqs_size; i++)
138143a6a7e7SGarlic Tseng 		afe->irqs[i].irq_data = &irq_data[i];
138243a6a7e7SGarlic Tseng 
138343a6a7e7SGarlic Tseng 	/* I2S initialize */
1384bfdc56e5SRyder Lee 	for (i = 0; i < afe_priv->soc->i2s_num; i++) {
1385ab7b4ee9SRyder Lee 		afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_PLAYBACK] =
1386ab7b4ee9SRyder Lee 			&mt2701_i2s_data[i][SNDRV_PCM_STREAM_PLAYBACK];
1387ab7b4ee9SRyder Lee 		afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_CAPTURE] =
1388ab7b4ee9SRyder Lee 			&mt2701_i2s_data[i][SNDRV_PCM_STREAM_CAPTURE];
138943a6a7e7SGarlic Tseng 	}
139043a6a7e7SGarlic Tseng 
139143a6a7e7SGarlic Tseng 	afe->mtk_afe_hardware = &mt2701_afe_hardware;
139243a6a7e7SGarlic Tseng 	afe->memif_fs = mt2701_memif_fs;
139343a6a7e7SGarlic Tseng 	afe->irq_fs = mt2701_irq_fs;
139443a6a7e7SGarlic Tseng 	afe->reg_back_up_list = mt2701_afe_backup_list;
139543a6a7e7SGarlic Tseng 	afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list);
139643a6a7e7SGarlic Tseng 	afe->runtime_resume = mt2701_afe_runtime_resume;
139743a6a7e7SGarlic Tseng 	afe->runtime_suspend = mt2701_afe_runtime_suspend;
139843a6a7e7SGarlic Tseng 
139943a6a7e7SGarlic Tseng 	/* initial audio related clock */
140043a6a7e7SGarlic Tseng 	ret = mt2701_init_clock(afe);
140143a6a7e7SGarlic Tseng 	if (ret) {
140243a6a7e7SGarlic Tseng 		dev_err(dev, "init clock error\n");
1403dc2a17f4SRyder Lee 		return ret;
140443a6a7e7SGarlic Tseng 	}
140543a6a7e7SGarlic Tseng 
140643a6a7e7SGarlic Tseng 	platform_set_drvdata(pdev, afe);
140743a6a7e7SGarlic Tseng 
1408dd6bb9b1SRyder Lee 	pm_runtime_enable(dev);
1409dd6bb9b1SRyder Lee 	if (!pm_runtime_enabled(dev)) {
1410dd6bb9b1SRyder Lee 		ret = mt2701_afe_runtime_resume(dev);
1411dd6bb9b1SRyder Lee 		if (ret)
1412dd6bb9b1SRyder Lee 			goto err_pm_disable;
1413dd6bb9b1SRyder Lee 	}
1414dd6bb9b1SRyder Lee 	pm_runtime_get_sync(dev);
1415dd6bb9b1SRyder Lee 
1416f1b5bf07SKuninori Morimoto 	ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform,
1417f1b5bf07SKuninori Morimoto 					      NULL, 0);
141843a6a7e7SGarlic Tseng 	if (ret) {
141943a6a7e7SGarlic Tseng 		dev_warn(dev, "err_platform\n");
142043a6a7e7SGarlic Tseng 		goto err_platform;
142143a6a7e7SGarlic Tseng 	}
142243a6a7e7SGarlic Tseng 
142310abdc7cSRyder Lee 	ret = devm_snd_soc_register_component(&pdev->dev,
142410abdc7cSRyder Lee 					 &mt2701_afe_pcm_dai_component,
142510abdc7cSRyder Lee 					 mt2701_afe_pcm_dais,
142610abdc7cSRyder Lee 					 ARRAY_SIZE(mt2701_afe_pcm_dais));
142743a6a7e7SGarlic Tseng 	if (ret) {
142843a6a7e7SGarlic Tseng 		dev_warn(dev, "err_dai_component\n");
1429f1b5bf07SKuninori Morimoto 		goto err_platform;
143043a6a7e7SGarlic Tseng 	}
143143a6a7e7SGarlic Tseng 
143243a6a7e7SGarlic Tseng 	return 0;
143343a6a7e7SGarlic Tseng 
143443a6a7e7SGarlic Tseng err_platform:
1435dd6bb9b1SRyder Lee 	pm_runtime_put_sync(dev);
143643a6a7e7SGarlic Tseng err_pm_disable:
1437dd6bb9b1SRyder Lee 	pm_runtime_disable(dev);
143843a6a7e7SGarlic Tseng 
143943a6a7e7SGarlic Tseng 	return ret;
144043a6a7e7SGarlic Tseng }
144143a6a7e7SGarlic Tseng 
1442*b3dff59eSUwe Kleine-König static void mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
144343a6a7e7SGarlic Tseng {
1444dd6bb9b1SRyder Lee 	pm_runtime_put_sync(&pdev->dev);
144543a6a7e7SGarlic Tseng 	pm_runtime_disable(&pdev->dev);
144643a6a7e7SGarlic Tseng 	if (!pm_runtime_status_suspended(&pdev->dev))
144743a6a7e7SGarlic Tseng 		mt2701_afe_runtime_suspend(&pdev->dev);
144843a6a7e7SGarlic Tseng }
144943a6a7e7SGarlic Tseng 
1450bfdc56e5SRyder Lee static const struct mt2701_soc_variants mt2701_soc_v1 = {
1451bfdc56e5SRyder Lee 	.i2s_num = 4,
1452bfdc56e5SRyder Lee };
1453bfdc56e5SRyder Lee 
1454bfdc56e5SRyder Lee static const struct mt2701_soc_variants mt2701_soc_v2 = {
1455bfdc56e5SRyder Lee 	.has_one_heart_mode = true,
1456bfdc56e5SRyder Lee 	.i2s_num = 4,
1457bfdc56e5SRyder Lee };
1458bfdc56e5SRyder Lee 
145943a6a7e7SGarlic Tseng static const struct of_device_id mt2701_afe_pcm_dt_match[] = {
1460bfdc56e5SRyder Lee 	{ .compatible = "mediatek,mt2701-audio", .data = &mt2701_soc_v1 },
1461bfdc56e5SRyder Lee 	{ .compatible = "mediatek,mt7622-audio", .data = &mt2701_soc_v2 },
146243a6a7e7SGarlic Tseng 	{},
146343a6a7e7SGarlic Tseng };
146443a6a7e7SGarlic Tseng MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match);
146543a6a7e7SGarlic Tseng 
146643a6a7e7SGarlic Tseng static const struct dev_pm_ops mt2701_afe_pm_ops = {
146743a6a7e7SGarlic Tseng 	SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend,
146843a6a7e7SGarlic Tseng 			   mt2701_afe_runtime_resume, NULL)
146943a6a7e7SGarlic Tseng };
147043a6a7e7SGarlic Tseng 
147143a6a7e7SGarlic Tseng static struct platform_driver mt2701_afe_pcm_driver = {
147243a6a7e7SGarlic Tseng 	.driver = {
147343a6a7e7SGarlic Tseng 		   .name = "mt2701-audio",
147443a6a7e7SGarlic Tseng 		   .of_match_table = mt2701_afe_pcm_dt_match,
147543a6a7e7SGarlic Tseng 		   .pm = &mt2701_afe_pm_ops,
147643a6a7e7SGarlic Tseng 	},
147743a6a7e7SGarlic Tseng 	.probe = mt2701_afe_pcm_dev_probe,
1478*b3dff59eSUwe Kleine-König 	.remove_new = mt2701_afe_pcm_dev_remove,
147943a6a7e7SGarlic Tseng };
148043a6a7e7SGarlic Tseng 
148143a6a7e7SGarlic Tseng module_platform_driver(mt2701_afe_pcm_driver);
148243a6a7e7SGarlic Tseng 
148343a6a7e7SGarlic Tseng MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701");
148443a6a7e7SGarlic Tseng MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
148543a6a7e7SGarlic Tseng MODULE_LICENSE("GPL v2");
1486