xref: /linux/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c (revision 3e8052d90d24320a1edb556c20523f3b17195985)
143a6a7e7SGarlic Tseng /*
243a6a7e7SGarlic Tseng  * Mediatek ALSA SoC AFE platform driver for 2701
343a6a7e7SGarlic Tseng  *
443a6a7e7SGarlic Tseng  * Copyright (c) 2016 MediaTek Inc.
543a6a7e7SGarlic Tseng  * Author: Garlic Tseng <garlic.tseng@mediatek.com>
643a6a7e7SGarlic Tseng  *             Ir Lian <ir.lian@mediatek.com>
743a6a7e7SGarlic Tseng  *
843a6a7e7SGarlic Tseng  * This program is free software; you can redistribute it and/or modify
943a6a7e7SGarlic Tseng  * it under the terms of the GNU General Public License version 2 and
1043a6a7e7SGarlic Tseng  * only version 2 as published by the Free Software Foundation.
1143a6a7e7SGarlic Tseng  *
1243a6a7e7SGarlic Tseng  * This program is distributed in the hope that it will be useful,
1343a6a7e7SGarlic Tseng  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1443a6a7e7SGarlic Tseng  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1543a6a7e7SGarlic Tseng  * GNU General Public License for more details.
1643a6a7e7SGarlic Tseng  */
1743a6a7e7SGarlic Tseng 
1843a6a7e7SGarlic Tseng #include <linux/delay.h>
1943a6a7e7SGarlic Tseng #include <linux/module.h>
20dfa3cbb8SRyder Lee #include <linux/mfd/syscon.h>
2143a6a7e7SGarlic Tseng #include <linux/of.h>
2243a6a7e7SGarlic Tseng #include <linux/of_address.h>
2343a6a7e7SGarlic Tseng #include <linux/pm_runtime.h>
2443a6a7e7SGarlic Tseng 
2543a6a7e7SGarlic Tseng #include "mt2701-afe-common.h"
2643a6a7e7SGarlic Tseng #include "mt2701-afe-clock-ctrl.h"
2743a6a7e7SGarlic Tseng #include "../common/mtk-afe-platform-driver.h"
2843a6a7e7SGarlic Tseng #include "../common/mtk-afe-fe-dai.h"
2943a6a7e7SGarlic Tseng 
3043a6a7e7SGarlic Tseng static const struct snd_pcm_hardware mt2701_afe_hardware = {
3143a6a7e7SGarlic Tseng 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
3243a6a7e7SGarlic Tseng 		| SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
3343a6a7e7SGarlic Tseng 	.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
3443a6a7e7SGarlic Tseng 		   | SNDRV_PCM_FMTBIT_S32_LE,
3543a6a7e7SGarlic Tseng 	.period_bytes_min = 1024,
3643a6a7e7SGarlic Tseng 	.period_bytes_max = 1024 * 256,
3743a6a7e7SGarlic Tseng 	.periods_min = 4,
3843a6a7e7SGarlic Tseng 	.periods_max = 1024,
3943a6a7e7SGarlic Tseng 	.buffer_bytes_max = 1024 * 1024 * 16,
4043a6a7e7SGarlic Tseng 	.fifo_size = 0,
4143a6a7e7SGarlic Tseng };
4243a6a7e7SGarlic Tseng 
4343a6a7e7SGarlic Tseng struct mt2701_afe_rate {
4443a6a7e7SGarlic Tseng 	unsigned int rate;
4543a6a7e7SGarlic Tseng 	unsigned int regvalue;
4643a6a7e7SGarlic Tseng };
4743a6a7e7SGarlic Tseng 
4843a6a7e7SGarlic Tseng static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
4943a6a7e7SGarlic Tseng 	{ .rate = 8000, .regvalue = 0 },
5043a6a7e7SGarlic Tseng 	{ .rate = 12000, .regvalue = 1 },
5143a6a7e7SGarlic Tseng 	{ .rate = 16000, .regvalue = 2 },
5243a6a7e7SGarlic Tseng 	{ .rate = 24000, .regvalue = 3 },
5343a6a7e7SGarlic Tseng 	{ .rate = 32000, .regvalue = 4 },
5443a6a7e7SGarlic Tseng 	{ .rate = 48000, .regvalue = 5 },
5543a6a7e7SGarlic Tseng 	{ .rate = 96000, .regvalue = 6 },
5643a6a7e7SGarlic Tseng 	{ .rate = 192000, .regvalue = 7 },
5743a6a7e7SGarlic Tseng 	{ .rate = 384000, .regvalue = 8 },
5843a6a7e7SGarlic Tseng 	{ .rate = 7350, .regvalue = 16 },
5943a6a7e7SGarlic Tseng 	{ .rate = 11025, .regvalue = 17 },
6043a6a7e7SGarlic Tseng 	{ .rate = 14700, .regvalue = 18 },
6143a6a7e7SGarlic Tseng 	{ .rate = 22050, .regvalue = 19 },
6243a6a7e7SGarlic Tseng 	{ .rate = 29400, .regvalue = 20 },
6343a6a7e7SGarlic Tseng 	{ .rate = 44100, .regvalue = 21 },
6443a6a7e7SGarlic Tseng 	{ .rate = 88200, .regvalue = 22 },
6543a6a7e7SGarlic Tseng 	{ .rate = 176400, .regvalue = 23 },
6643a6a7e7SGarlic Tseng 	{ .rate = 352800, .regvalue = 24 },
6743a6a7e7SGarlic Tseng };
6843a6a7e7SGarlic Tseng 
6925d01dc6SWei Yongjun static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
7043a6a7e7SGarlic Tseng {
7143a6a7e7SGarlic Tseng 	int val = num - MT2701_IO_I2S;
7243a6a7e7SGarlic Tseng 
7343a6a7e7SGarlic Tseng 	if (val < 0 || val >= MT2701_I2S_NUM) {
7443a6a7e7SGarlic Tseng 		dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
7543a6a7e7SGarlic Tseng 			__func__, num, val);
7643a6a7e7SGarlic Tseng 		return -EINVAL;
7743a6a7e7SGarlic Tseng 	}
7843a6a7e7SGarlic Tseng 	return val;
7943a6a7e7SGarlic Tseng }
8043a6a7e7SGarlic Tseng 
8143a6a7e7SGarlic Tseng static int mt2701_afe_i2s_fs(unsigned int sample_rate)
8243a6a7e7SGarlic Tseng {
8343a6a7e7SGarlic Tseng 	int i;
8443a6a7e7SGarlic Tseng 
8543a6a7e7SGarlic Tseng 	for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)
8643a6a7e7SGarlic Tseng 		if (mt2701_afe_i2s_rates[i].rate == sample_rate)
8743a6a7e7SGarlic Tseng 			return mt2701_afe_i2s_rates[i].regvalue;
8843a6a7e7SGarlic Tseng 
8943a6a7e7SGarlic Tseng 	return -EINVAL;
9043a6a7e7SGarlic Tseng }
9143a6a7e7SGarlic Tseng 
9243a6a7e7SGarlic Tseng static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
9343a6a7e7SGarlic Tseng 				  struct snd_soc_dai *dai)
9443a6a7e7SGarlic Tseng {
9543a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
9643a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
9743a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
9843a6a7e7SGarlic Tseng 
9943a6a7e7SGarlic Tseng 	if (i2s_num < 0)
10043a6a7e7SGarlic Tseng 		return i2s_num;
10143a6a7e7SGarlic Tseng 
102d8d99d8eSRyder Lee 	return mt2701_afe_enable_mclk(afe, i2s_num);
10343a6a7e7SGarlic Tseng }
10443a6a7e7SGarlic Tseng 
10543a6a7e7SGarlic Tseng static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
10643a6a7e7SGarlic Tseng 					struct snd_soc_dai *dai,
107600b2fd4SRyder Lee 					int i2s_num,
10843a6a7e7SGarlic Tseng 					int dir_invert)
10943a6a7e7SGarlic Tseng {
11043a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
11143a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
11243a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
113600b2fd4SRyder Lee 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
11443a6a7e7SGarlic Tseng 	const struct mt2701_i2s_data *i2s_data;
11543a6a7e7SGarlic Tseng 	int stream_dir = substream->stream;
11643a6a7e7SGarlic Tseng 
11743a6a7e7SGarlic Tseng 	if (dir_invert)	{
11843a6a7e7SGarlic Tseng 		if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
11943a6a7e7SGarlic Tseng 			stream_dir = SNDRV_PCM_STREAM_CAPTURE;
12043a6a7e7SGarlic Tseng 		else
12143a6a7e7SGarlic Tseng 			stream_dir = SNDRV_PCM_STREAM_PLAYBACK;
12243a6a7e7SGarlic Tseng 	}
12343a6a7e7SGarlic Tseng 	i2s_data = i2s_path->i2s_data[stream_dir];
12443a6a7e7SGarlic Tseng 
12543a6a7e7SGarlic Tseng 	i2s_path->on[stream_dir]--;
12643a6a7e7SGarlic Tseng 	if (i2s_path->on[stream_dir] < 0) {
12743a6a7e7SGarlic Tseng 		dev_warn(afe->dev, "i2s_path->on: %d, dir: %d\n",
12843a6a7e7SGarlic Tseng 			 i2s_path->on[stream_dir], stream_dir);
12943a6a7e7SGarlic Tseng 		i2s_path->on[stream_dir] = 0;
13043a6a7e7SGarlic Tseng 	}
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 
138d8d99d8eSRyder Lee 	mt2701_afe_disable_i2s(afe, i2s_num, 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 {
14643a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
14743a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
14843a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
14943a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
15043a6a7e7SGarlic Tseng 	struct mt2701_i2s_path *i2s_path;
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
16043a6a7e7SGarlic Tseng 		goto I2S_UNSTART;
16143a6a7e7SGarlic Tseng 
162600b2fd4SRyder Lee 	mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 0);
16343a6a7e7SGarlic Tseng 
16443a6a7e7SGarlic Tseng 	/* need to disable i2s-out path when disable i2s-in */
16543a6a7e7SGarlic Tseng 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
166600b2fd4SRyder Lee 		mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 1);
16743a6a7e7SGarlic Tseng 
16843a6a7e7SGarlic Tseng I2S_UNSTART:
16943a6a7e7SGarlic Tseng 	/* disable mclk */
170d8d99d8eSRyder Lee 	mt2701_afe_disable_mclk(afe, i2s_num);
17143a6a7e7SGarlic Tseng }
17243a6a7e7SGarlic Tseng 
17343a6a7e7SGarlic Tseng static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream,
17443a6a7e7SGarlic Tseng 					  struct snd_soc_dai *dai,
175600b2fd4SRyder Lee 					  int i2s_num,
17643a6a7e7SGarlic Tseng 					  int dir_invert)
17743a6a7e7SGarlic Tseng {
17843a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
17943a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
18043a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
181600b2fd4SRyder Lee 	struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num];
18243a6a7e7SGarlic Tseng 	const struct mt2701_i2s_data *i2s_data;
18343a6a7e7SGarlic Tseng 	struct snd_pcm_runtime * const runtime = substream->runtime;
18443a6a7e7SGarlic Tseng 	int reg, fs, w_len = 1; /* now we support bck 64bits only */
18543a6a7e7SGarlic Tseng 	int stream_dir = substream->stream;
18643a6a7e7SGarlic Tseng 	unsigned int mask = 0, val = 0;
18743a6a7e7SGarlic Tseng 
18843a6a7e7SGarlic Tseng 	if (dir_invert) {
18943a6a7e7SGarlic Tseng 		if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
19043a6a7e7SGarlic Tseng 			stream_dir = SNDRV_PCM_STREAM_CAPTURE;
19143a6a7e7SGarlic Tseng 		else
19243a6a7e7SGarlic Tseng 			stream_dir = SNDRV_PCM_STREAM_PLAYBACK;
19343a6a7e7SGarlic Tseng 	}
19443a6a7e7SGarlic Tseng 	i2s_data = i2s_path->i2s_data[stream_dir];
19543a6a7e7SGarlic Tseng 
19643a6a7e7SGarlic Tseng 	/* no need to enable if already done */
19743a6a7e7SGarlic Tseng 	i2s_path->on[stream_dir]++;
19843a6a7e7SGarlic Tseng 
19943a6a7e7SGarlic Tseng 	if (i2s_path->on[stream_dir] != 1)
20043a6a7e7SGarlic Tseng 		return 0;
20143a6a7e7SGarlic Tseng 
20243a6a7e7SGarlic Tseng 	fs = mt2701_afe_i2s_fs(runtime->rate);
20343a6a7e7SGarlic Tseng 
20443a6a7e7SGarlic Tseng 	mask = ASYS_I2S_CON_FS |
20543a6a7e7SGarlic Tseng 	       ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */
20643a6a7e7SGarlic Tseng 	       ASYS_I2S_CON_I2S_MODE |
20743a6a7e7SGarlic Tseng 	       ASYS_I2S_CON_WIDE_MODE;
20843a6a7e7SGarlic Tseng 
20943a6a7e7SGarlic Tseng 	val = ASYS_I2S_CON_FS_SET(fs) |
21043a6a7e7SGarlic Tseng 	      ASYS_I2S_CON_I2S_MODE |
21143a6a7e7SGarlic Tseng 	      ASYS_I2S_CON_WIDE_MODE_SET(w_len);
21243a6a7e7SGarlic Tseng 
21343a6a7e7SGarlic Tseng 	if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) {
21443a6a7e7SGarlic Tseng 		mask |= ASYS_I2S_IN_PHASE_FIX;
21543a6a7e7SGarlic Tseng 		val |= ASYS_I2S_IN_PHASE_FIX;
21643a6a7e7SGarlic Tseng 	}
21743a6a7e7SGarlic Tseng 
21843a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val);
21943a6a7e7SGarlic Tseng 
22043a6a7e7SGarlic Tseng 	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
22143a6a7e7SGarlic Tseng 		reg = ASMO_TIMING_CON1;
22243a6a7e7SGarlic Tseng 	else
22343a6a7e7SGarlic Tseng 		reg = ASMI_TIMING_CON1;
22443a6a7e7SGarlic Tseng 
22543a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, reg,
22643a6a7e7SGarlic Tseng 			   i2s_data->i2s_asrc_fs_mask
22743a6a7e7SGarlic Tseng 			   << i2s_data->i2s_asrc_fs_shift,
22843a6a7e7SGarlic Tseng 			   fs << i2s_data->i2s_asrc_fs_shift);
22943a6a7e7SGarlic Tseng 
23043a6a7e7SGarlic Tseng 	/* enable i2s */
231d8d99d8eSRyder Lee 	mt2701_afe_enable_i2s(afe, i2s_num, stream_dir);
23243a6a7e7SGarlic Tseng 
23343a6a7e7SGarlic Tseng 	/* reset i2s hw status before enable */
23443a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
23543a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET);
23643a6a7e7SGarlic Tseng 	udelay(1);
23743a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
23843a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_RESET, 0);
23943a6a7e7SGarlic Tseng 	udelay(1);
24043a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
24143a6a7e7SGarlic Tseng 			   ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN);
24243a6a7e7SGarlic Tseng 	return 0;
24343a6a7e7SGarlic Tseng }
24443a6a7e7SGarlic Tseng 
24543a6a7e7SGarlic Tseng static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
24643a6a7e7SGarlic Tseng 				  struct snd_soc_dai *dai)
24743a6a7e7SGarlic Tseng {
24843a6a7e7SGarlic Tseng 	int clk_domain;
24943a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
25043a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
25143a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
25243a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
25343a6a7e7SGarlic Tseng 	struct mt2701_i2s_path *i2s_path;
25443a6a7e7SGarlic Tseng 	int mclk_rate;
25543a6a7e7SGarlic Tseng 
25643a6a7e7SGarlic Tseng 	if (i2s_num < 0)
25743a6a7e7SGarlic Tseng 		return i2s_num;
25843a6a7e7SGarlic Tseng 
25943a6a7e7SGarlic Tseng 	i2s_path = &afe_priv->i2s_path[i2s_num];
26043a6a7e7SGarlic Tseng 	mclk_rate = i2s_path->mclk_rate;
26143a6a7e7SGarlic Tseng 
26243a6a7e7SGarlic Tseng 	if (i2s_path->occupied[substream->stream])
26343a6a7e7SGarlic Tseng 		return -EBUSY;
26443a6a7e7SGarlic Tseng 	i2s_path->occupied[substream->stream] = 1;
26543a6a7e7SGarlic Tseng 
26643a6a7e7SGarlic Tseng 	if (MT2701_PLL_DOMAIN_0_RATE % mclk_rate == 0) {
26743a6a7e7SGarlic Tseng 		clk_domain = 0;
26843a6a7e7SGarlic Tseng 	} else if (MT2701_PLL_DOMAIN_1_RATE % mclk_rate == 0) {
26943a6a7e7SGarlic Tseng 		clk_domain = 1;
27043a6a7e7SGarlic Tseng 	} else {
27143a6a7e7SGarlic Tseng 		dev_err(dai->dev, "%s() bad mclk rate %d\n",
27243a6a7e7SGarlic Tseng 			__func__, mclk_rate);
27343a6a7e7SGarlic Tseng 		return -EINVAL;
27443a6a7e7SGarlic Tseng 	}
27543a6a7e7SGarlic Tseng 	mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate);
27643a6a7e7SGarlic Tseng 
27743a6a7e7SGarlic Tseng 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
278600b2fd4SRyder Lee 		mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0);
27943a6a7e7SGarlic Tseng 	} else {
28043a6a7e7SGarlic Tseng 		/* need to enable i2s-out path when enable i2s-in */
28143a6a7e7SGarlic Tseng 		/* prepare for another direction "out" */
282600b2fd4SRyder Lee 		mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 1);
28343a6a7e7SGarlic Tseng 		/* prepare for "in" */
284600b2fd4SRyder Lee 		mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0);
28543a6a7e7SGarlic Tseng 	}
28643a6a7e7SGarlic Tseng 
28743a6a7e7SGarlic Tseng 	return 0;
28843a6a7e7SGarlic Tseng }
28943a6a7e7SGarlic Tseng 
29043a6a7e7SGarlic Tseng static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
29143a6a7e7SGarlic Tseng 				     unsigned int freq, int dir)
29243a6a7e7SGarlic Tseng {
29343a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
29443a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
29543a6a7e7SGarlic Tseng 	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
29643a6a7e7SGarlic Tseng 
29743a6a7e7SGarlic Tseng 	if (i2s_num < 0)
29843a6a7e7SGarlic Tseng 		return i2s_num;
29943a6a7e7SGarlic Tseng 
30043a6a7e7SGarlic Tseng 	/* mclk */
30143a6a7e7SGarlic Tseng 	if (dir == SND_SOC_CLOCK_IN) {
30243a6a7e7SGarlic Tseng 		dev_warn(dai->dev,
30343a6a7e7SGarlic Tseng 			 "%s() warning: mt2701 doesn't support mclk input\n",
30443a6a7e7SGarlic Tseng 			__func__);
30543a6a7e7SGarlic Tseng 		return -EINVAL;
30643a6a7e7SGarlic Tseng 	}
30743a6a7e7SGarlic Tseng 	afe_priv->i2s_path[i2s_num].mclk_rate = freq;
30843a6a7e7SGarlic Tseng 	return 0;
30943a6a7e7SGarlic Tseng }
31043a6a7e7SGarlic Tseng 
3114bdc8d45SGarlic Tseng static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
3124bdc8d45SGarlic Tseng 				struct snd_soc_dai *dai)
3134bdc8d45SGarlic Tseng {
3144bdc8d45SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
3154bdc8d45SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
3164bdc8d45SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
317d8d99d8eSRyder Lee 	int ret;
3184bdc8d45SGarlic Tseng 
319d8d99d8eSRyder Lee 	ret = mt2701_enable_btmrg_clk(afe);
320d8d99d8eSRyder Lee 	if (ret)
321d8d99d8eSRyder Lee 		return ret;
3224bdc8d45SGarlic Tseng 
3234bdc8d45SGarlic Tseng 	afe_priv->mrg_enable[substream->stream] = 1;
3244bdc8d45SGarlic Tseng 	return 0;
3254bdc8d45SGarlic Tseng }
3264bdc8d45SGarlic Tseng 
3274bdc8d45SGarlic Tseng static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
3284bdc8d45SGarlic Tseng 				  struct snd_pcm_hw_params *params,
3294bdc8d45SGarlic Tseng 				  struct snd_soc_dai *dai)
3304bdc8d45SGarlic Tseng {
3314bdc8d45SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
3324bdc8d45SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
3334bdc8d45SGarlic Tseng 	int stream_fs;
3344bdc8d45SGarlic Tseng 	u32 val, msk;
3354bdc8d45SGarlic Tseng 
3364bdc8d45SGarlic Tseng 	stream_fs = params_rate(params);
3374bdc8d45SGarlic Tseng 
3384bdc8d45SGarlic Tseng 	if ((stream_fs != 8000) && (stream_fs != 16000)) {
3394bdc8d45SGarlic Tseng 		dev_err(afe->dev, "%s() btmgr not supprt this stream_fs %d\n",
3404bdc8d45SGarlic Tseng 			__func__, stream_fs);
3414bdc8d45SGarlic Tseng 		return -EINVAL;
3424bdc8d45SGarlic Tseng 	}
3434bdc8d45SGarlic Tseng 
3444bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3454bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_I2S_MODE_MASK,
3464bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_I2S_MODE_32K);
3474bdc8d45SGarlic Tseng 
3484bdc8d45SGarlic Tseng 	val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY
3494bdc8d45SGarlic Tseng 	      | AFE_DAIBT_CON0_MRG_USE;
3504bdc8d45SGarlic Tseng 	msk = val;
3514bdc8d45SGarlic Tseng 
3524bdc8d45SGarlic Tseng 	if (stream_fs == 16000)
3534bdc8d45SGarlic Tseng 		val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
3544bdc8d45SGarlic Tseng 
3554bdc8d45SGarlic Tseng 	msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
3564bdc8d45SGarlic Tseng 
3574bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);
3584bdc8d45SGarlic Tseng 
3594bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
3604bdc8d45SGarlic Tseng 			   AFE_DAIBT_CON0_DAIBT_EN,
3614bdc8d45SGarlic Tseng 			   AFE_DAIBT_CON0_DAIBT_EN);
3624bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3634bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_I2S_EN,
3644bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_I2S_EN);
3654bdc8d45SGarlic Tseng 	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3664bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_EN,
3674bdc8d45SGarlic Tseng 			   AFE_MRGIF_CON_MRG_EN);
3684bdc8d45SGarlic Tseng 	return 0;
3694bdc8d45SGarlic Tseng }
3704bdc8d45SGarlic Tseng 
3714bdc8d45SGarlic Tseng static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
3724bdc8d45SGarlic Tseng 				  struct snd_soc_dai *dai)
3734bdc8d45SGarlic Tseng {
3744bdc8d45SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
3754bdc8d45SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
3764bdc8d45SGarlic Tseng 	struct mt2701_afe_private *afe_priv = afe->platform_priv;
3774bdc8d45SGarlic Tseng 
3784bdc8d45SGarlic Tseng 	/* if the other direction stream is not occupied */
3794bdc8d45SGarlic Tseng 	if (!afe_priv->mrg_enable[!substream->stream]) {
3804bdc8d45SGarlic Tseng 		regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
3814bdc8d45SGarlic Tseng 				   AFE_DAIBT_CON0_DAIBT_EN, 0);
3824bdc8d45SGarlic Tseng 		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3834bdc8d45SGarlic Tseng 				   AFE_MRGIF_CON_MRG_EN, 0);
3844bdc8d45SGarlic Tseng 		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3854bdc8d45SGarlic Tseng 				   AFE_MRGIF_CON_MRG_I2S_EN, 0);
386d8d99d8eSRyder Lee 		mt2701_disable_btmrg_clk(afe);
3874bdc8d45SGarlic Tseng 	}
3884bdc8d45SGarlic Tseng 	afe_priv->mrg_enable[substream->stream] = 0;
3894bdc8d45SGarlic Tseng }
3904bdc8d45SGarlic Tseng 
39143a6a7e7SGarlic Tseng static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
39243a6a7e7SGarlic Tseng 				    struct snd_soc_dai *dai)
39343a6a7e7SGarlic Tseng {
39443a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
39543a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
39643a6a7e7SGarlic Tseng 	int stream_dir = substream->stream;
39743a6a7e7SGarlic Tseng 	int memif_num = rtd->cpu_dai->id;
39843a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif_tmp;
39943a6a7e7SGarlic Tseng 
40043a6a7e7SGarlic Tseng 	/* can't run single DL & DLM at the same time */
40143a6a7e7SGarlic Tseng 	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
40243a6a7e7SGarlic Tseng 		memif_tmp = &afe->memif[MT2701_MEMIF_DLM];
40343a6a7e7SGarlic Tseng 		if (memif_tmp->substream) {
40443a6a7e7SGarlic Tseng 			dev_warn(afe->dev, "%s memif is not available, stream_dir %d, memif_num %d\n",
40543a6a7e7SGarlic Tseng 				 __func__, stream_dir, memif_num);
40643a6a7e7SGarlic Tseng 			return -EBUSY;
40743a6a7e7SGarlic Tseng 		}
40843a6a7e7SGarlic Tseng 	}
40943a6a7e7SGarlic Tseng 	return mtk_afe_fe_startup(substream, dai);
41043a6a7e7SGarlic Tseng }
41143a6a7e7SGarlic Tseng 
41243a6a7e7SGarlic Tseng static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
41343a6a7e7SGarlic Tseng 				      struct snd_pcm_hw_params *params,
41443a6a7e7SGarlic Tseng 				      struct snd_soc_dai *dai)
41543a6a7e7SGarlic Tseng {
41643a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
41743a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
41843a6a7e7SGarlic Tseng 	int stream_dir = substream->stream;
41943a6a7e7SGarlic Tseng 
42043a6a7e7SGarlic Tseng 	/* single DL use PAIR_INTERLEAVE */
42143a6a7e7SGarlic Tseng 	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
42243a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap,
42343a6a7e7SGarlic Tseng 				   AFE_MEMIF_PBUF_SIZE,
42443a6a7e7SGarlic Tseng 				   AFE_MEMIF_PBUF_SIZE_DLM_MASK,
42543a6a7e7SGarlic Tseng 				   AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE);
42643a6a7e7SGarlic Tseng 	}
42743a6a7e7SGarlic Tseng 	return mtk_afe_fe_hw_params(substream, params, dai);
42843a6a7e7SGarlic Tseng }
42943a6a7e7SGarlic Tseng 
43043a6a7e7SGarlic Tseng static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
43143a6a7e7SGarlic Tseng 				 struct snd_soc_dai *dai)
43243a6a7e7SGarlic Tseng {
43343a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
43443a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
43543a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif_tmp;
43643a6a7e7SGarlic Tseng 	const struct mtk_base_memif_data *memif_data;
43743a6a7e7SGarlic Tseng 	int i;
43843a6a7e7SGarlic Tseng 
43943a6a7e7SGarlic Tseng 	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
44043a6a7e7SGarlic Tseng 		memif_tmp = &afe->memif[i];
44143a6a7e7SGarlic Tseng 		if (memif_tmp->substream)
44243a6a7e7SGarlic Tseng 			return -EBUSY;
44343a6a7e7SGarlic Tseng 	}
44443a6a7e7SGarlic Tseng 
44543a6a7e7SGarlic Tseng 	/* enable agent for all signal DL (due to hw design) */
44643a6a7e7SGarlic Tseng 	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
44743a6a7e7SGarlic Tseng 		memif_data = afe->memif[i].data;
44843a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap,
44943a6a7e7SGarlic Tseng 				   memif_data->agent_disable_reg,
45043a6a7e7SGarlic Tseng 				   1 << memif_data->agent_disable_shift,
45143a6a7e7SGarlic Tseng 				   0 << memif_data->agent_disable_shift);
45243a6a7e7SGarlic Tseng 	}
45343a6a7e7SGarlic Tseng 
45443a6a7e7SGarlic Tseng 	return mtk_afe_fe_startup(substream, dai);
45543a6a7e7SGarlic Tseng }
45643a6a7e7SGarlic Tseng 
45743a6a7e7SGarlic Tseng static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
45843a6a7e7SGarlic Tseng 				   struct snd_soc_dai *dai)
45943a6a7e7SGarlic Tseng {
46043a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
46143a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
46243a6a7e7SGarlic Tseng 	const struct mtk_base_memif_data *memif_data;
46343a6a7e7SGarlic Tseng 	int i;
46443a6a7e7SGarlic Tseng 
46543a6a7e7SGarlic Tseng 	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
46643a6a7e7SGarlic Tseng 		memif_data = afe->memif[i].data;
46743a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap,
46843a6a7e7SGarlic Tseng 				   memif_data->agent_disable_reg,
46943a6a7e7SGarlic Tseng 				   1 << memif_data->agent_disable_shift,
47043a6a7e7SGarlic Tseng 				   1 << memif_data->agent_disable_shift);
47143a6a7e7SGarlic Tseng 	}
47243a6a7e7SGarlic Tseng 	return mtk_afe_fe_shutdown(substream, dai);
47343a6a7e7SGarlic Tseng }
47443a6a7e7SGarlic Tseng 
47543a6a7e7SGarlic Tseng static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
47643a6a7e7SGarlic Tseng 				   struct snd_pcm_hw_params *params,
47743a6a7e7SGarlic Tseng 				   struct snd_soc_dai *dai)
47843a6a7e7SGarlic Tseng {
47943a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
48043a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
48143a6a7e7SGarlic Tseng 	int channels = params_channels(params);
48243a6a7e7SGarlic Tseng 
48343a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap,
48443a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE,
48543a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_MASK,
48643a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE);
48743a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap,
48843a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE,
48943a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK,
49043a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_32BYTES);
49143a6a7e7SGarlic Tseng 	regmap_update_bits(afe->regmap,
49243a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE,
49343a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK,
49443a6a7e7SGarlic Tseng 			   AFE_MEMIF_PBUF_SIZE_DLM_CH(channels));
49543a6a7e7SGarlic Tseng 
49643a6a7e7SGarlic Tseng 	return mtk_afe_fe_hw_params(substream, params, dai);
49743a6a7e7SGarlic Tseng }
49843a6a7e7SGarlic Tseng 
49943a6a7e7SGarlic Tseng static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
50043a6a7e7SGarlic Tseng 				 int cmd, struct snd_soc_dai *dai)
50143a6a7e7SGarlic Tseng {
50243a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
50343a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
50443a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
50543a6a7e7SGarlic Tseng 
50643a6a7e7SGarlic Tseng 	switch (cmd) {
50743a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_START:
50843a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_RESUME:
50943a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
51043a6a7e7SGarlic Tseng 				   1 << memif_tmp->data->enable_shift,
51143a6a7e7SGarlic Tseng 				   1 << memif_tmp->data->enable_shift);
51243a6a7e7SGarlic Tseng 		mtk_afe_fe_trigger(substream, cmd, dai);
51343a6a7e7SGarlic Tseng 		return 0;
51443a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_STOP:
51543a6a7e7SGarlic Tseng 	case SNDRV_PCM_TRIGGER_SUSPEND:
51643a6a7e7SGarlic Tseng 		mtk_afe_fe_trigger(substream, cmd, dai);
51743a6a7e7SGarlic Tseng 		regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
51843a6a7e7SGarlic Tseng 				   1 << memif_tmp->data->enable_shift, 0);
51943a6a7e7SGarlic Tseng 
52043a6a7e7SGarlic Tseng 		return 0;
52143a6a7e7SGarlic Tseng 	default:
52243a6a7e7SGarlic Tseng 		return -EINVAL;
52343a6a7e7SGarlic Tseng 	}
52443a6a7e7SGarlic Tseng }
52543a6a7e7SGarlic Tseng 
52643a6a7e7SGarlic Tseng static int mt2701_memif_fs(struct snd_pcm_substream *substream,
52743a6a7e7SGarlic Tseng 			   unsigned int rate)
52843a6a7e7SGarlic Tseng {
52943a6a7e7SGarlic Tseng 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
53043a6a7e7SGarlic Tseng 	int fs;
53143a6a7e7SGarlic Tseng 
53243a6a7e7SGarlic Tseng 	if (rtd->cpu_dai->id != MT2701_MEMIF_ULBT)
53343a6a7e7SGarlic Tseng 		fs = mt2701_afe_i2s_fs(rate);
53443a6a7e7SGarlic Tseng 	else
53543a6a7e7SGarlic Tseng 		fs = (rate == 16000 ? 1 : 0);
53643a6a7e7SGarlic Tseng 	return fs;
53743a6a7e7SGarlic Tseng }
53843a6a7e7SGarlic Tseng 
53943a6a7e7SGarlic Tseng static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
54043a6a7e7SGarlic Tseng {
54143a6a7e7SGarlic Tseng 	return mt2701_afe_i2s_fs(rate);
54243a6a7e7SGarlic Tseng }
54343a6a7e7SGarlic Tseng 
54443a6a7e7SGarlic Tseng /* FE DAIs */
54543a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = {
54643a6a7e7SGarlic Tseng 	.startup	= mt2701_simple_fe_startup,
54743a6a7e7SGarlic Tseng 	.shutdown	= mtk_afe_fe_shutdown,
54843a6a7e7SGarlic Tseng 	.hw_params	= mt2701_simple_fe_hw_params,
54943a6a7e7SGarlic Tseng 	.hw_free	= mtk_afe_fe_hw_free,
55043a6a7e7SGarlic Tseng 	.prepare	= mtk_afe_fe_prepare,
55143a6a7e7SGarlic Tseng 	.trigger	= mtk_afe_fe_trigger,
55243a6a7e7SGarlic Tseng };
55343a6a7e7SGarlic Tseng 
55443a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = {
55543a6a7e7SGarlic Tseng 	.startup	= mt2701_dlm_fe_startup,
55643a6a7e7SGarlic Tseng 	.shutdown	= mt2701_dlm_fe_shutdown,
55743a6a7e7SGarlic Tseng 	.hw_params	= mt2701_dlm_fe_hw_params,
55843a6a7e7SGarlic Tseng 	.hw_free	= mtk_afe_fe_hw_free,
55943a6a7e7SGarlic Tseng 	.prepare	= mtk_afe_fe_prepare,
56043a6a7e7SGarlic Tseng 	.trigger	= mt2701_dlm_fe_trigger,
56143a6a7e7SGarlic Tseng };
56243a6a7e7SGarlic Tseng 
56343a6a7e7SGarlic Tseng /* I2S BE DAIs */
56443a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {
56543a6a7e7SGarlic Tseng 	.startup	= mt2701_afe_i2s_startup,
56643a6a7e7SGarlic Tseng 	.shutdown	= mt2701_afe_i2s_shutdown,
56743a6a7e7SGarlic Tseng 	.prepare	= mt2701_afe_i2s_prepare,
56843a6a7e7SGarlic Tseng 	.set_sysclk	= mt2701_afe_i2s_set_sysclk,
56943a6a7e7SGarlic Tseng };
57043a6a7e7SGarlic Tseng 
5714bdc8d45SGarlic Tseng /* MRG BE DAIs */
572549acff9SGustavo A. R. Silva static const struct snd_soc_dai_ops mt2701_btmrg_ops = {
5734bdc8d45SGarlic Tseng 	.startup = mt2701_btmrg_startup,
5744bdc8d45SGarlic Tseng 	.shutdown = mt2701_btmrg_shutdown,
5754bdc8d45SGarlic Tseng 	.hw_params = mt2701_btmrg_hw_params,
5764bdc8d45SGarlic Tseng };
5774bdc8d45SGarlic Tseng 
57843a6a7e7SGarlic Tseng static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
57943a6a7e7SGarlic Tseng 	/* FE DAIs: memory intefaces to CPU */
58043a6a7e7SGarlic Tseng 	{
5818625c1dbSRyder Lee 		.name = "PCMO0",
5828625c1dbSRyder Lee 		.id = MT2701_MEMIF_DL1,
5838625c1dbSRyder Lee 		.suspend = mtk_afe_dai_suspend,
5848625c1dbSRyder Lee 		.resume = mtk_afe_dai_resume,
5858625c1dbSRyder Lee 		.playback = {
5868625c1dbSRyder Lee 			.stream_name = "DL1",
5878625c1dbSRyder Lee 			.channels_min = 1,
5888625c1dbSRyder Lee 			.channels_max = 2,
5898625c1dbSRyder Lee 			.rates = SNDRV_PCM_RATE_8000_192000,
5908625c1dbSRyder Lee 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
5918625c1dbSRyder Lee 				| SNDRV_PCM_FMTBIT_S24_LE
5928625c1dbSRyder Lee 				| SNDRV_PCM_FMTBIT_S32_LE)
5938625c1dbSRyder Lee 		},
5948625c1dbSRyder Lee 		.ops = &mt2701_single_memif_dai_ops,
5958625c1dbSRyder Lee 	},
5968625c1dbSRyder Lee 	{
59743a6a7e7SGarlic Tseng 		.name = "PCM_multi",
59843a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DLM,
59943a6a7e7SGarlic Tseng 		.suspend = mtk_afe_dai_suspend,
60043a6a7e7SGarlic Tseng 		.resume = mtk_afe_dai_resume,
60143a6a7e7SGarlic Tseng 		.playback = {
60243a6a7e7SGarlic Tseng 			.stream_name = "DLM",
60343a6a7e7SGarlic Tseng 			.channels_min = 1,
60443a6a7e7SGarlic Tseng 			.channels_max = 8,
60543a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
60643a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
60743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
60843a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
60943a6a7e7SGarlic Tseng 
61043a6a7e7SGarlic Tseng 		},
61143a6a7e7SGarlic Tseng 		.ops = &mt2701_dlm_memif_dai_ops,
61243a6a7e7SGarlic Tseng 	},
61343a6a7e7SGarlic Tseng 	{
61443a6a7e7SGarlic Tseng 		.name = "PCM0",
61543a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL1,
61643a6a7e7SGarlic Tseng 		.suspend = mtk_afe_dai_suspend,
61743a6a7e7SGarlic Tseng 		.resume = mtk_afe_dai_resume,
61843a6a7e7SGarlic Tseng 		.capture = {
61943a6a7e7SGarlic Tseng 			.stream_name = "UL1",
62043a6a7e7SGarlic Tseng 			.channels_min = 1,
62143a6a7e7SGarlic Tseng 			.channels_max = 2,
62243a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_48000,
62343a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
62443a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
62543a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
62643a6a7e7SGarlic Tseng 		},
62743a6a7e7SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
62843a6a7e7SGarlic Tseng 	},
62943a6a7e7SGarlic Tseng 	{
63043a6a7e7SGarlic Tseng 		.name = "PCM1",
63143a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL2,
63243a6a7e7SGarlic Tseng 		.suspend = mtk_afe_dai_suspend,
63343a6a7e7SGarlic Tseng 		.resume = mtk_afe_dai_resume,
63443a6a7e7SGarlic Tseng 		.capture = {
63543a6a7e7SGarlic Tseng 			.stream_name = "UL2",
63643a6a7e7SGarlic Tseng 			.channels_min = 1,
63743a6a7e7SGarlic Tseng 			.channels_max = 2,
63843a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
63943a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
64043a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
64143a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
64243a6a7e7SGarlic Tseng 
64343a6a7e7SGarlic Tseng 		},
64443a6a7e7SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
64543a6a7e7SGarlic Tseng 	},
6464bdc8d45SGarlic Tseng 	{
6474bdc8d45SGarlic Tseng 		.name = "PCM_BT_DL",
6484bdc8d45SGarlic Tseng 		.id = MT2701_MEMIF_DLBT,
6494bdc8d45SGarlic Tseng 		.suspend = mtk_afe_dai_suspend,
6504bdc8d45SGarlic Tseng 		.resume = mtk_afe_dai_resume,
6514bdc8d45SGarlic Tseng 		.playback = {
6524bdc8d45SGarlic Tseng 			.stream_name = "DLBT",
6534bdc8d45SGarlic Tseng 			.channels_min = 1,
6544bdc8d45SGarlic Tseng 			.channels_max = 1,
6554bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
6564bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
6574bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
6584bdc8d45SGarlic Tseng 		},
6594bdc8d45SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
6604bdc8d45SGarlic Tseng 	},
6614bdc8d45SGarlic Tseng 	{
6624bdc8d45SGarlic Tseng 		.name = "PCM_BT_UL",
6634bdc8d45SGarlic Tseng 		.id = MT2701_MEMIF_ULBT,
6644bdc8d45SGarlic Tseng 		.suspend = mtk_afe_dai_suspend,
6654bdc8d45SGarlic Tseng 		.resume = mtk_afe_dai_resume,
6664bdc8d45SGarlic Tseng 		.capture = {
6674bdc8d45SGarlic Tseng 			.stream_name = "ULBT",
6684bdc8d45SGarlic Tseng 			.channels_min = 1,
6694bdc8d45SGarlic Tseng 			.channels_max = 1,
6704bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
6714bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
6724bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
6734bdc8d45SGarlic Tseng 		},
6744bdc8d45SGarlic Tseng 		.ops = &mt2701_single_memif_dai_ops,
6754bdc8d45SGarlic Tseng 	},
67643a6a7e7SGarlic Tseng 	/* BE DAIs */
67743a6a7e7SGarlic Tseng 	{
67843a6a7e7SGarlic Tseng 		.name = "I2S0",
67943a6a7e7SGarlic Tseng 		.id = MT2701_IO_I2S,
68043a6a7e7SGarlic Tseng 		.playback = {
68143a6a7e7SGarlic Tseng 			.stream_name = "I2S0 Playback",
68243a6a7e7SGarlic Tseng 			.channels_min = 1,
68343a6a7e7SGarlic Tseng 			.channels_max = 2,
68443a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
68543a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
68643a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
68743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
68843a6a7e7SGarlic Tseng 
68943a6a7e7SGarlic Tseng 		},
69043a6a7e7SGarlic Tseng 		.capture = {
69143a6a7e7SGarlic Tseng 			.stream_name = "I2S0 Capture",
69243a6a7e7SGarlic Tseng 			.channels_min = 1,
69343a6a7e7SGarlic Tseng 			.channels_max = 2,
69443a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
69543a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
69643a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
69743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
69843a6a7e7SGarlic Tseng 
69943a6a7e7SGarlic Tseng 		},
70043a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
70143a6a7e7SGarlic Tseng 		.symmetric_rates = 1,
70243a6a7e7SGarlic Tseng 	},
70343a6a7e7SGarlic Tseng 	{
70443a6a7e7SGarlic Tseng 		.name = "I2S1",
70543a6a7e7SGarlic Tseng 		.id = MT2701_IO_2ND_I2S,
70643a6a7e7SGarlic Tseng 		.playback = {
70743a6a7e7SGarlic Tseng 			.stream_name = "I2S1 Playback",
70843a6a7e7SGarlic Tseng 			.channels_min = 1,
70943a6a7e7SGarlic Tseng 			.channels_max = 2,
71043a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
71143a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
71243a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
71343a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
71443a6a7e7SGarlic Tseng 			},
71543a6a7e7SGarlic Tseng 		.capture = {
71643a6a7e7SGarlic Tseng 			.stream_name = "I2S1 Capture",
71743a6a7e7SGarlic Tseng 			.channels_min = 1,
71843a6a7e7SGarlic Tseng 			.channels_max = 2,
71943a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
72043a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
72143a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
72243a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
72343a6a7e7SGarlic Tseng 			},
72443a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
72543a6a7e7SGarlic Tseng 		.symmetric_rates = 1,
72643a6a7e7SGarlic Tseng 	},
72743a6a7e7SGarlic Tseng 	{
72843a6a7e7SGarlic Tseng 		.name = "I2S2",
72943a6a7e7SGarlic Tseng 		.id = MT2701_IO_3RD_I2S,
73043a6a7e7SGarlic Tseng 		.playback = {
73143a6a7e7SGarlic Tseng 			.stream_name = "I2S2 Playback",
73243a6a7e7SGarlic Tseng 			.channels_min = 1,
73343a6a7e7SGarlic Tseng 			.channels_max = 2,
73443a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
73543a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
73643a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
73743a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
73843a6a7e7SGarlic Tseng 			},
73943a6a7e7SGarlic Tseng 		.capture = {
74043a6a7e7SGarlic Tseng 			.stream_name = "I2S2 Capture",
74143a6a7e7SGarlic Tseng 			.channels_min = 1,
74243a6a7e7SGarlic Tseng 			.channels_max = 2,
74343a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
74443a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
74543a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
74643a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
74743a6a7e7SGarlic Tseng 			},
74843a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
74943a6a7e7SGarlic Tseng 		.symmetric_rates = 1,
75043a6a7e7SGarlic Tseng 	},
75143a6a7e7SGarlic Tseng 	{
75243a6a7e7SGarlic Tseng 		.name = "I2S3",
75343a6a7e7SGarlic Tseng 		.id = MT2701_IO_4TH_I2S,
75443a6a7e7SGarlic Tseng 		.playback = {
75543a6a7e7SGarlic Tseng 			.stream_name = "I2S3 Playback",
75643a6a7e7SGarlic Tseng 			.channels_min = 1,
75743a6a7e7SGarlic Tseng 			.channels_max = 2,
75843a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
75943a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
76043a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
76143a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
76243a6a7e7SGarlic Tseng 			},
76343a6a7e7SGarlic Tseng 		.capture = {
76443a6a7e7SGarlic Tseng 			.stream_name = "I2S3 Capture",
76543a6a7e7SGarlic Tseng 			.channels_min = 1,
76643a6a7e7SGarlic Tseng 			.channels_max = 2,
76743a6a7e7SGarlic Tseng 			.rates = SNDRV_PCM_RATE_8000_192000,
76843a6a7e7SGarlic Tseng 			.formats = (SNDRV_PCM_FMTBIT_S16_LE
76943a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S24_LE
77043a6a7e7SGarlic Tseng 				| SNDRV_PCM_FMTBIT_S32_LE)
77143a6a7e7SGarlic Tseng 			},
77243a6a7e7SGarlic Tseng 		.ops = &mt2701_afe_i2s_ops,
77343a6a7e7SGarlic Tseng 		.symmetric_rates = 1,
77443a6a7e7SGarlic Tseng 	},
7754bdc8d45SGarlic Tseng 	{
7764bdc8d45SGarlic Tseng 		.name = "MRG BT",
7774bdc8d45SGarlic Tseng 		.id = MT2701_IO_MRG,
7784bdc8d45SGarlic Tseng 		.playback = {
7794bdc8d45SGarlic Tseng 			.stream_name = "BT Playback",
7804bdc8d45SGarlic Tseng 			.channels_min = 1,
7814bdc8d45SGarlic Tseng 			.channels_max = 1,
7824bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
7834bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
7844bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
7854bdc8d45SGarlic Tseng 		},
7864bdc8d45SGarlic Tseng 		.capture = {
7874bdc8d45SGarlic Tseng 			.stream_name = "BT Capture",
7884bdc8d45SGarlic Tseng 			.channels_min = 1,
7894bdc8d45SGarlic Tseng 			.channels_max = 1,
7904bdc8d45SGarlic Tseng 			.rates = (SNDRV_PCM_RATE_8000
7914bdc8d45SGarlic Tseng 				| SNDRV_PCM_RATE_16000),
7924bdc8d45SGarlic Tseng 			.formats = SNDRV_PCM_FMTBIT_S16_LE,
7934bdc8d45SGarlic Tseng 		},
7944bdc8d45SGarlic Tseng 		.ops = &mt2701_btmrg_ops,
7954bdc8d45SGarlic Tseng 		.symmetric_rates = 1,
7964bdc8d45SGarlic Tseng 	}
79743a6a7e7SGarlic Tseng };
79843a6a7e7SGarlic Tseng 
79943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = {
80043a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0),
80143a6a7e7SGarlic Tseng };
80243a6a7e7SGarlic Tseng 
80343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o01_mix[] = {
80443a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0),
80543a6a7e7SGarlic Tseng };
80643a6a7e7SGarlic Tseng 
80743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o02_mix[] = {
80843a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0),
80943a6a7e7SGarlic Tseng };
81043a6a7e7SGarlic Tseng 
81143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o03_mix[] = {
81243a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0),
81343a6a7e7SGarlic Tseng };
81443a6a7e7SGarlic Tseng 
81543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o14_mix[] = {
81643a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0),
81743a6a7e7SGarlic Tseng };
81843a6a7e7SGarlic Tseng 
81943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o15_mix[] = {
82043a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0),
82143a6a7e7SGarlic Tseng };
82243a6a7e7SGarlic Tseng 
82343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o16_mix[] = {
82443a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0),
82543a6a7e7SGarlic Tseng };
82643a6a7e7SGarlic Tseng 
82743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o17_mix[] = {
82843a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0),
82943a6a7e7SGarlic Tseng };
83043a6a7e7SGarlic Tseng 
83143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o18_mix[] = {
83243a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0),
83343a6a7e7SGarlic Tseng };
83443a6a7e7SGarlic Tseng 
83543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o19_mix[] = {
83643a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0),
83743a6a7e7SGarlic Tseng };
83843a6a7e7SGarlic Tseng 
83943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o20_mix[] = {
84043a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0),
84143a6a7e7SGarlic Tseng };
84243a6a7e7SGarlic Tseng 
84343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o21_mix[] = {
84443a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0),
84543a6a7e7SGarlic Tseng };
84643a6a7e7SGarlic Tseng 
84743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = {
84843a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),
84943a6a7e7SGarlic Tseng };
85043a6a7e7SGarlic Tseng 
85143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o23_mix[] = {
85243a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0),
85343a6a7e7SGarlic Tseng };
85443a6a7e7SGarlic Tseng 
85543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o24_mix[] = {
85643a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0),
85743a6a7e7SGarlic Tseng };
85843a6a7e7SGarlic Tseng 
85943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = {
86043a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0),
86143a6a7e7SGarlic Tseng };
86243a6a7e7SGarlic Tseng 
86343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_i02_mix[] = {
86443a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0),
86543a6a7e7SGarlic Tseng };
86643a6a7e7SGarlic Tseng 
86743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = {
86843a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch",
86943a6a7e7SGarlic Tseng 				    ASYS_I2SO1_CON, 26, 1, 0),
87043a6a7e7SGarlic Tseng };
87143a6a7e7SGarlic Tseng 
87243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = {
87343a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch",
87443a6a7e7SGarlic Tseng 				    ASYS_I2SO2_CON, 26, 1, 0),
87543a6a7e7SGarlic Tseng };
87643a6a7e7SGarlic Tseng 
87743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = {
87843a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch",
87943a6a7e7SGarlic Tseng 				    PWR2_TOP_CON, 17, 1, 0),
88043a6a7e7SGarlic Tseng };
88143a6a7e7SGarlic Tseng 
88243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = {
88343a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch",
88443a6a7e7SGarlic Tseng 				    PWR2_TOP_CON, 18, 1, 0),
88543a6a7e7SGarlic Tseng };
88643a6a7e7SGarlic Tseng 
88743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = {
88843a6a7e7SGarlic Tseng 	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S4 Out Switch",
88943a6a7e7SGarlic Tseng 				    PWR2_TOP_CON, 19, 1, 0),
89043a6a7e7SGarlic Tseng };
89143a6a7e7SGarlic Tseng 
89243a6a7e7SGarlic Tseng static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
89343a6a7e7SGarlic Tseng 	/* inter-connections */
89443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),
89543a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0),
89643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix,
89743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_i02_mix)),
89843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
89943a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0),
90043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0),
90143a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0),
90243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0),
90343a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0),
90443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
90543a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),
90643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0),
90743a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0),
90843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0),
90943a6a7e7SGarlic Tseng 
91043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix,
91143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o00_mix)),
91243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix,
91343a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o01_mix)),
91443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix,
91543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o02_mix)),
91643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix,
91743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o03_mix)),
91843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix,
91943a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o14_mix)),
92043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix,
92143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o15_mix)),
92243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix,
92343a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o16_mix)),
92443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix,
92543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o17_mix)),
92643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix,
92743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o18_mix)),
92843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix,
92943a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o19_mix)),
93043a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix,
93143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o20_mix)),
93243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix,
93343a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o21_mix)),
93443a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix,
93543a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o22_mix)),
93643a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix,
93743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_o31_mix)),
93843a6a7e7SGarlic Tseng 
93943a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0,
94043a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s0,
94143a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)),
94243a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0,
94343a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s1,
94443a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)),
94543a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0,
94643a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s2,
94743a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)),
94843a6a7e7SGarlic Tseng 	SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0,
94943a6a7e7SGarlic Tseng 			   mt2701_afe_multi_ch_out_i2s3,
95043a6a7e7SGarlic Tseng 			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)),
95143a6a7e7SGarlic Tseng };
95243a6a7e7SGarlic Tseng 
95343a6a7e7SGarlic Tseng static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
95443a6a7e7SGarlic Tseng 	{"I12", NULL, "DL1"},
95543a6a7e7SGarlic Tseng 	{"I13", NULL, "DL1"},
95643a6a7e7SGarlic Tseng 	{"I35", NULL, "DLBT"},
95743a6a7e7SGarlic Tseng 
95843a6a7e7SGarlic Tseng 	{"I2S0 Playback", NULL, "O15"},
95943a6a7e7SGarlic Tseng 	{"I2S0 Playback", NULL, "O16"},
96043a6a7e7SGarlic Tseng 	{"I2S1 Playback", NULL, "O17"},
96143a6a7e7SGarlic Tseng 	{"I2S1 Playback", NULL, "O18"},
96243a6a7e7SGarlic Tseng 	{"I2S2 Playback", NULL, "O19"},
96343a6a7e7SGarlic Tseng 	{"I2S2 Playback", NULL, "O20"},
96443a6a7e7SGarlic Tseng 	{"I2S3 Playback", NULL, "O21"},
96543a6a7e7SGarlic Tseng 	{"I2S3 Playback", NULL, "O22"},
96643a6a7e7SGarlic Tseng 	{"BT Playback", NULL, "O31"},
96743a6a7e7SGarlic Tseng 
96843a6a7e7SGarlic Tseng 	{"UL1", NULL, "O00"},
96943a6a7e7SGarlic Tseng 	{"UL1", NULL, "O01"},
97043a6a7e7SGarlic Tseng 	{"UL2", NULL, "O02"},
97143a6a7e7SGarlic Tseng 	{"UL2", NULL, "O03"},
97243a6a7e7SGarlic Tseng 	{"ULBT", NULL, "O14"},
97343a6a7e7SGarlic Tseng 
97443a6a7e7SGarlic Tseng 	{"I00", NULL, "I2S0 Capture"},
97543a6a7e7SGarlic Tseng 	{"I01", NULL, "I2S0 Capture"},
97643a6a7e7SGarlic Tseng 	{"I02", NULL, "I2S1 Capture"},
97743a6a7e7SGarlic Tseng 	{"I03", NULL, "I2S1 Capture"},
97843a6a7e7SGarlic Tseng 	/* I02,03 link to UL2, also need to open I2S0 */
97943a6a7e7SGarlic Tseng 	{"I02", "I2S0 Switch", "I2S0 Capture"},
98043a6a7e7SGarlic Tseng 
98143a6a7e7SGarlic Tseng 	{"I26", NULL, "BT Capture"},
98243a6a7e7SGarlic Tseng 
983600b2fd4SRyder Lee 	{"I12I13", "Multich I2S0 Out Switch", "DLM"},
984600b2fd4SRyder Lee 	{"I14I15", "Multich I2S1 Out Switch", "DLM"},
985600b2fd4SRyder Lee 	{"I16I17", "Multich I2S2 Out Switch", "DLM"},
986600b2fd4SRyder Lee 	{"I18I19", "Multich I2S3 Out Switch", "DLM"},
98743a6a7e7SGarlic Tseng 
98843a6a7e7SGarlic Tseng 	{ "I12", NULL, "I12I13" },
98943a6a7e7SGarlic Tseng 	{ "I13", NULL, "I12I13" },
99043a6a7e7SGarlic Tseng 	{ "I14", NULL, "I14I15" },
99143a6a7e7SGarlic Tseng 	{ "I15", NULL, "I14I15" },
99243a6a7e7SGarlic Tseng 	{ "I16", NULL, "I16I17" },
99343a6a7e7SGarlic Tseng 	{ "I17", NULL, "I16I17" },
99443a6a7e7SGarlic Tseng 	{ "I18", NULL, "I18I19" },
99543a6a7e7SGarlic Tseng 	{ "I19", NULL, "I18I19" },
99643a6a7e7SGarlic Tseng 
99743a6a7e7SGarlic Tseng 	{ "O00", "I00 Switch", "I00" },
99843a6a7e7SGarlic Tseng 	{ "O01", "I01 Switch", "I01" },
99943a6a7e7SGarlic Tseng 	{ "O02", "I02 Switch", "I02" },
100043a6a7e7SGarlic Tseng 	{ "O03", "I03 Switch", "I03" },
100143a6a7e7SGarlic Tseng 	{ "O14", "I26 Switch", "I26" },
100243a6a7e7SGarlic Tseng 	{ "O15", "I12 Switch", "I12" },
100343a6a7e7SGarlic Tseng 	{ "O16", "I13 Switch", "I13" },
100443a6a7e7SGarlic Tseng 	{ "O17", "I14 Switch", "I14" },
100543a6a7e7SGarlic Tseng 	{ "O18", "I15 Switch", "I15" },
100643a6a7e7SGarlic Tseng 	{ "O19", "I16 Switch", "I16" },
100743a6a7e7SGarlic Tseng 	{ "O20", "I17 Switch", "I17" },
100843a6a7e7SGarlic Tseng 	{ "O21", "I18 Switch", "I18" },
100943a6a7e7SGarlic Tseng 	{ "O22", "I19 Switch", "I19" },
101043a6a7e7SGarlic Tseng 	{ "O31", "I35 Switch", "I35" },
101143a6a7e7SGarlic Tseng };
101243a6a7e7SGarlic Tseng 
101343a6a7e7SGarlic Tseng static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {
101443a6a7e7SGarlic Tseng 	.name = "mt2701-afe-pcm-dai",
101543a6a7e7SGarlic Tseng 	.dapm_widgets = mt2701_afe_pcm_widgets,
101643a6a7e7SGarlic Tseng 	.num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets),
101743a6a7e7SGarlic Tseng 	.dapm_routes = mt2701_afe_pcm_routes,
101843a6a7e7SGarlic Tseng 	.num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes),
101943a6a7e7SGarlic Tseng };
102043a6a7e7SGarlic Tseng 
102143a6a7e7SGarlic Tseng static const struct mtk_base_memif_data memif_data[MT2701_MEMIF_NUM] = {
102243a6a7e7SGarlic Tseng 	{
102343a6a7e7SGarlic Tseng 		.name = "DL1",
102443a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL1,
102543a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL1_BASE,
102643a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL1_CUR,
102743a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
102843a6a7e7SGarlic Tseng 		.fs_shift = 0,
102943a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
103043a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
103143a6a7e7SGarlic Tseng 		.mono_shift = 16,
103243a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
103343a6a7e7SGarlic Tseng 		.enable_shift = 1,
103443a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
103543a6a7e7SGarlic Tseng 		.hd_shift = 0,
103643a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
103743a6a7e7SGarlic Tseng 		.agent_disable_shift = 6,
103843a6a7e7SGarlic Tseng 		.msb_reg = -1,
103943a6a7e7SGarlic Tseng 		.msb_shift = -1,
104043a6a7e7SGarlic Tseng 	},
104143a6a7e7SGarlic Tseng 	{
104243a6a7e7SGarlic Tseng 		.name = "DL2",
104343a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL2,
104443a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL2_BASE,
104543a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL2_CUR,
104643a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
104743a6a7e7SGarlic Tseng 		.fs_shift = 5,
104843a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
104943a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
105043a6a7e7SGarlic Tseng 		.mono_shift = 17,
105143a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
105243a6a7e7SGarlic Tseng 		.enable_shift = 2,
105343a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
105443a6a7e7SGarlic Tseng 		.hd_shift = 2,
105543a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
105643a6a7e7SGarlic Tseng 		.agent_disable_shift = 7,
105743a6a7e7SGarlic Tseng 		.msb_reg = -1,
105843a6a7e7SGarlic Tseng 		.msb_shift = -1,
105943a6a7e7SGarlic Tseng 	},
106043a6a7e7SGarlic Tseng 	{
106143a6a7e7SGarlic Tseng 		.name = "DL3",
106243a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL3,
106343a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL3_BASE,
106443a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL3_CUR,
106543a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
106643a6a7e7SGarlic Tseng 		.fs_shift = 10,
106743a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
106843a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
106943a6a7e7SGarlic Tseng 		.mono_shift = 18,
107043a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
107143a6a7e7SGarlic Tseng 		.enable_shift = 3,
107243a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
107343a6a7e7SGarlic Tseng 		.hd_shift = 4,
107443a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
107543a6a7e7SGarlic Tseng 		.agent_disable_shift = 8,
107643a6a7e7SGarlic Tseng 		.msb_reg = -1,
107743a6a7e7SGarlic Tseng 		.msb_shift = -1,
107843a6a7e7SGarlic Tseng 	},
107943a6a7e7SGarlic Tseng 	{
108043a6a7e7SGarlic Tseng 		.name = "DL4",
108143a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL4,
108243a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL4_BASE,
108343a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL4_CUR,
108443a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
108543a6a7e7SGarlic Tseng 		.fs_shift = 15,
108643a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
108743a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
108843a6a7e7SGarlic Tseng 		.mono_shift = 19,
108943a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
109043a6a7e7SGarlic Tseng 		.enable_shift = 4,
109143a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
109243a6a7e7SGarlic Tseng 		.hd_shift = 6,
109343a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
109443a6a7e7SGarlic Tseng 		.agent_disable_shift = 9,
109543a6a7e7SGarlic Tseng 		.msb_reg = -1,
109643a6a7e7SGarlic Tseng 		.msb_shift = -1,
109743a6a7e7SGarlic Tseng 	},
109843a6a7e7SGarlic Tseng 	{
109943a6a7e7SGarlic Tseng 		.name = "DL5",
110043a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DL5,
110143a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DL5_BASE,
110243a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DL5_CUR,
110343a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
110443a6a7e7SGarlic Tseng 		.fs_shift = 20,
110543a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
110643a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
110743a6a7e7SGarlic Tseng 		.mono_shift = 20,
110843a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
110943a6a7e7SGarlic Tseng 		.enable_shift = 5,
111043a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
111143a6a7e7SGarlic Tseng 		.hd_shift = 8,
111243a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
111343a6a7e7SGarlic Tseng 		.agent_disable_shift = 10,
111443a6a7e7SGarlic Tseng 		.msb_reg = -1,
111543a6a7e7SGarlic Tseng 		.msb_shift = -1,
111643a6a7e7SGarlic Tseng 	},
111743a6a7e7SGarlic Tseng 	{
111843a6a7e7SGarlic Tseng 		.name = "DLM",
111943a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DLM,
112043a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DLMCH_BASE,
112143a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DLMCH_CUR,
112243a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON1,
112343a6a7e7SGarlic Tseng 		.fs_shift = 0,
112443a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
112543a6a7e7SGarlic Tseng 		.mono_reg = -1,
112643a6a7e7SGarlic Tseng 		.mono_shift = -1,
112743a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
112843a6a7e7SGarlic Tseng 		.enable_shift = 7,
112943a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_PBUF_SIZE,
113043a6a7e7SGarlic Tseng 		.hd_shift = 28,
113143a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
113243a6a7e7SGarlic Tseng 		.agent_disable_shift = 12,
113343a6a7e7SGarlic Tseng 		.msb_reg = -1,
113443a6a7e7SGarlic Tseng 		.msb_shift = -1,
113543a6a7e7SGarlic Tseng 	},
113643a6a7e7SGarlic Tseng 	{
113743a6a7e7SGarlic Tseng 		.name = "UL1",
113843a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL1,
113943a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_VUL_BASE,
114043a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_VUL_CUR,
114143a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
114243a6a7e7SGarlic Tseng 		.fs_shift = 0,
114343a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
114443a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
114543a6a7e7SGarlic Tseng 		.mono_shift = 0,
114643a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
114743a6a7e7SGarlic Tseng 		.enable_shift = 10,
114843a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON1,
114943a6a7e7SGarlic Tseng 		.hd_shift = 0,
115043a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
115143a6a7e7SGarlic Tseng 		.agent_disable_shift = 0,
115243a6a7e7SGarlic Tseng 		.msb_reg = -1,
115343a6a7e7SGarlic Tseng 		.msb_shift = -1,
115443a6a7e7SGarlic Tseng 	},
115543a6a7e7SGarlic Tseng 	{
115643a6a7e7SGarlic Tseng 		.name = "UL2",
115743a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL2,
115843a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL2_BASE,
115943a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL2_CUR,
116043a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
116143a6a7e7SGarlic Tseng 		.fs_shift = 5,
116243a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
116343a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
116443a6a7e7SGarlic Tseng 		.mono_shift = 2,
116543a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
116643a6a7e7SGarlic Tseng 		.enable_shift = 11,
116743a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON1,
116843a6a7e7SGarlic Tseng 		.hd_shift = 2,
116943a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
117043a6a7e7SGarlic Tseng 		.agent_disable_shift = 1,
117143a6a7e7SGarlic Tseng 		.msb_reg = -1,
117243a6a7e7SGarlic Tseng 		.msb_shift = -1,
117343a6a7e7SGarlic Tseng 	},
117443a6a7e7SGarlic Tseng 	{
117543a6a7e7SGarlic Tseng 		.name = "UL3",
117643a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL3,
117743a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL3_BASE,
117843a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL3_CUR,
117943a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
118043a6a7e7SGarlic Tseng 		.fs_shift = 10,
118143a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
118243a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
118343a6a7e7SGarlic Tseng 		.mono_shift = 4,
118443a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
118543a6a7e7SGarlic Tseng 		.enable_shift = 12,
118643a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
118743a6a7e7SGarlic Tseng 		.hd_shift = 0,
118843a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
118943a6a7e7SGarlic Tseng 		.agent_disable_shift = 2,
119043a6a7e7SGarlic Tseng 		.msb_reg = -1,
119143a6a7e7SGarlic Tseng 		.msb_shift = -1,
119243a6a7e7SGarlic Tseng 	},
119343a6a7e7SGarlic Tseng 	{
119443a6a7e7SGarlic Tseng 		.name = "UL4",
119543a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL4,
119643a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL4_BASE,
119743a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL4_CUR,
119843a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
119943a6a7e7SGarlic Tseng 		.fs_shift = 15,
120043a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
120143a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
120243a6a7e7SGarlic Tseng 		.mono_shift = 6,
120343a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
120443a6a7e7SGarlic Tseng 		.enable_shift = 13,
120543a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
120643a6a7e7SGarlic Tseng 		.hd_shift = 6,
120743a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
120843a6a7e7SGarlic Tseng 		.agent_disable_shift = 3,
120943a6a7e7SGarlic Tseng 		.msb_reg = -1,
121043a6a7e7SGarlic Tseng 		.msb_shift = -1,
121143a6a7e7SGarlic Tseng 	},
121243a6a7e7SGarlic Tseng 	{
121343a6a7e7SGarlic Tseng 		.name = "UL5",
121443a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_UL5,
121543a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_UL5_BASE,
121643a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_UL5_CUR,
121743a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
121843a6a7e7SGarlic Tseng 		.fs_shift = 20,
121943a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON4,
122043a6a7e7SGarlic Tseng 		.mono_shift = 8,
122143a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
122243a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
122343a6a7e7SGarlic Tseng 		.enable_shift = 14,
122443a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
122543a6a7e7SGarlic Tseng 		.hd_shift = 8,
122643a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
122743a6a7e7SGarlic Tseng 		.agent_disable_shift = 4,
122843a6a7e7SGarlic Tseng 		.msb_reg = -1,
122943a6a7e7SGarlic Tseng 		.msb_shift = -1,
123043a6a7e7SGarlic Tseng 	},
123143a6a7e7SGarlic Tseng 	{
123243a6a7e7SGarlic Tseng 		.name = "DLBT",
123343a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_DLBT,
123443a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_ARB1_BASE,
123543a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_ARB1_CUR,
123643a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON3,
123743a6a7e7SGarlic Tseng 		.fs_shift = 10,
123843a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1f,
123943a6a7e7SGarlic Tseng 		.mono_reg = AFE_DAC_CON3,
124043a6a7e7SGarlic Tseng 		.mono_shift = 22,
124143a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
124243a6a7e7SGarlic Tseng 		.enable_shift = 8,
124343a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON0,
124443a6a7e7SGarlic Tseng 		.hd_shift = 14,
124543a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
124643a6a7e7SGarlic Tseng 		.agent_disable_shift = 13,
124743a6a7e7SGarlic Tseng 		.msb_reg = -1,
124843a6a7e7SGarlic Tseng 		.msb_shift = -1,
124943a6a7e7SGarlic Tseng 	},
125043a6a7e7SGarlic Tseng 	{
125143a6a7e7SGarlic Tseng 		.name = "ULBT",
125243a6a7e7SGarlic Tseng 		.id = MT2701_MEMIF_ULBT,
125343a6a7e7SGarlic Tseng 		.reg_ofs_base = AFE_DAI_BASE,
125443a6a7e7SGarlic Tseng 		.reg_ofs_cur = AFE_DAI_CUR,
125543a6a7e7SGarlic Tseng 		.fs_reg = AFE_DAC_CON2,
125643a6a7e7SGarlic Tseng 		.fs_shift = 30,
125743a6a7e7SGarlic Tseng 		.fs_maskbit = 0x1,
125843a6a7e7SGarlic Tseng 		.mono_reg = -1,
125943a6a7e7SGarlic Tseng 		.mono_shift = -1,
126043a6a7e7SGarlic Tseng 		.enable_reg = AFE_DAC_CON0,
126143a6a7e7SGarlic Tseng 		.enable_shift = 17,
126243a6a7e7SGarlic Tseng 		.hd_reg = AFE_MEMIF_HD_CON1,
126343a6a7e7SGarlic Tseng 		.hd_shift = 20,
126443a6a7e7SGarlic Tseng 		.agent_disable_reg = AUDIO_TOP_CON5,
126543a6a7e7SGarlic Tseng 		.agent_disable_shift = 16,
126643a6a7e7SGarlic Tseng 		.msb_reg = -1,
126743a6a7e7SGarlic Tseng 		.msb_shift = -1,
126843a6a7e7SGarlic Tseng 	},
126943a6a7e7SGarlic Tseng };
127043a6a7e7SGarlic Tseng 
127143a6a7e7SGarlic Tseng static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {
127243a6a7e7SGarlic Tseng 	{
127343a6a7e7SGarlic Tseng 		.id = MT2701_IRQ_ASYS_IRQ1,
127443a6a7e7SGarlic Tseng 		.irq_cnt_reg = ASYS_IRQ1_CON,
127543a6a7e7SGarlic Tseng 		.irq_cnt_shift = 0,
127643a6a7e7SGarlic Tseng 		.irq_cnt_maskbit = 0xffffff,
127743a6a7e7SGarlic Tseng 		.irq_fs_reg = ASYS_IRQ1_CON,
127843a6a7e7SGarlic Tseng 		.irq_fs_shift = 24,
127943a6a7e7SGarlic Tseng 		.irq_fs_maskbit = 0x1f,
128043a6a7e7SGarlic Tseng 		.irq_en_reg = ASYS_IRQ1_CON,
128143a6a7e7SGarlic Tseng 		.irq_en_shift = 31,
128243a6a7e7SGarlic Tseng 		.irq_clr_reg = ASYS_IRQ_CLR,
128343a6a7e7SGarlic Tseng 		.irq_clr_shift = 0,
128443a6a7e7SGarlic Tseng 	},
128543a6a7e7SGarlic Tseng 	{
128643a6a7e7SGarlic Tseng 		.id = MT2701_IRQ_ASYS_IRQ2,
128743a6a7e7SGarlic Tseng 		.irq_cnt_reg = ASYS_IRQ2_CON,
128843a6a7e7SGarlic Tseng 		.irq_cnt_shift = 0,
128943a6a7e7SGarlic Tseng 		.irq_cnt_maskbit = 0xffffff,
129043a6a7e7SGarlic Tseng 		.irq_fs_reg = ASYS_IRQ2_CON,
129143a6a7e7SGarlic Tseng 		.irq_fs_shift = 24,
129243a6a7e7SGarlic Tseng 		.irq_fs_maskbit = 0x1f,
129343a6a7e7SGarlic Tseng 		.irq_en_reg = ASYS_IRQ2_CON,
129443a6a7e7SGarlic Tseng 		.irq_en_shift = 31,
129543a6a7e7SGarlic Tseng 		.irq_clr_reg = ASYS_IRQ_CLR,
129643a6a7e7SGarlic Tseng 		.irq_clr_shift = 1,
129743a6a7e7SGarlic Tseng 	},
129843a6a7e7SGarlic Tseng 	{
129943a6a7e7SGarlic Tseng 		.id = MT2701_IRQ_ASYS_IRQ3,
130043a6a7e7SGarlic Tseng 		.irq_cnt_reg = ASYS_IRQ3_CON,
130143a6a7e7SGarlic Tseng 		.irq_cnt_shift = 0,
130243a6a7e7SGarlic Tseng 		.irq_cnt_maskbit = 0xffffff,
130343a6a7e7SGarlic Tseng 		.irq_fs_reg = ASYS_IRQ3_CON,
130443a6a7e7SGarlic Tseng 		.irq_fs_shift = 24,
130543a6a7e7SGarlic Tseng 		.irq_fs_maskbit = 0x1f,
130643a6a7e7SGarlic Tseng 		.irq_en_reg = ASYS_IRQ3_CON,
130743a6a7e7SGarlic Tseng 		.irq_en_shift = 31,
130843a6a7e7SGarlic Tseng 		.irq_clr_reg = ASYS_IRQ_CLR,
130943a6a7e7SGarlic Tseng 		.irq_clr_shift = 2,
131043a6a7e7SGarlic Tseng 	}
131143a6a7e7SGarlic Tseng };
131243a6a7e7SGarlic Tseng 
131343a6a7e7SGarlic Tseng static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = {
131443a6a7e7SGarlic Tseng 	{
131543a6a7e7SGarlic Tseng 		{
131643a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SO1_CON,
131743a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 0,
131843a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
131943a6a7e7SGarlic Tseng 
132043a6a7e7SGarlic Tseng 		},
132143a6a7e7SGarlic Tseng 		{
132243a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SIN1_CON,
132343a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 0,
132443a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
132543a6a7e7SGarlic Tseng 
132643a6a7e7SGarlic Tseng 		},
132743a6a7e7SGarlic Tseng 	},
132843a6a7e7SGarlic Tseng 	{
132943a6a7e7SGarlic Tseng 		{
133043a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SO2_CON,
133143a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 5,
133243a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
133343a6a7e7SGarlic Tseng 
133443a6a7e7SGarlic Tseng 		},
133543a6a7e7SGarlic Tseng 		{
133643a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SIN2_CON,
133743a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 5,
133843a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
133943a6a7e7SGarlic Tseng 
134043a6a7e7SGarlic Tseng 		},
134143a6a7e7SGarlic Tseng 	},
134243a6a7e7SGarlic Tseng 	{
134343a6a7e7SGarlic Tseng 		{
134443a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SO3_CON,
134543a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 10,
134643a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
134743a6a7e7SGarlic Tseng 
134843a6a7e7SGarlic Tseng 		},
134943a6a7e7SGarlic Tseng 		{
135043a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SIN3_CON,
135143a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 10,
135243a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
135343a6a7e7SGarlic Tseng 
135443a6a7e7SGarlic Tseng 		},
135543a6a7e7SGarlic Tseng 	},
135643a6a7e7SGarlic Tseng 	{
135743a6a7e7SGarlic Tseng 		{
135843a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SO4_CON,
135943a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 15,
136043a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
136143a6a7e7SGarlic Tseng 
136243a6a7e7SGarlic Tseng 		},
136343a6a7e7SGarlic Tseng 		{
136443a6a7e7SGarlic Tseng 			.i2s_ctrl_reg = ASYS_I2SIN4_CON,
136543a6a7e7SGarlic Tseng 			.i2s_asrc_fs_shift = 15,
136643a6a7e7SGarlic Tseng 			.i2s_asrc_fs_mask = 0x1f,
136743a6a7e7SGarlic Tseng 
136843a6a7e7SGarlic Tseng 		},
136943a6a7e7SGarlic Tseng 	},
137043a6a7e7SGarlic Tseng };
137143a6a7e7SGarlic Tseng 
137243a6a7e7SGarlic Tseng static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
137343a6a7e7SGarlic Tseng {
137443a6a7e7SGarlic Tseng 	int id;
137543a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev;
137643a6a7e7SGarlic Tseng 	struct mtk_base_afe_memif *memif;
137743a6a7e7SGarlic Tseng 	struct mtk_base_afe_irq *irq;
137843a6a7e7SGarlic Tseng 	u32 status;
137943a6a7e7SGarlic Tseng 
138043a6a7e7SGarlic Tseng 	regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status);
138143a6a7e7SGarlic Tseng 	regmap_write(afe->regmap, ASYS_IRQ_CLR, status);
138243a6a7e7SGarlic Tseng 
138343a6a7e7SGarlic Tseng 	for (id = 0; id < MT2701_MEMIF_NUM; ++id) {
138443a6a7e7SGarlic Tseng 		memif = &afe->memif[id];
138543a6a7e7SGarlic Tseng 		if (memif->irq_usage < 0)
138643a6a7e7SGarlic Tseng 			continue;
138743a6a7e7SGarlic Tseng 		irq = &afe->irqs[memif->irq_usage];
138843a6a7e7SGarlic Tseng 		if (status & 1 << (irq->irq_data->irq_clr_shift))
138943a6a7e7SGarlic Tseng 			snd_pcm_period_elapsed(memif->substream);
139043a6a7e7SGarlic Tseng 	}
139143a6a7e7SGarlic Tseng 	return IRQ_HANDLED;
139243a6a7e7SGarlic Tseng }
139343a6a7e7SGarlic Tseng 
139443a6a7e7SGarlic Tseng static int mt2701_afe_runtime_suspend(struct device *dev)
139543a6a7e7SGarlic Tseng {
139643a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev_get_drvdata(dev);
139743a6a7e7SGarlic Tseng 
1398d8d99d8eSRyder Lee 	return mt2701_afe_disable_clock(afe);
139943a6a7e7SGarlic Tseng }
140043a6a7e7SGarlic Tseng 
140143a6a7e7SGarlic Tseng static int mt2701_afe_runtime_resume(struct device *dev)
140243a6a7e7SGarlic Tseng {
140343a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe = dev_get_drvdata(dev);
140443a6a7e7SGarlic Tseng 
140543a6a7e7SGarlic Tseng 	return mt2701_afe_enable_clock(afe);
140643a6a7e7SGarlic Tseng }
140743a6a7e7SGarlic Tseng 
140843a6a7e7SGarlic Tseng static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
140943a6a7e7SGarlic Tseng {
1410dfa3cbb8SRyder Lee 	struct snd_soc_component *component;
141143a6a7e7SGarlic Tseng 	struct mtk_base_afe *afe;
141243a6a7e7SGarlic Tseng 	struct mt2701_afe_private *afe_priv;
141343a6a7e7SGarlic Tseng 	struct device *dev;
1414f6c1626eSRyder Lee 	int i, irq_id, ret;
141543a6a7e7SGarlic Tseng 
141643a6a7e7SGarlic Tseng 	afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
141743a6a7e7SGarlic Tseng 	if (!afe)
141843a6a7e7SGarlic Tseng 		return -ENOMEM;
1419600b2fd4SRyder Lee 
1420b02c5cc7SDan Carpenter 	afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
1421b02c5cc7SDan Carpenter 					  GFP_KERNEL);
1422b02c5cc7SDan Carpenter 	if (!afe->platform_priv)
1423b02c5cc7SDan Carpenter 		return -ENOMEM;
142443a6a7e7SGarlic Tseng 
1425600b2fd4SRyder Lee 	afe_priv = afe->platform_priv;
142643a6a7e7SGarlic Tseng 	afe->dev = &pdev->dev;
142743a6a7e7SGarlic Tseng 	dev = afe->dev;
142843a6a7e7SGarlic Tseng 
1429f6c1626eSRyder Lee 	irq_id = platform_get_irq_byname(pdev, "asys");
1430f6c1626eSRyder Lee 	if (irq_id < 0) {
1431f6c1626eSRyder Lee 		dev_err(dev, "unable to get ASYS IRQ\n");
1432f6c1626eSRyder Lee 		return irq_id;
143343a6a7e7SGarlic Tseng 	}
1434f6c1626eSRyder Lee 
143543a6a7e7SGarlic Tseng 	ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
143643a6a7e7SGarlic Tseng 			       IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
143743a6a7e7SGarlic Tseng 	if (ret) {
143843a6a7e7SGarlic Tseng 		dev_err(dev, "could not request_irq for asys-isr\n");
143943a6a7e7SGarlic Tseng 		return ret;
144043a6a7e7SGarlic Tseng 	}
144143a6a7e7SGarlic Tseng 
1442dfa3cbb8SRyder Lee 	afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
1443*3e8052d9SWei Yongjun 	if (IS_ERR(afe->regmap)) {
1444dfa3cbb8SRyder Lee 		dev_err(dev, "could not get regmap from parent\n");
1445*3e8052d9SWei Yongjun 		return PTR_ERR(afe->regmap);
1446dfa3cbb8SRyder Lee 	}
144743a6a7e7SGarlic Tseng 
144843a6a7e7SGarlic Tseng 	mutex_init(&afe->irq_alloc_lock);
144943a6a7e7SGarlic Tseng 
145043a6a7e7SGarlic Tseng 	/* memif initialize */
145143a6a7e7SGarlic Tseng 	afe->memif_size = MT2701_MEMIF_NUM;
145243a6a7e7SGarlic Tseng 	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
145343a6a7e7SGarlic Tseng 				  GFP_KERNEL);
145443a6a7e7SGarlic Tseng 	if (!afe->memif)
145543a6a7e7SGarlic Tseng 		return -ENOMEM;
145643a6a7e7SGarlic Tseng 
145743a6a7e7SGarlic Tseng 	for (i = 0; i < afe->memif_size; i++) {
145843a6a7e7SGarlic Tseng 		afe->memif[i].data = &memif_data[i];
145943a6a7e7SGarlic Tseng 		afe->memif[i].irq_usage = -1;
146043a6a7e7SGarlic Tseng 	}
146143a6a7e7SGarlic Tseng 
146243a6a7e7SGarlic Tseng 	/* irq initialize */
146343a6a7e7SGarlic Tseng 	afe->irqs_size = MT2701_IRQ_ASYS_END;
146443a6a7e7SGarlic Tseng 	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
146543a6a7e7SGarlic Tseng 				 GFP_KERNEL);
146643a6a7e7SGarlic Tseng 	if (!afe->irqs)
146743a6a7e7SGarlic Tseng 		return -ENOMEM;
146843a6a7e7SGarlic Tseng 
146943a6a7e7SGarlic Tseng 	for (i = 0; i < afe->irqs_size; i++)
147043a6a7e7SGarlic Tseng 		afe->irqs[i].irq_data = &irq_data[i];
147143a6a7e7SGarlic Tseng 
147243a6a7e7SGarlic Tseng 	/* I2S initialize */
147343a6a7e7SGarlic Tseng 	for (i = 0; i < MT2701_I2S_NUM; i++) {
147443a6a7e7SGarlic Tseng 		afe_priv->i2s_path[i].i2s_data[I2S_OUT]
147543a6a7e7SGarlic Tseng 			= &mt2701_i2s_data[i][I2S_OUT];
147643a6a7e7SGarlic Tseng 		afe_priv->i2s_path[i].i2s_data[I2S_IN]
147743a6a7e7SGarlic Tseng 			= &mt2701_i2s_data[i][I2S_IN];
147843a6a7e7SGarlic Tseng 	}
147943a6a7e7SGarlic Tseng 
1480dfa3cbb8SRyder Lee 	component = kzalloc(sizeof(*component), GFP_KERNEL);
1481dfa3cbb8SRyder Lee 	if (!component)
1482dfa3cbb8SRyder Lee 		return -ENOMEM;
1483dfa3cbb8SRyder Lee 
1484dfa3cbb8SRyder Lee 	component->regmap = afe->regmap;
1485dfa3cbb8SRyder Lee 
148643a6a7e7SGarlic Tseng 	afe->mtk_afe_hardware = &mt2701_afe_hardware;
148743a6a7e7SGarlic Tseng 	afe->memif_fs = mt2701_memif_fs;
148843a6a7e7SGarlic Tseng 	afe->irq_fs = mt2701_irq_fs;
148943a6a7e7SGarlic Tseng 	afe->reg_back_up_list = mt2701_afe_backup_list;
149043a6a7e7SGarlic Tseng 	afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list);
149143a6a7e7SGarlic Tseng 	afe->runtime_resume = mt2701_afe_runtime_resume;
149243a6a7e7SGarlic Tseng 	afe->runtime_suspend = mt2701_afe_runtime_suspend;
149343a6a7e7SGarlic Tseng 
149443a6a7e7SGarlic Tseng 	/* initial audio related clock */
149543a6a7e7SGarlic Tseng 	ret = mt2701_init_clock(afe);
149643a6a7e7SGarlic Tseng 	if (ret) {
149743a6a7e7SGarlic Tseng 		dev_err(dev, "init clock error\n");
1498dfa3cbb8SRyder Lee 		goto err_init_clock;
149943a6a7e7SGarlic Tseng 	}
150043a6a7e7SGarlic Tseng 
150143a6a7e7SGarlic Tseng 	platform_set_drvdata(pdev, afe);
150243a6a7e7SGarlic Tseng 
1503dd6bb9b1SRyder Lee 	pm_runtime_enable(dev);
1504dd6bb9b1SRyder Lee 	if (!pm_runtime_enabled(dev)) {
1505dd6bb9b1SRyder Lee 		ret = mt2701_afe_runtime_resume(dev);
1506dd6bb9b1SRyder Lee 		if (ret)
1507dd6bb9b1SRyder Lee 			goto err_pm_disable;
1508dd6bb9b1SRyder Lee 	}
1509dd6bb9b1SRyder Lee 	pm_runtime_get_sync(dev);
1510dd6bb9b1SRyder Lee 
1511dd6bb9b1SRyder Lee 	ret = snd_soc_register_platform(dev, &mtk_afe_pcm_platform);
151243a6a7e7SGarlic Tseng 	if (ret) {
151343a6a7e7SGarlic Tseng 		dev_warn(dev, "err_platform\n");
151443a6a7e7SGarlic Tseng 		goto err_platform;
151543a6a7e7SGarlic Tseng 	}
151643a6a7e7SGarlic Tseng 
1517dfa3cbb8SRyder Lee 	ret = snd_soc_add_component(dev, component,
151843a6a7e7SGarlic Tseng 				    &mt2701_afe_pcm_dai_component,
151943a6a7e7SGarlic Tseng 				    mt2701_afe_pcm_dais,
152043a6a7e7SGarlic Tseng 				    ARRAY_SIZE(mt2701_afe_pcm_dais));
152143a6a7e7SGarlic Tseng 	if (ret) {
152243a6a7e7SGarlic Tseng 		dev_warn(dev, "err_dai_component\n");
152343a6a7e7SGarlic Tseng 		goto err_dai_component;
152443a6a7e7SGarlic Tseng 	}
152543a6a7e7SGarlic Tseng 
152643a6a7e7SGarlic Tseng 	return 0;
152743a6a7e7SGarlic Tseng 
152843a6a7e7SGarlic Tseng err_dai_component:
1529dd6bb9b1SRyder Lee 	snd_soc_unregister_platform(dev);
153043a6a7e7SGarlic Tseng err_platform:
1531dd6bb9b1SRyder Lee 	pm_runtime_put_sync(dev);
153243a6a7e7SGarlic Tseng err_pm_disable:
1533dd6bb9b1SRyder Lee 	pm_runtime_disable(dev);
1534dfa3cbb8SRyder Lee err_init_clock:
1535dfa3cbb8SRyder Lee 	kfree(component);
153643a6a7e7SGarlic Tseng 
153743a6a7e7SGarlic Tseng 	return ret;
153843a6a7e7SGarlic Tseng }
153943a6a7e7SGarlic Tseng 
154043a6a7e7SGarlic Tseng static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
154143a6a7e7SGarlic Tseng {
1542dd6bb9b1SRyder Lee 	pm_runtime_put_sync(&pdev->dev);
154343a6a7e7SGarlic Tseng 	pm_runtime_disable(&pdev->dev);
154443a6a7e7SGarlic Tseng 	if (!pm_runtime_status_suspended(&pdev->dev))
154543a6a7e7SGarlic Tseng 		mt2701_afe_runtime_suspend(&pdev->dev);
154643a6a7e7SGarlic Tseng 
154743a6a7e7SGarlic Tseng 	snd_soc_unregister_component(&pdev->dev);
154843a6a7e7SGarlic Tseng 	snd_soc_unregister_platform(&pdev->dev);
1549dd6bb9b1SRyder Lee 
155043a6a7e7SGarlic Tseng 	return 0;
155143a6a7e7SGarlic Tseng }
155243a6a7e7SGarlic Tseng 
155343a6a7e7SGarlic Tseng static const struct of_device_id mt2701_afe_pcm_dt_match[] = {
155443a6a7e7SGarlic Tseng 	{ .compatible = "mediatek,mt2701-audio", },
155543a6a7e7SGarlic Tseng 	{},
155643a6a7e7SGarlic Tseng };
155743a6a7e7SGarlic Tseng MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match);
155843a6a7e7SGarlic Tseng 
155943a6a7e7SGarlic Tseng static const struct dev_pm_ops mt2701_afe_pm_ops = {
156043a6a7e7SGarlic Tseng 	SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend,
156143a6a7e7SGarlic Tseng 			   mt2701_afe_runtime_resume, NULL)
156243a6a7e7SGarlic Tseng };
156343a6a7e7SGarlic Tseng 
156443a6a7e7SGarlic Tseng static struct platform_driver mt2701_afe_pcm_driver = {
156543a6a7e7SGarlic Tseng 	.driver = {
156643a6a7e7SGarlic Tseng 		   .name = "mt2701-audio",
156743a6a7e7SGarlic Tseng 		   .of_match_table = mt2701_afe_pcm_dt_match,
156843a6a7e7SGarlic Tseng #ifdef CONFIG_PM
156943a6a7e7SGarlic Tseng 		   .pm = &mt2701_afe_pm_ops,
157043a6a7e7SGarlic Tseng #endif
157143a6a7e7SGarlic Tseng 	},
157243a6a7e7SGarlic Tseng 	.probe = mt2701_afe_pcm_dev_probe,
157343a6a7e7SGarlic Tseng 	.remove = mt2701_afe_pcm_dev_remove,
157443a6a7e7SGarlic Tseng };
157543a6a7e7SGarlic Tseng 
157643a6a7e7SGarlic Tseng module_platform_driver(mt2701_afe_pcm_driver);
157743a6a7e7SGarlic Tseng 
157843a6a7e7SGarlic Tseng MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701");
157943a6a7e7SGarlic Tseng MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
158043a6a7e7SGarlic Tseng MODULE_LICENSE("GPL v2");
1581