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/pm_runtime.h>
1643a6a7e7SGarlic Tseng
1743a6a7e7SGarlic Tseng #include "mt2701-afe-common.h"
1843a6a7e7SGarlic Tseng #include "mt2701-afe-clock-ctrl.h"
1943a6a7e7SGarlic Tseng #include "../common/mtk-afe-platform-driver.h"
2043a6a7e7SGarlic Tseng #include "../common/mtk-afe-fe-dai.h"
2143a6a7e7SGarlic Tseng
2243a6a7e7SGarlic Tseng static const struct snd_pcm_hardware mt2701_afe_hardware = {
2343a6a7e7SGarlic Tseng .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
2443a6a7e7SGarlic Tseng | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
2543a6a7e7SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
2643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE,
2743a6a7e7SGarlic Tseng .period_bytes_min = 1024,
2843a6a7e7SGarlic Tseng .period_bytes_max = 1024 * 256,
2943a6a7e7SGarlic Tseng .periods_min = 4,
3043a6a7e7SGarlic Tseng .periods_max = 1024,
31bfdc56e5SRyder Lee .buffer_bytes_max = 1024 * 1024,
3243a6a7e7SGarlic Tseng .fifo_size = 0,
3343a6a7e7SGarlic Tseng };
3443a6a7e7SGarlic Tseng
3543a6a7e7SGarlic Tseng struct mt2701_afe_rate {
3643a6a7e7SGarlic Tseng unsigned int rate;
3743a6a7e7SGarlic Tseng unsigned int regvalue;
3843a6a7e7SGarlic Tseng };
3943a6a7e7SGarlic Tseng
4043a6a7e7SGarlic Tseng static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
4143a6a7e7SGarlic Tseng { .rate = 8000, .regvalue = 0 },
4243a6a7e7SGarlic Tseng { .rate = 12000, .regvalue = 1 },
4343a6a7e7SGarlic Tseng { .rate = 16000, .regvalue = 2 },
4443a6a7e7SGarlic Tseng { .rate = 24000, .regvalue = 3 },
4543a6a7e7SGarlic Tseng { .rate = 32000, .regvalue = 4 },
4643a6a7e7SGarlic Tseng { .rate = 48000, .regvalue = 5 },
4743a6a7e7SGarlic Tseng { .rate = 96000, .regvalue = 6 },
4843a6a7e7SGarlic Tseng { .rate = 192000, .regvalue = 7 },
4943a6a7e7SGarlic Tseng { .rate = 384000, .regvalue = 8 },
5043a6a7e7SGarlic Tseng { .rate = 7350, .regvalue = 16 },
5143a6a7e7SGarlic Tseng { .rate = 11025, .regvalue = 17 },
5243a6a7e7SGarlic Tseng { .rate = 14700, .regvalue = 18 },
5343a6a7e7SGarlic Tseng { .rate = 22050, .regvalue = 19 },
5443a6a7e7SGarlic Tseng { .rate = 29400, .regvalue = 20 },
5543a6a7e7SGarlic Tseng { .rate = 44100, .regvalue = 21 },
5643a6a7e7SGarlic Tseng { .rate = 88200, .regvalue = 22 },
5743a6a7e7SGarlic Tseng { .rate = 176400, .regvalue = 23 },
5843a6a7e7SGarlic Tseng { .rate = 352800, .regvalue = 24 },
5943a6a7e7SGarlic Tseng };
6043a6a7e7SGarlic Tseng
6197aad5ceSYueHaibing static const unsigned int mt2701_afe_backup_list[] = {
6297aad5ceSYueHaibing AUDIO_TOP_CON0,
6397aad5ceSYueHaibing AUDIO_TOP_CON4,
6497aad5ceSYueHaibing AUDIO_TOP_CON5,
6597aad5ceSYueHaibing ASYS_TOP_CON,
6697aad5ceSYueHaibing AFE_CONN0,
6797aad5ceSYueHaibing AFE_CONN1,
6897aad5ceSYueHaibing AFE_CONN2,
6997aad5ceSYueHaibing AFE_CONN3,
7097aad5ceSYueHaibing AFE_CONN15,
7197aad5ceSYueHaibing AFE_CONN16,
7297aad5ceSYueHaibing AFE_CONN17,
7397aad5ceSYueHaibing AFE_CONN18,
7497aad5ceSYueHaibing AFE_CONN19,
7597aad5ceSYueHaibing AFE_CONN20,
7697aad5ceSYueHaibing AFE_CONN21,
7797aad5ceSYueHaibing AFE_CONN22,
7897aad5ceSYueHaibing AFE_DAC_CON0,
7997aad5ceSYueHaibing AFE_MEMIF_PBUF_SIZE,
8097aad5ceSYueHaibing };
8197aad5ceSYueHaibing
mt2701_dai_num_to_i2s(struct mtk_base_afe * afe,int num)8225d01dc6SWei Yongjun static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
8343a6a7e7SGarlic Tseng {
84bfdc56e5SRyder Lee struct mt2701_afe_private *afe_priv = afe->platform_priv;
8543a6a7e7SGarlic Tseng int val = num - MT2701_IO_I2S;
8643a6a7e7SGarlic Tseng
87bfdc56e5SRyder Lee if (val < 0 || val >= afe_priv->soc->i2s_num) {
8843a6a7e7SGarlic Tseng dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
8943a6a7e7SGarlic Tseng __func__, num, val);
9043a6a7e7SGarlic Tseng return -EINVAL;
9143a6a7e7SGarlic Tseng }
9243a6a7e7SGarlic Tseng return val;
9343a6a7e7SGarlic Tseng }
9443a6a7e7SGarlic Tseng
mt2701_afe_i2s_fs(unsigned int sample_rate)9543a6a7e7SGarlic Tseng static int mt2701_afe_i2s_fs(unsigned int sample_rate)
9643a6a7e7SGarlic Tseng {
9743a6a7e7SGarlic Tseng int i;
9843a6a7e7SGarlic Tseng
9943a6a7e7SGarlic Tseng for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)
10043a6a7e7SGarlic Tseng if (mt2701_afe_i2s_rates[i].rate == sample_rate)
10143a6a7e7SGarlic Tseng return mt2701_afe_i2s_rates[i].regvalue;
10243a6a7e7SGarlic Tseng
10343a6a7e7SGarlic Tseng return -EINVAL;
10443a6a7e7SGarlic Tseng }
10543a6a7e7SGarlic Tseng
mt2701_afe_i2s_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)10643a6a7e7SGarlic Tseng static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
10743a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
10843a6a7e7SGarlic Tseng {
109e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
110bfdc56e5SRyder Lee struct mt2701_afe_private *afe_priv = afe->platform_priv;
11143a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
112bfdc56e5SRyder Lee bool mode = afe_priv->soc->has_one_heart_mode;
11343a6a7e7SGarlic Tseng
11443a6a7e7SGarlic Tseng if (i2s_num < 0)
11543a6a7e7SGarlic Tseng return i2s_num;
11643a6a7e7SGarlic Tseng
117bfdc56e5SRyder Lee return mt2701_afe_enable_mclk(afe, mode ? 1 : i2s_num);
11843a6a7e7SGarlic Tseng }
11943a6a7e7SGarlic Tseng
mt2701_afe_i2s_path_disable(struct mtk_base_afe * afe,struct mt2701_i2s_path * i2s_path,int stream_dir)120cf870273SRyder Lee static int mt2701_afe_i2s_path_disable(struct mtk_base_afe *afe,
121cf870273SRyder Lee struct mt2701_i2s_path *i2s_path,
122cf870273SRyder Lee int stream_dir)
12343a6a7e7SGarlic Tseng {
124cf870273SRyder Lee const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];
12543a6a7e7SGarlic Tseng
126cf870273SRyder Lee if (--i2s_path->on[stream_dir] < 0)
12743a6a7e7SGarlic Tseng i2s_path->on[stream_dir] = 0;
128cf870273SRyder Lee
12943a6a7e7SGarlic Tseng if (i2s_path->on[stream_dir])
13043a6a7e7SGarlic Tseng return 0;
13143a6a7e7SGarlic Tseng
13243a6a7e7SGarlic Tseng /* disable i2s */
13343a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
13443a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_EN, 0);
135d8d99d8eSRyder Lee
136cf870273SRyder Lee mt2701_afe_disable_i2s(afe, i2s_path, stream_dir);
137d8d99d8eSRyder Lee
13843a6a7e7SGarlic Tseng return 0;
13943a6a7e7SGarlic Tseng }
14043a6a7e7SGarlic Tseng
mt2701_afe_i2s_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)14143a6a7e7SGarlic Tseng static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,
14243a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
14343a6a7e7SGarlic Tseng {
144e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
14543a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv;
14643a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
14743a6a7e7SGarlic Tseng struct mt2701_i2s_path *i2s_path;
148bfdc56e5SRyder Lee bool mode = afe_priv->soc->has_one_heart_mode;
14943a6a7e7SGarlic Tseng
15043a6a7e7SGarlic Tseng if (i2s_num < 0)
15143a6a7e7SGarlic Tseng return;
15243a6a7e7SGarlic Tseng
15343a6a7e7SGarlic Tseng i2s_path = &afe_priv->i2s_path[i2s_num];
15443a6a7e7SGarlic Tseng
15543a6a7e7SGarlic Tseng if (i2s_path->occupied[substream->stream])
15643a6a7e7SGarlic Tseng i2s_path->occupied[substream->stream] = 0;
15743a6a7e7SGarlic Tseng else
158cf870273SRyder Lee goto exit;
15943a6a7e7SGarlic Tseng
160cf870273SRyder Lee mt2701_afe_i2s_path_disable(afe, i2s_path, substream->stream);
16143a6a7e7SGarlic Tseng
16243a6a7e7SGarlic Tseng /* need to disable i2s-out path when disable i2s-in */
16343a6a7e7SGarlic Tseng if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
164cf870273SRyder Lee mt2701_afe_i2s_path_disable(afe, i2s_path, !substream->stream);
16543a6a7e7SGarlic Tseng
166cf870273SRyder Lee exit:
16743a6a7e7SGarlic Tseng /* disable mclk */
168bfdc56e5SRyder Lee mt2701_afe_disable_mclk(afe, mode ? 1 : i2s_num);
16943a6a7e7SGarlic Tseng }
17043a6a7e7SGarlic Tseng
mt2701_i2s_path_enable(struct mtk_base_afe * afe,struct mt2701_i2s_path * i2s_path,int stream_dir,int rate)171cf870273SRyder Lee static int mt2701_i2s_path_enable(struct mtk_base_afe *afe,
172cf870273SRyder Lee struct mt2701_i2s_path *i2s_path,
173cf870273SRyder Lee int stream_dir, int rate)
17443a6a7e7SGarlic Tseng {
175cf870273SRyder Lee const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];
176bfdc56e5SRyder Lee struct mt2701_afe_private *afe_priv = afe->platform_priv;
17743a6a7e7SGarlic Tseng int reg, fs, w_len = 1; /* now we support bck 64bits only */
178e4b31b81SRyder Lee unsigned int mask, val;
17943a6a7e7SGarlic Tseng
18043a6a7e7SGarlic Tseng /* no need to enable if already done */
181cf870273SRyder Lee if (++i2s_path->on[stream_dir] != 1)
18243a6a7e7SGarlic Tseng return 0;
18343a6a7e7SGarlic Tseng
184cf870273SRyder Lee fs = mt2701_afe_i2s_fs(rate);
18543a6a7e7SGarlic Tseng
18643a6a7e7SGarlic Tseng mask = ASYS_I2S_CON_FS |
18743a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */
18843a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_MODE |
18943a6a7e7SGarlic Tseng ASYS_I2S_CON_WIDE_MODE;
19043a6a7e7SGarlic Tseng
19143a6a7e7SGarlic Tseng val = ASYS_I2S_CON_FS_SET(fs) |
19243a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_MODE |
19343a6a7e7SGarlic Tseng ASYS_I2S_CON_WIDE_MODE_SET(w_len);
19443a6a7e7SGarlic Tseng
19543a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) {
19643a6a7e7SGarlic Tseng mask |= ASYS_I2S_IN_PHASE_FIX;
19743a6a7e7SGarlic Tseng val |= ASYS_I2S_IN_PHASE_FIX;
198cf870273SRyder Lee reg = ASMI_TIMING_CON1;
199cf870273SRyder Lee } else {
200bfdc56e5SRyder Lee if (afe_priv->soc->has_one_heart_mode) {
201bfdc56e5SRyder Lee mask |= ASYS_I2S_CON_ONE_HEART_MODE;
202bfdc56e5SRyder Lee val |= ASYS_I2S_CON_ONE_HEART_MODE;
203bfdc56e5SRyder Lee }
204cf870273SRyder Lee reg = ASMO_TIMING_CON1;
20543a6a7e7SGarlic Tseng }
20643a6a7e7SGarlic Tseng
20743a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val);
20843a6a7e7SGarlic Tseng
20943a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, reg,
21043a6a7e7SGarlic Tseng i2s_data->i2s_asrc_fs_mask
21143a6a7e7SGarlic Tseng << i2s_data->i2s_asrc_fs_shift,
21243a6a7e7SGarlic Tseng fs << i2s_data->i2s_asrc_fs_shift);
21343a6a7e7SGarlic Tseng
21443a6a7e7SGarlic Tseng /* enable i2s */
215cf870273SRyder Lee mt2701_afe_enable_i2s(afe, i2s_path, stream_dir);
21643a6a7e7SGarlic Tseng
21743a6a7e7SGarlic Tseng /* reset i2s hw status before enable */
21843a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
21943a6a7e7SGarlic Tseng ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET);
22043a6a7e7SGarlic Tseng udelay(1);
22143a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
22243a6a7e7SGarlic Tseng ASYS_I2S_CON_RESET, 0);
22343a6a7e7SGarlic Tseng udelay(1);
22443a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,
22543a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN);
22643a6a7e7SGarlic Tseng return 0;
22743a6a7e7SGarlic Tseng }
22843a6a7e7SGarlic Tseng
mt2701_afe_i2s_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)22943a6a7e7SGarlic Tseng static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,
23043a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
23143a6a7e7SGarlic Tseng {
232e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
23343a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv;
234cf870273SRyder Lee int ret, i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
23543a6a7e7SGarlic Tseng struct mt2701_i2s_path *i2s_path;
236bfdc56e5SRyder Lee bool mode = afe_priv->soc->has_one_heart_mode;
23743a6a7e7SGarlic Tseng
23843a6a7e7SGarlic Tseng if (i2s_num < 0)
23943a6a7e7SGarlic Tseng return i2s_num;
24043a6a7e7SGarlic Tseng
24143a6a7e7SGarlic Tseng i2s_path = &afe_priv->i2s_path[i2s_num];
24243a6a7e7SGarlic Tseng
24343a6a7e7SGarlic Tseng if (i2s_path->occupied[substream->stream])
24443a6a7e7SGarlic Tseng return -EBUSY;
245cf870273SRyder Lee
246bfdc56e5SRyder Lee ret = mt2701_mclk_configuration(afe, mode ? 1 : i2s_num);
247cf870273SRyder Lee if (ret)
248cf870273SRyder Lee return ret;
249cf870273SRyder Lee
25043a6a7e7SGarlic Tseng i2s_path->occupied[substream->stream] = 1;
25143a6a7e7SGarlic Tseng
25243a6a7e7SGarlic Tseng /* need to enable i2s-out path when enable i2s-in */
253cf870273SRyder Lee if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
254cf870273SRyder Lee mt2701_i2s_path_enable(afe, i2s_path, !substream->stream,
255cf870273SRyder Lee substream->runtime->rate);
256cf870273SRyder Lee
257cf870273SRyder Lee mt2701_i2s_path_enable(afe, i2s_path, substream->stream,
258cf870273SRyder Lee substream->runtime->rate);
25943a6a7e7SGarlic Tseng
26043a6a7e7SGarlic Tseng return 0;
26143a6a7e7SGarlic Tseng }
26243a6a7e7SGarlic Tseng
mt2701_afe_i2s_set_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)26343a6a7e7SGarlic Tseng static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
26443a6a7e7SGarlic Tseng unsigned int freq, int dir)
26543a6a7e7SGarlic Tseng {
266e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
26743a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv;
26843a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
269bfdc56e5SRyder Lee bool mode = afe_priv->soc->has_one_heart_mode;
27043a6a7e7SGarlic Tseng
27143a6a7e7SGarlic Tseng if (i2s_num < 0)
27243a6a7e7SGarlic Tseng return i2s_num;
27343a6a7e7SGarlic Tseng
27443a6a7e7SGarlic Tseng /* mclk */
27543a6a7e7SGarlic Tseng if (dir == SND_SOC_CLOCK_IN) {
276bfdc56e5SRyder Lee dev_warn(dai->dev, "The SoCs doesn't support mclk input\n");
27743a6a7e7SGarlic Tseng return -EINVAL;
27843a6a7e7SGarlic Tseng }
279e4b31b81SRyder Lee
280bfdc56e5SRyder Lee afe_priv->i2s_path[mode ? 1 : i2s_num].mclk_rate = freq;
281e4b31b81SRyder Lee
28243a6a7e7SGarlic Tseng return 0;
28343a6a7e7SGarlic Tseng }
28443a6a7e7SGarlic Tseng
mt2701_btmrg_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)2854bdc8d45SGarlic Tseng static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
2864bdc8d45SGarlic Tseng struct snd_soc_dai *dai)
2874bdc8d45SGarlic Tseng {
288e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
2894bdc8d45SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv;
290d8d99d8eSRyder Lee int ret;
2914bdc8d45SGarlic Tseng
292d8d99d8eSRyder Lee ret = mt2701_enable_btmrg_clk(afe);
293d8d99d8eSRyder Lee if (ret)
294d8d99d8eSRyder Lee return ret;
2954bdc8d45SGarlic Tseng
2964bdc8d45SGarlic Tseng afe_priv->mrg_enable[substream->stream] = 1;
297e4b31b81SRyder Lee
2984bdc8d45SGarlic Tseng return 0;
2994bdc8d45SGarlic Tseng }
3004bdc8d45SGarlic Tseng
mt2701_btmrg_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)3014bdc8d45SGarlic Tseng static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
3024bdc8d45SGarlic Tseng struct snd_pcm_hw_params *params,
3034bdc8d45SGarlic Tseng struct snd_soc_dai *dai)
3044bdc8d45SGarlic Tseng {
305e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
3064bdc8d45SGarlic Tseng int stream_fs;
3074bdc8d45SGarlic Tseng u32 val, msk;
3084bdc8d45SGarlic Tseng
3094bdc8d45SGarlic Tseng stream_fs = params_rate(params);
3104bdc8d45SGarlic Tseng
311e4b31b81SRyder Lee if (stream_fs != 8000 && stream_fs != 16000) {
312e4b31b81SRyder Lee dev_err(afe->dev, "unsupported rate %d\n", stream_fs);
3134bdc8d45SGarlic Tseng return -EINVAL;
3144bdc8d45SGarlic Tseng }
3154bdc8d45SGarlic Tseng
3164bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3174bdc8d45SGarlic Tseng AFE_MRGIF_CON_I2S_MODE_MASK,
3184bdc8d45SGarlic Tseng AFE_MRGIF_CON_I2S_MODE_32K);
3194bdc8d45SGarlic Tseng
3204bdc8d45SGarlic Tseng val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY
3214bdc8d45SGarlic Tseng | AFE_DAIBT_CON0_MRG_USE;
3224bdc8d45SGarlic Tseng msk = val;
3234bdc8d45SGarlic Tseng
3244bdc8d45SGarlic Tseng if (stream_fs == 16000)
3254bdc8d45SGarlic Tseng val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
3264bdc8d45SGarlic Tseng
3274bdc8d45SGarlic Tseng msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
3284bdc8d45SGarlic Tseng
3294bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);
3304bdc8d45SGarlic Tseng
3314bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
3324bdc8d45SGarlic Tseng AFE_DAIBT_CON0_DAIBT_EN,
3334bdc8d45SGarlic Tseng AFE_DAIBT_CON0_DAIBT_EN);
3344bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3354bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_I2S_EN,
3364bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_I2S_EN);
3374bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3384bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_EN,
3394bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_EN);
3404bdc8d45SGarlic Tseng return 0;
3414bdc8d45SGarlic Tseng }
3424bdc8d45SGarlic Tseng
mt2701_btmrg_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)3434bdc8d45SGarlic Tseng static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
3444bdc8d45SGarlic Tseng struct snd_soc_dai *dai)
3454bdc8d45SGarlic Tseng {
346e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
3474bdc8d45SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv;
3484bdc8d45SGarlic Tseng
3494bdc8d45SGarlic Tseng /* if the other direction stream is not occupied */
3504bdc8d45SGarlic Tseng if (!afe_priv->mrg_enable[!substream->stream]) {
3514bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
3524bdc8d45SGarlic Tseng AFE_DAIBT_CON0_DAIBT_EN, 0);
3534bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3544bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_EN, 0);
3554bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
3564bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_I2S_EN, 0);
357d8d99d8eSRyder Lee mt2701_disable_btmrg_clk(afe);
3584bdc8d45SGarlic Tseng }
359e4b31b81SRyder Lee
3604bdc8d45SGarlic Tseng afe_priv->mrg_enable[substream->stream] = 0;
3614bdc8d45SGarlic Tseng }
3624bdc8d45SGarlic Tseng
mt2701_simple_fe_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)36343a6a7e7SGarlic Tseng static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
36443a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
36543a6a7e7SGarlic Tseng {
366e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
36743a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif_tmp;
368e4b31b81SRyder Lee int stream_dir = substream->stream;
36943a6a7e7SGarlic Tseng
37043a6a7e7SGarlic Tseng /* can't run single DL & DLM at the same time */
37143a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {
37243a6a7e7SGarlic Tseng memif_tmp = &afe->memif[MT2701_MEMIF_DLM];
37343a6a7e7SGarlic Tseng if (memif_tmp->substream) {
374e4b31b81SRyder Lee dev_warn(afe->dev, "memif is not available");
37543a6a7e7SGarlic Tseng return -EBUSY;
37643a6a7e7SGarlic Tseng }
37743a6a7e7SGarlic Tseng }
378e4b31b81SRyder Lee
37943a6a7e7SGarlic Tseng return mtk_afe_fe_startup(substream, dai);
38043a6a7e7SGarlic Tseng }
38143a6a7e7SGarlic Tseng
mt2701_simple_fe_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)38243a6a7e7SGarlic Tseng static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,
38343a6a7e7SGarlic Tseng struct snd_pcm_hw_params *params,
38443a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
38543a6a7e7SGarlic Tseng {
386e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
38743a6a7e7SGarlic Tseng int stream_dir = substream->stream;
38843a6a7e7SGarlic Tseng
38943a6a7e7SGarlic Tseng /* single DL use PAIR_INTERLEAVE */
390e4b31b81SRyder Lee if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)
39143a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap,
39243a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE,
39343a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_MASK,
39443a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE);
395e4b31b81SRyder Lee
39643a6a7e7SGarlic Tseng return mtk_afe_fe_hw_params(substream, params, dai);
39743a6a7e7SGarlic Tseng }
39843a6a7e7SGarlic Tseng
mt2701_dlm_fe_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)39943a6a7e7SGarlic Tseng static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,
40043a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
40143a6a7e7SGarlic Tseng {
402e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
40343a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif_tmp;
40443a6a7e7SGarlic Tseng const struct mtk_base_memif_data *memif_data;
40543a6a7e7SGarlic Tseng int i;
40643a6a7e7SGarlic Tseng
40743a6a7e7SGarlic Tseng for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
40843a6a7e7SGarlic Tseng memif_tmp = &afe->memif[i];
40943a6a7e7SGarlic Tseng if (memif_tmp->substream)
41043a6a7e7SGarlic Tseng return -EBUSY;
41143a6a7e7SGarlic Tseng }
41243a6a7e7SGarlic Tseng
41343a6a7e7SGarlic Tseng /* enable agent for all signal DL (due to hw design) */
41443a6a7e7SGarlic Tseng for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
41543a6a7e7SGarlic Tseng memif_data = afe->memif[i].data;
41643a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap,
41743a6a7e7SGarlic Tseng memif_data->agent_disable_reg,
41843a6a7e7SGarlic Tseng 1 << memif_data->agent_disable_shift,
41943a6a7e7SGarlic Tseng 0 << memif_data->agent_disable_shift);
42043a6a7e7SGarlic Tseng }
42143a6a7e7SGarlic Tseng
42243a6a7e7SGarlic Tseng return mtk_afe_fe_startup(substream, dai);
42343a6a7e7SGarlic Tseng }
42443a6a7e7SGarlic Tseng
mt2701_dlm_fe_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)42543a6a7e7SGarlic Tseng static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,
42643a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
42743a6a7e7SGarlic Tseng {
428e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
42943a6a7e7SGarlic Tseng const struct mtk_base_memif_data *memif_data;
43043a6a7e7SGarlic Tseng int i;
43143a6a7e7SGarlic Tseng
43243a6a7e7SGarlic Tseng for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {
43343a6a7e7SGarlic Tseng memif_data = afe->memif[i].data;
43443a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap,
43543a6a7e7SGarlic Tseng memif_data->agent_disable_reg,
43643a6a7e7SGarlic Tseng 1 << memif_data->agent_disable_shift,
43743a6a7e7SGarlic Tseng 1 << memif_data->agent_disable_shift);
43843a6a7e7SGarlic Tseng }
439e4b31b81SRyder Lee
44043a6a7e7SGarlic Tseng return mtk_afe_fe_shutdown(substream, dai);
44143a6a7e7SGarlic Tseng }
44243a6a7e7SGarlic Tseng
mt2701_dlm_fe_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)44343a6a7e7SGarlic Tseng static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,
44443a6a7e7SGarlic Tseng struct snd_pcm_hw_params *params,
44543a6a7e7SGarlic Tseng struct snd_soc_dai *dai)
44643a6a7e7SGarlic Tseng {
447e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
44843a6a7e7SGarlic Tseng int channels = params_channels(params);
44943a6a7e7SGarlic Tseng
45043a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap,
45143a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE,
45243a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_MASK,
45343a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE);
45443a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap,
45543a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE,
45643a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK,
45743a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_32BYTES);
45843a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap,
45943a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE,
46043a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK,
46143a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_CH(channels));
46243a6a7e7SGarlic Tseng
46343a6a7e7SGarlic Tseng return mtk_afe_fe_hw_params(substream, params, dai);
46443a6a7e7SGarlic Tseng }
46543a6a7e7SGarlic Tseng
mt2701_dlm_fe_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)46643a6a7e7SGarlic Tseng static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,
46743a6a7e7SGarlic Tseng int cmd, struct snd_soc_dai *dai)
46843a6a7e7SGarlic Tseng {
469e4b31b81SRyder Lee struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
47043a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];
47143a6a7e7SGarlic Tseng
47243a6a7e7SGarlic Tseng switch (cmd) {
47343a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_START:
47443a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_RESUME:
47543a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
47643a6a7e7SGarlic Tseng 1 << memif_tmp->data->enable_shift,
47743a6a7e7SGarlic Tseng 1 << memif_tmp->data->enable_shift);
47843a6a7e7SGarlic Tseng mtk_afe_fe_trigger(substream, cmd, dai);
47943a6a7e7SGarlic Tseng return 0;
48043a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_STOP:
48143a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_SUSPEND:
48243a6a7e7SGarlic Tseng mtk_afe_fe_trigger(substream, cmd, dai);
48343a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,
48443a6a7e7SGarlic Tseng 1 << memif_tmp->data->enable_shift, 0);
48543a6a7e7SGarlic Tseng
48643a6a7e7SGarlic Tseng return 0;
48743a6a7e7SGarlic Tseng default:
48843a6a7e7SGarlic Tseng return -EINVAL;
48943a6a7e7SGarlic Tseng }
49043a6a7e7SGarlic Tseng }
49143a6a7e7SGarlic Tseng
mt2701_memif_fs(struct snd_pcm_substream * substream,unsigned int rate)49243a6a7e7SGarlic Tseng static int mt2701_memif_fs(struct snd_pcm_substream *substream,
49343a6a7e7SGarlic Tseng unsigned int rate)
49443a6a7e7SGarlic Tseng {
495de9e7013SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
49643a6a7e7SGarlic Tseng int fs;
49743a6a7e7SGarlic Tseng
498de9e7013SKuninori Morimoto if (snd_soc_rtd_to_cpu(rtd, 0)->id != MT2701_MEMIF_ULBT)
49943a6a7e7SGarlic Tseng fs = mt2701_afe_i2s_fs(rate);
50043a6a7e7SGarlic Tseng else
50143a6a7e7SGarlic Tseng fs = (rate == 16000 ? 1 : 0);
502e4b31b81SRyder Lee
50343a6a7e7SGarlic Tseng return fs;
50443a6a7e7SGarlic Tseng }
50543a6a7e7SGarlic Tseng
mt2701_irq_fs(struct snd_pcm_substream * substream,unsigned int rate)50643a6a7e7SGarlic Tseng static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
50743a6a7e7SGarlic Tseng {
50843a6a7e7SGarlic Tseng return mt2701_afe_i2s_fs(rate);
50943a6a7e7SGarlic Tseng }
51043a6a7e7SGarlic Tseng
51143a6a7e7SGarlic Tseng /* FE DAIs */
51243a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = {
51343a6a7e7SGarlic Tseng .startup = mt2701_simple_fe_startup,
51443a6a7e7SGarlic Tseng .shutdown = mtk_afe_fe_shutdown,
51543a6a7e7SGarlic Tseng .hw_params = mt2701_simple_fe_hw_params,
51643a6a7e7SGarlic Tseng .hw_free = mtk_afe_fe_hw_free,
51743a6a7e7SGarlic Tseng .prepare = mtk_afe_fe_prepare,
51843a6a7e7SGarlic Tseng .trigger = mtk_afe_fe_trigger,
51943a6a7e7SGarlic Tseng };
52043a6a7e7SGarlic Tseng
52143a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = {
52243a6a7e7SGarlic Tseng .startup = mt2701_dlm_fe_startup,
52343a6a7e7SGarlic Tseng .shutdown = mt2701_dlm_fe_shutdown,
52443a6a7e7SGarlic Tseng .hw_params = mt2701_dlm_fe_hw_params,
52543a6a7e7SGarlic Tseng .hw_free = mtk_afe_fe_hw_free,
52643a6a7e7SGarlic Tseng .prepare = mtk_afe_fe_prepare,
52743a6a7e7SGarlic Tseng .trigger = mt2701_dlm_fe_trigger,
52843a6a7e7SGarlic Tseng };
52943a6a7e7SGarlic Tseng
53043a6a7e7SGarlic Tseng /* I2S BE DAIs */
53143a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {
53243a6a7e7SGarlic Tseng .startup = mt2701_afe_i2s_startup,
53343a6a7e7SGarlic Tseng .shutdown = mt2701_afe_i2s_shutdown,
53443a6a7e7SGarlic Tseng .prepare = mt2701_afe_i2s_prepare,
53543a6a7e7SGarlic Tseng .set_sysclk = mt2701_afe_i2s_set_sysclk,
53643a6a7e7SGarlic Tseng };
53743a6a7e7SGarlic Tseng
5384bdc8d45SGarlic Tseng /* MRG BE DAIs */
539549acff9SGustavo A. R. Silva static const struct snd_soc_dai_ops mt2701_btmrg_ops = {
5404bdc8d45SGarlic Tseng .startup = mt2701_btmrg_startup,
5414bdc8d45SGarlic Tseng .shutdown = mt2701_btmrg_shutdown,
5424bdc8d45SGarlic Tseng .hw_params = mt2701_btmrg_hw_params,
5434bdc8d45SGarlic Tseng };
5444bdc8d45SGarlic Tseng
54543a6a7e7SGarlic Tseng static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
54643a6a7e7SGarlic Tseng /* FE DAIs: memory intefaces to CPU */
54743a6a7e7SGarlic Tseng {
5488625c1dbSRyder Lee .name = "PCMO0",
5498625c1dbSRyder Lee .id = MT2701_MEMIF_DL1,
5508625c1dbSRyder Lee .playback = {
5518625c1dbSRyder Lee .stream_name = "DL1",
5528625c1dbSRyder Lee .channels_min = 1,
5538625c1dbSRyder Lee .channels_max = 2,
5548625c1dbSRyder Lee .rates = SNDRV_PCM_RATE_8000_192000,
5558625c1dbSRyder Lee .formats = (SNDRV_PCM_FMTBIT_S16_LE
5568625c1dbSRyder Lee | SNDRV_PCM_FMTBIT_S24_LE
5578625c1dbSRyder Lee | SNDRV_PCM_FMTBIT_S32_LE)
5588625c1dbSRyder Lee },
5598625c1dbSRyder Lee .ops = &mt2701_single_memif_dai_ops,
5608625c1dbSRyder Lee },
5618625c1dbSRyder Lee {
56243a6a7e7SGarlic Tseng .name = "PCM_multi",
56343a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DLM,
56443a6a7e7SGarlic Tseng .playback = {
56543a6a7e7SGarlic Tseng .stream_name = "DLM",
56643a6a7e7SGarlic Tseng .channels_min = 1,
56743a6a7e7SGarlic Tseng .channels_max = 8,
56843a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
56943a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
57043a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
57143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
57243a6a7e7SGarlic Tseng
57343a6a7e7SGarlic Tseng },
57443a6a7e7SGarlic Tseng .ops = &mt2701_dlm_memif_dai_ops,
57543a6a7e7SGarlic Tseng },
57643a6a7e7SGarlic Tseng {
57743a6a7e7SGarlic Tseng .name = "PCM0",
57843a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL1,
57943a6a7e7SGarlic Tseng .capture = {
58043a6a7e7SGarlic Tseng .stream_name = "UL1",
58143a6a7e7SGarlic Tseng .channels_min = 1,
58243a6a7e7SGarlic Tseng .channels_max = 2,
58343a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_48000,
58443a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
58543a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
58643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
58743a6a7e7SGarlic Tseng },
58843a6a7e7SGarlic Tseng .ops = &mt2701_single_memif_dai_ops,
58943a6a7e7SGarlic Tseng },
59043a6a7e7SGarlic Tseng {
59143a6a7e7SGarlic Tseng .name = "PCM1",
59243a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL2,
59343a6a7e7SGarlic Tseng .capture = {
59443a6a7e7SGarlic Tseng .stream_name = "UL2",
59543a6a7e7SGarlic Tseng .channels_min = 1,
59643a6a7e7SGarlic Tseng .channels_max = 2,
59743a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
59843a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
59943a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
60043a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
60143a6a7e7SGarlic Tseng
60243a6a7e7SGarlic Tseng },
60343a6a7e7SGarlic Tseng .ops = &mt2701_single_memif_dai_ops,
60443a6a7e7SGarlic Tseng },
6054bdc8d45SGarlic Tseng {
6064bdc8d45SGarlic Tseng .name = "PCM_BT_DL",
6074bdc8d45SGarlic Tseng .id = MT2701_MEMIF_DLBT,
6084bdc8d45SGarlic Tseng .playback = {
6094bdc8d45SGarlic Tseng .stream_name = "DLBT",
6104bdc8d45SGarlic Tseng .channels_min = 1,
6114bdc8d45SGarlic Tseng .channels_max = 1,
6124bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000
6134bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000),
6144bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE,
6154bdc8d45SGarlic Tseng },
6164bdc8d45SGarlic Tseng .ops = &mt2701_single_memif_dai_ops,
6174bdc8d45SGarlic Tseng },
6184bdc8d45SGarlic Tseng {
6194bdc8d45SGarlic Tseng .name = "PCM_BT_UL",
6204bdc8d45SGarlic Tseng .id = MT2701_MEMIF_ULBT,
6214bdc8d45SGarlic Tseng .capture = {
6224bdc8d45SGarlic Tseng .stream_name = "ULBT",
6234bdc8d45SGarlic Tseng .channels_min = 1,
6244bdc8d45SGarlic Tseng .channels_max = 1,
6254bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000
6264bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000),
6274bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE,
6284bdc8d45SGarlic Tseng },
6294bdc8d45SGarlic Tseng .ops = &mt2701_single_memif_dai_ops,
6304bdc8d45SGarlic Tseng },
63143a6a7e7SGarlic Tseng /* BE DAIs */
63243a6a7e7SGarlic Tseng {
63343a6a7e7SGarlic Tseng .name = "I2S0",
63443a6a7e7SGarlic Tseng .id = MT2701_IO_I2S,
63543a6a7e7SGarlic Tseng .playback = {
63643a6a7e7SGarlic Tseng .stream_name = "I2S0 Playback",
63743a6a7e7SGarlic Tseng .channels_min = 1,
63843a6a7e7SGarlic Tseng .channels_max = 2,
63943a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
64043a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
64143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
64243a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
64343a6a7e7SGarlic Tseng
64443a6a7e7SGarlic Tseng },
64543a6a7e7SGarlic Tseng .capture = {
64643a6a7e7SGarlic Tseng .stream_name = "I2S0 Capture",
64743a6a7e7SGarlic Tseng .channels_min = 1,
64843a6a7e7SGarlic Tseng .channels_max = 2,
64943a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
65043a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
65143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
65243a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
65343a6a7e7SGarlic Tseng
65443a6a7e7SGarlic Tseng },
65543a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops,
6564b7ead03SKuninori Morimoto .symmetric_rate = 1,
65743a6a7e7SGarlic Tseng },
65843a6a7e7SGarlic Tseng {
65943a6a7e7SGarlic Tseng .name = "I2S1",
66043a6a7e7SGarlic Tseng .id = MT2701_IO_2ND_I2S,
66143a6a7e7SGarlic Tseng .playback = {
66243a6a7e7SGarlic Tseng .stream_name = "I2S1 Playback",
66343a6a7e7SGarlic Tseng .channels_min = 1,
66443a6a7e7SGarlic Tseng .channels_max = 2,
66543a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
66643a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
66743a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
66843a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
66943a6a7e7SGarlic Tseng },
67043a6a7e7SGarlic Tseng .capture = {
67143a6a7e7SGarlic Tseng .stream_name = "I2S1 Capture",
67243a6a7e7SGarlic Tseng .channels_min = 1,
67343a6a7e7SGarlic Tseng .channels_max = 2,
67443a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
67543a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
67643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
67743a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
67843a6a7e7SGarlic Tseng },
67943a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops,
6804b7ead03SKuninori Morimoto .symmetric_rate = 1,
68143a6a7e7SGarlic Tseng },
68243a6a7e7SGarlic Tseng {
68343a6a7e7SGarlic Tseng .name = "I2S2",
68443a6a7e7SGarlic Tseng .id = MT2701_IO_3RD_I2S,
68543a6a7e7SGarlic Tseng .playback = {
68643a6a7e7SGarlic Tseng .stream_name = "I2S2 Playback",
68743a6a7e7SGarlic Tseng .channels_min = 1,
68843a6a7e7SGarlic Tseng .channels_max = 2,
68943a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
69043a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
69143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
69243a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
69343a6a7e7SGarlic Tseng },
69443a6a7e7SGarlic Tseng .capture = {
69543a6a7e7SGarlic Tseng .stream_name = "I2S2 Capture",
69643a6a7e7SGarlic Tseng .channels_min = 1,
69743a6a7e7SGarlic Tseng .channels_max = 2,
69843a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
69943a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
70043a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
70143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
70243a6a7e7SGarlic Tseng },
70343a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops,
7044b7ead03SKuninori Morimoto .symmetric_rate = 1,
70543a6a7e7SGarlic Tseng },
70643a6a7e7SGarlic Tseng {
70743a6a7e7SGarlic Tseng .name = "I2S3",
70843a6a7e7SGarlic Tseng .id = MT2701_IO_4TH_I2S,
70943a6a7e7SGarlic Tseng .playback = {
71043a6a7e7SGarlic Tseng .stream_name = "I2S3 Playback",
71143a6a7e7SGarlic Tseng .channels_min = 1,
71243a6a7e7SGarlic Tseng .channels_max = 2,
71343a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
71443a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
71543a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
71643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
71743a6a7e7SGarlic Tseng },
71843a6a7e7SGarlic Tseng .capture = {
71943a6a7e7SGarlic Tseng .stream_name = "I2S3 Capture",
72043a6a7e7SGarlic Tseng .channels_min = 1,
72143a6a7e7SGarlic Tseng .channels_max = 2,
72243a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000,
72343a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE
72443a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE
72543a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE)
72643a6a7e7SGarlic Tseng },
72743a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops,
7284b7ead03SKuninori Morimoto .symmetric_rate = 1,
72943a6a7e7SGarlic Tseng },
7304bdc8d45SGarlic Tseng {
7314bdc8d45SGarlic Tseng .name = "MRG BT",
7324bdc8d45SGarlic Tseng .id = MT2701_IO_MRG,
7334bdc8d45SGarlic Tseng .playback = {
7344bdc8d45SGarlic Tseng .stream_name = "BT Playback",
7354bdc8d45SGarlic Tseng .channels_min = 1,
7364bdc8d45SGarlic Tseng .channels_max = 1,
7374bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000
7384bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000),
7394bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE,
7404bdc8d45SGarlic Tseng },
7414bdc8d45SGarlic Tseng .capture = {
7424bdc8d45SGarlic Tseng .stream_name = "BT Capture",
7434bdc8d45SGarlic Tseng .channels_min = 1,
7444bdc8d45SGarlic Tseng .channels_max = 1,
7454bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000
7464bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000),
7474bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE,
7484bdc8d45SGarlic Tseng },
7494bdc8d45SGarlic Tseng .ops = &mt2701_btmrg_ops,
7504b7ead03SKuninori Morimoto .symmetric_rate = 1,
7514bdc8d45SGarlic Tseng }
75243a6a7e7SGarlic Tseng };
75343a6a7e7SGarlic Tseng
75443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = {
75543a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0),
75643a6a7e7SGarlic Tseng };
75743a6a7e7SGarlic Tseng
75843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o01_mix[] = {
75943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0),
76043a6a7e7SGarlic Tseng };
76143a6a7e7SGarlic Tseng
76243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o02_mix[] = {
76343a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0),
76443a6a7e7SGarlic Tseng };
76543a6a7e7SGarlic Tseng
76643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o03_mix[] = {
76743a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0),
76843a6a7e7SGarlic Tseng };
76943a6a7e7SGarlic Tseng
77043a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o14_mix[] = {
77143a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0),
77243a6a7e7SGarlic Tseng };
77343a6a7e7SGarlic Tseng
77443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o15_mix[] = {
77543a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0),
77643a6a7e7SGarlic Tseng };
77743a6a7e7SGarlic Tseng
77843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o16_mix[] = {
77943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0),
78043a6a7e7SGarlic Tseng };
78143a6a7e7SGarlic Tseng
78243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o17_mix[] = {
78343a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0),
78443a6a7e7SGarlic Tseng };
78543a6a7e7SGarlic Tseng
78643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o18_mix[] = {
78743a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0),
78843a6a7e7SGarlic Tseng };
78943a6a7e7SGarlic Tseng
79043a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o19_mix[] = {
79143a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0),
79243a6a7e7SGarlic Tseng };
79343a6a7e7SGarlic Tseng
79443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o20_mix[] = {
79543a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0),
79643a6a7e7SGarlic Tseng };
79743a6a7e7SGarlic Tseng
79843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o21_mix[] = {
79943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0),
80043a6a7e7SGarlic Tseng };
80143a6a7e7SGarlic Tseng
80243a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = {
80343a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),
80443a6a7e7SGarlic Tseng };
80543a6a7e7SGarlic Tseng
80643a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = {
80743a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0),
80843a6a7e7SGarlic Tseng };
80943a6a7e7SGarlic Tseng
81043a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_i02_mix[] = {
81143a6a7e7SGarlic Tseng SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0),
81243a6a7e7SGarlic Tseng };
81343a6a7e7SGarlic Tseng
81443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = {
81543a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch",
81643a6a7e7SGarlic Tseng ASYS_I2SO1_CON, 26, 1, 0),
81743a6a7e7SGarlic Tseng };
81843a6a7e7SGarlic Tseng
81943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = {
82043a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch",
82143a6a7e7SGarlic Tseng ASYS_I2SO2_CON, 26, 1, 0),
82243a6a7e7SGarlic Tseng };
82343a6a7e7SGarlic Tseng
82443a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = {
82543a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch",
82643a6a7e7SGarlic Tseng PWR2_TOP_CON, 17, 1, 0),
82743a6a7e7SGarlic Tseng };
82843a6a7e7SGarlic Tseng
82943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = {
83043a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch",
83143a6a7e7SGarlic Tseng PWR2_TOP_CON, 18, 1, 0),
83243a6a7e7SGarlic Tseng };
83343a6a7e7SGarlic Tseng
83443a6a7e7SGarlic Tseng static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {
83543a6a7e7SGarlic Tseng /* inter-connections */
83643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),
83743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0),
83843a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix,
83943a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_i02_mix)),
84043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),
84143a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0),
84243a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0),
84343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0),
84443a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0),
84543a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0),
84643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),
84743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),
84843a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0),
84943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0),
85043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0),
85143a6a7e7SGarlic Tseng
85243a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix,
85343a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o00_mix)),
85443a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix,
85543a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o01_mix)),
85643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix,
85743a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o02_mix)),
85843a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix,
85943a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o03_mix)),
86043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix,
86143a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o14_mix)),
86243a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix,
86343a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o15_mix)),
86443a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix,
86543a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o16_mix)),
86643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix,
86743a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o17_mix)),
86843a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix,
86943a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o18_mix)),
87043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix,
87143a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o19_mix)),
87243a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix,
87343a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o20_mix)),
87443a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix,
87543a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o21_mix)),
87643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix,
87743a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o22_mix)),
87843a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix,
87943a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o31_mix)),
88043a6a7e7SGarlic Tseng
88143a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0,
88243a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s0,
88343a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)),
88443a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0,
88543a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s1,
88643a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)),
88743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0,
88843a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s2,
88943a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)),
89043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0,
89143a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s3,
89243a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)),
89343a6a7e7SGarlic Tseng };
89443a6a7e7SGarlic Tseng
89543a6a7e7SGarlic Tseng static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {
89643a6a7e7SGarlic Tseng {"I12", NULL, "DL1"},
89743a6a7e7SGarlic Tseng {"I13", NULL, "DL1"},
89843a6a7e7SGarlic Tseng {"I35", NULL, "DLBT"},
89943a6a7e7SGarlic Tseng
90043a6a7e7SGarlic Tseng {"I2S0 Playback", NULL, "O15"},
90143a6a7e7SGarlic Tseng {"I2S0 Playback", NULL, "O16"},
90243a6a7e7SGarlic Tseng {"I2S1 Playback", NULL, "O17"},
90343a6a7e7SGarlic Tseng {"I2S1 Playback", NULL, "O18"},
90443a6a7e7SGarlic Tseng {"I2S2 Playback", NULL, "O19"},
90543a6a7e7SGarlic Tseng {"I2S2 Playback", NULL, "O20"},
90643a6a7e7SGarlic Tseng {"I2S3 Playback", NULL, "O21"},
90743a6a7e7SGarlic Tseng {"I2S3 Playback", NULL, "O22"},
90843a6a7e7SGarlic Tseng {"BT Playback", NULL, "O31"},
90943a6a7e7SGarlic Tseng
91043a6a7e7SGarlic Tseng {"UL1", NULL, "O00"},
91143a6a7e7SGarlic Tseng {"UL1", NULL, "O01"},
91243a6a7e7SGarlic Tseng {"UL2", NULL, "O02"},
91343a6a7e7SGarlic Tseng {"UL2", NULL, "O03"},
91443a6a7e7SGarlic Tseng {"ULBT", NULL, "O14"},
91543a6a7e7SGarlic Tseng
91643a6a7e7SGarlic Tseng {"I00", NULL, "I2S0 Capture"},
91743a6a7e7SGarlic Tseng {"I01", NULL, "I2S0 Capture"},
91843a6a7e7SGarlic Tseng {"I02", NULL, "I2S1 Capture"},
91943a6a7e7SGarlic Tseng {"I03", NULL, "I2S1 Capture"},
92043a6a7e7SGarlic Tseng /* I02,03 link to UL2, also need to open I2S0 */
92143a6a7e7SGarlic Tseng {"I02", "I2S0 Switch", "I2S0 Capture"},
92243a6a7e7SGarlic Tseng
92343a6a7e7SGarlic Tseng {"I26", NULL, "BT Capture"},
92443a6a7e7SGarlic Tseng
925600b2fd4SRyder Lee {"I12I13", "Multich I2S0 Out Switch", "DLM"},
926600b2fd4SRyder Lee {"I14I15", "Multich I2S1 Out Switch", "DLM"},
927600b2fd4SRyder Lee {"I16I17", "Multich I2S2 Out Switch", "DLM"},
928600b2fd4SRyder Lee {"I18I19", "Multich I2S3 Out Switch", "DLM"},
92943a6a7e7SGarlic Tseng
93043a6a7e7SGarlic Tseng { "I12", NULL, "I12I13" },
93143a6a7e7SGarlic Tseng { "I13", NULL, "I12I13" },
93243a6a7e7SGarlic Tseng { "I14", NULL, "I14I15" },
93343a6a7e7SGarlic Tseng { "I15", NULL, "I14I15" },
93443a6a7e7SGarlic Tseng { "I16", NULL, "I16I17" },
93543a6a7e7SGarlic Tseng { "I17", NULL, "I16I17" },
93643a6a7e7SGarlic Tseng { "I18", NULL, "I18I19" },
93743a6a7e7SGarlic Tseng { "I19", NULL, "I18I19" },
93843a6a7e7SGarlic Tseng
93943a6a7e7SGarlic Tseng { "O00", "I00 Switch", "I00" },
94043a6a7e7SGarlic Tseng { "O01", "I01 Switch", "I01" },
94143a6a7e7SGarlic Tseng { "O02", "I02 Switch", "I02" },
94243a6a7e7SGarlic Tseng { "O03", "I03 Switch", "I03" },
94343a6a7e7SGarlic Tseng { "O14", "I26 Switch", "I26" },
94443a6a7e7SGarlic Tseng { "O15", "I12 Switch", "I12" },
94543a6a7e7SGarlic Tseng { "O16", "I13 Switch", "I13" },
94643a6a7e7SGarlic Tseng { "O17", "I14 Switch", "I14" },
94743a6a7e7SGarlic Tseng { "O18", "I15 Switch", "I15" },
94843a6a7e7SGarlic Tseng { "O19", "I16 Switch", "I16" },
94943a6a7e7SGarlic Tseng { "O20", "I17 Switch", "I17" },
95043a6a7e7SGarlic Tseng { "O21", "I18 Switch", "I18" },
95143a6a7e7SGarlic Tseng { "O22", "I19 Switch", "I19" },
95243a6a7e7SGarlic Tseng { "O31", "I35 Switch", "I35" },
95343a6a7e7SGarlic Tseng };
95443a6a7e7SGarlic Tseng
mt2701_afe_pcm_probe(struct snd_soc_component * component)95510abdc7cSRyder Lee static int mt2701_afe_pcm_probe(struct snd_soc_component *component)
95610abdc7cSRyder Lee {
95710abdc7cSRyder Lee struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
95810abdc7cSRyder Lee
95910abdc7cSRyder Lee snd_soc_component_init_regmap(component, afe->regmap);
96010abdc7cSRyder Lee
96110abdc7cSRyder Lee return 0;
96210abdc7cSRyder Lee }
96310abdc7cSRyder Lee
96443a6a7e7SGarlic Tseng static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {
96510abdc7cSRyder Lee .probe = mt2701_afe_pcm_probe,
96643a6a7e7SGarlic Tseng .name = "mt2701-afe-pcm-dai",
96743a6a7e7SGarlic Tseng .dapm_widgets = mt2701_afe_pcm_widgets,
96843a6a7e7SGarlic Tseng .num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets),
96943a6a7e7SGarlic Tseng .dapm_routes = mt2701_afe_pcm_routes,
97043a6a7e7SGarlic Tseng .num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes),
9717ec6b431SKuninori Morimoto .suspend = mtk_afe_suspend,
9727ec6b431SKuninori Morimoto .resume = mtk_afe_resume,
97343a6a7e7SGarlic Tseng };
97443a6a7e7SGarlic Tseng
975d9cdc133SPierre-Louis Bossart static const struct mtk_base_memif_data memif_data_array[MT2701_MEMIF_NUM] = {
97643a6a7e7SGarlic Tseng {
97743a6a7e7SGarlic Tseng .name = "DL1",
97843a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL1,
97943a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL1_BASE,
98043a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL1_CUR,
98143a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1,
98243a6a7e7SGarlic Tseng .fs_shift = 0,
98343a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
98443a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3,
98543a6a7e7SGarlic Tseng .mono_shift = 16,
98643a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
98743a6a7e7SGarlic Tseng .enable_shift = 1,
98843a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
98943a6a7e7SGarlic Tseng .hd_shift = 0,
99043a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
99143a6a7e7SGarlic Tseng .agent_disable_shift = 6,
99243a6a7e7SGarlic Tseng .msb_reg = -1,
99343a6a7e7SGarlic Tseng },
99443a6a7e7SGarlic Tseng {
99543a6a7e7SGarlic Tseng .name = "DL2",
99643a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL2,
99743a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL2_BASE,
99843a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL2_CUR,
99943a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1,
100043a6a7e7SGarlic Tseng .fs_shift = 5,
100143a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
100243a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3,
100343a6a7e7SGarlic Tseng .mono_shift = 17,
100443a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
100543a6a7e7SGarlic Tseng .enable_shift = 2,
100643a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
100743a6a7e7SGarlic Tseng .hd_shift = 2,
100843a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
100943a6a7e7SGarlic Tseng .agent_disable_shift = 7,
101043a6a7e7SGarlic Tseng .msb_reg = -1,
101143a6a7e7SGarlic Tseng },
101243a6a7e7SGarlic Tseng {
101343a6a7e7SGarlic Tseng .name = "DL3",
101443a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL3,
101543a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL3_BASE,
101643a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL3_CUR,
101743a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1,
101843a6a7e7SGarlic Tseng .fs_shift = 10,
101943a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
102043a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3,
102143a6a7e7SGarlic Tseng .mono_shift = 18,
102243a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
102343a6a7e7SGarlic Tseng .enable_shift = 3,
102443a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
102543a6a7e7SGarlic Tseng .hd_shift = 4,
102643a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
102743a6a7e7SGarlic Tseng .agent_disable_shift = 8,
102843a6a7e7SGarlic Tseng .msb_reg = -1,
102943a6a7e7SGarlic Tseng },
103043a6a7e7SGarlic Tseng {
103143a6a7e7SGarlic Tseng .name = "DL4",
103243a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL4,
103343a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL4_BASE,
103443a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL4_CUR,
103543a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1,
103643a6a7e7SGarlic Tseng .fs_shift = 15,
103743a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
103843a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3,
103943a6a7e7SGarlic Tseng .mono_shift = 19,
104043a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
104143a6a7e7SGarlic Tseng .enable_shift = 4,
104243a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
104343a6a7e7SGarlic Tseng .hd_shift = 6,
104443a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
104543a6a7e7SGarlic Tseng .agent_disable_shift = 9,
104643a6a7e7SGarlic Tseng .msb_reg = -1,
104743a6a7e7SGarlic Tseng },
104843a6a7e7SGarlic Tseng {
104943a6a7e7SGarlic Tseng .name = "DL5",
105043a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL5,
105143a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL5_BASE,
105243a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL5_CUR,
105343a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1,
105443a6a7e7SGarlic Tseng .fs_shift = 20,
105543a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
105643a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3,
105743a6a7e7SGarlic Tseng .mono_shift = 20,
105843a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
105943a6a7e7SGarlic Tseng .enable_shift = 5,
106043a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
106143a6a7e7SGarlic Tseng .hd_shift = 8,
106243a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
106343a6a7e7SGarlic Tseng .agent_disable_shift = 10,
106443a6a7e7SGarlic Tseng .msb_reg = -1,
106543a6a7e7SGarlic Tseng },
106643a6a7e7SGarlic Tseng {
106743a6a7e7SGarlic Tseng .name = "DLM",
106843a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DLM,
106943a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DLMCH_BASE,
107043a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DLMCH_CUR,
107143a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1,
107243a6a7e7SGarlic Tseng .fs_shift = 0,
107343a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
107443a6a7e7SGarlic Tseng .mono_reg = -1,
107543a6a7e7SGarlic Tseng .mono_shift = -1,
107643a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
107743a6a7e7SGarlic Tseng .enable_shift = 7,
107843a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_PBUF_SIZE,
107943a6a7e7SGarlic Tseng .hd_shift = 28,
108043a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
108143a6a7e7SGarlic Tseng .agent_disable_shift = 12,
108243a6a7e7SGarlic Tseng .msb_reg = -1,
108343a6a7e7SGarlic Tseng },
108443a6a7e7SGarlic Tseng {
108543a6a7e7SGarlic Tseng .name = "UL1",
108643a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL1,
108743a6a7e7SGarlic Tseng .reg_ofs_base = AFE_VUL_BASE,
108843a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_VUL_CUR,
108943a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2,
109043a6a7e7SGarlic Tseng .fs_shift = 0,
109143a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
109243a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4,
109343a6a7e7SGarlic Tseng .mono_shift = 0,
109443a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
109543a6a7e7SGarlic Tseng .enable_shift = 10,
109643a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON1,
109743a6a7e7SGarlic Tseng .hd_shift = 0,
109843a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
109943a6a7e7SGarlic Tseng .agent_disable_shift = 0,
110043a6a7e7SGarlic Tseng .msb_reg = -1,
110143a6a7e7SGarlic Tseng },
110243a6a7e7SGarlic Tseng {
110343a6a7e7SGarlic Tseng .name = "UL2",
110443a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL2,
110543a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL2_BASE,
110643a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL2_CUR,
110743a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2,
110843a6a7e7SGarlic Tseng .fs_shift = 5,
110943a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
111043a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4,
111143a6a7e7SGarlic Tseng .mono_shift = 2,
111243a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
111343a6a7e7SGarlic Tseng .enable_shift = 11,
111443a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON1,
111543a6a7e7SGarlic Tseng .hd_shift = 2,
111643a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
111743a6a7e7SGarlic Tseng .agent_disable_shift = 1,
111843a6a7e7SGarlic Tseng .msb_reg = -1,
111943a6a7e7SGarlic Tseng },
112043a6a7e7SGarlic Tseng {
112143a6a7e7SGarlic Tseng .name = "UL3",
112243a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL3,
112343a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL3_BASE,
112443a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL3_CUR,
112543a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2,
112643a6a7e7SGarlic Tseng .fs_shift = 10,
112743a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
112843a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4,
112943a6a7e7SGarlic Tseng .mono_shift = 4,
113043a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
113143a6a7e7SGarlic Tseng .enable_shift = 12,
113243a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
113343a6a7e7SGarlic Tseng .hd_shift = 0,
113443a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
113543a6a7e7SGarlic Tseng .agent_disable_shift = 2,
113643a6a7e7SGarlic Tseng .msb_reg = -1,
113743a6a7e7SGarlic Tseng },
113843a6a7e7SGarlic Tseng {
113943a6a7e7SGarlic Tseng .name = "UL4",
114043a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL4,
114143a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL4_BASE,
114243a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL4_CUR,
114343a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2,
114443a6a7e7SGarlic Tseng .fs_shift = 15,
114543a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
114643a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4,
114743a6a7e7SGarlic Tseng .mono_shift = 6,
114843a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
114943a6a7e7SGarlic Tseng .enable_shift = 13,
115043a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
115143a6a7e7SGarlic Tseng .hd_shift = 6,
115243a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
115343a6a7e7SGarlic Tseng .agent_disable_shift = 3,
115443a6a7e7SGarlic Tseng .msb_reg = -1,
115543a6a7e7SGarlic Tseng },
115643a6a7e7SGarlic Tseng {
115743a6a7e7SGarlic Tseng .name = "UL5",
115843a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL5,
115943a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL5_BASE,
116043a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL5_CUR,
116143a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2,
116243a6a7e7SGarlic Tseng .fs_shift = 20,
116343a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4,
116443a6a7e7SGarlic Tseng .mono_shift = 8,
116543a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
116643a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
116743a6a7e7SGarlic Tseng .enable_shift = 14,
116843a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
116943a6a7e7SGarlic Tseng .hd_shift = 8,
117043a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
117143a6a7e7SGarlic Tseng .agent_disable_shift = 4,
117243a6a7e7SGarlic Tseng .msb_reg = -1,
117343a6a7e7SGarlic Tseng },
117443a6a7e7SGarlic Tseng {
117543a6a7e7SGarlic Tseng .name = "DLBT",
117643a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DLBT,
117743a6a7e7SGarlic Tseng .reg_ofs_base = AFE_ARB1_BASE,
117843a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_ARB1_CUR,
117943a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON3,
118043a6a7e7SGarlic Tseng .fs_shift = 10,
118143a6a7e7SGarlic Tseng .fs_maskbit = 0x1f,
118243a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3,
118343a6a7e7SGarlic Tseng .mono_shift = 22,
118443a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
118543a6a7e7SGarlic Tseng .enable_shift = 8,
118643a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0,
118743a6a7e7SGarlic Tseng .hd_shift = 14,
118843a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
118943a6a7e7SGarlic Tseng .agent_disable_shift = 13,
119043a6a7e7SGarlic Tseng .msb_reg = -1,
119143a6a7e7SGarlic Tseng },
119243a6a7e7SGarlic Tseng {
119343a6a7e7SGarlic Tseng .name = "ULBT",
119443a6a7e7SGarlic Tseng .id = MT2701_MEMIF_ULBT,
119543a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DAI_BASE,
119643a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DAI_CUR,
119743a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2,
119843a6a7e7SGarlic Tseng .fs_shift = 30,
119943a6a7e7SGarlic Tseng .fs_maskbit = 0x1,
120043a6a7e7SGarlic Tseng .mono_reg = -1,
120143a6a7e7SGarlic Tseng .mono_shift = -1,
120243a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0,
120343a6a7e7SGarlic Tseng .enable_shift = 17,
120443a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON1,
120543a6a7e7SGarlic Tseng .hd_shift = 20,
120643a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5,
120743a6a7e7SGarlic Tseng .agent_disable_shift = 16,
120843a6a7e7SGarlic Tseng .msb_reg = -1,
120943a6a7e7SGarlic Tseng },
121043a6a7e7SGarlic Tseng };
121143a6a7e7SGarlic Tseng
121243a6a7e7SGarlic Tseng static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {
121343a6a7e7SGarlic Tseng {
121443a6a7e7SGarlic Tseng .id = MT2701_IRQ_ASYS_IRQ1,
121543a6a7e7SGarlic Tseng .irq_cnt_reg = ASYS_IRQ1_CON,
121643a6a7e7SGarlic Tseng .irq_cnt_shift = 0,
121743a6a7e7SGarlic Tseng .irq_cnt_maskbit = 0xffffff,
121843a6a7e7SGarlic Tseng .irq_fs_reg = ASYS_IRQ1_CON,
121943a6a7e7SGarlic Tseng .irq_fs_shift = 24,
122043a6a7e7SGarlic Tseng .irq_fs_maskbit = 0x1f,
122143a6a7e7SGarlic Tseng .irq_en_reg = ASYS_IRQ1_CON,
122243a6a7e7SGarlic Tseng .irq_en_shift = 31,
122343a6a7e7SGarlic Tseng .irq_clr_reg = ASYS_IRQ_CLR,
122443a6a7e7SGarlic Tseng .irq_clr_shift = 0,
122543a6a7e7SGarlic Tseng },
122643a6a7e7SGarlic Tseng {
122743a6a7e7SGarlic Tseng .id = MT2701_IRQ_ASYS_IRQ2,
122843a6a7e7SGarlic Tseng .irq_cnt_reg = ASYS_IRQ2_CON,
122943a6a7e7SGarlic Tseng .irq_cnt_shift = 0,
123043a6a7e7SGarlic Tseng .irq_cnt_maskbit = 0xffffff,
123143a6a7e7SGarlic Tseng .irq_fs_reg = ASYS_IRQ2_CON,
123243a6a7e7SGarlic Tseng .irq_fs_shift = 24,
123343a6a7e7SGarlic Tseng .irq_fs_maskbit = 0x1f,
123443a6a7e7SGarlic Tseng .irq_en_reg = ASYS_IRQ2_CON,
123543a6a7e7SGarlic Tseng .irq_en_shift = 31,
123643a6a7e7SGarlic Tseng .irq_clr_reg = ASYS_IRQ_CLR,
123743a6a7e7SGarlic Tseng .irq_clr_shift = 1,
123843a6a7e7SGarlic Tseng },
123943a6a7e7SGarlic Tseng {
124043a6a7e7SGarlic Tseng .id = MT2701_IRQ_ASYS_IRQ3,
124143a6a7e7SGarlic Tseng .irq_cnt_reg = ASYS_IRQ3_CON,
124243a6a7e7SGarlic Tseng .irq_cnt_shift = 0,
124343a6a7e7SGarlic Tseng .irq_cnt_maskbit = 0xffffff,
124443a6a7e7SGarlic Tseng .irq_fs_reg = ASYS_IRQ3_CON,
124543a6a7e7SGarlic Tseng .irq_fs_shift = 24,
124643a6a7e7SGarlic Tseng .irq_fs_maskbit = 0x1f,
124743a6a7e7SGarlic Tseng .irq_en_reg = ASYS_IRQ3_CON,
124843a6a7e7SGarlic Tseng .irq_en_shift = 31,
124943a6a7e7SGarlic Tseng .irq_clr_reg = ASYS_IRQ_CLR,
125043a6a7e7SGarlic Tseng .irq_clr_shift = 2,
125143a6a7e7SGarlic Tseng }
125243a6a7e7SGarlic Tseng };
125343a6a7e7SGarlic Tseng
1254ab7b4ee9SRyder Lee static const struct mt2701_i2s_data mt2701_i2s_data[][2] = {
125543a6a7e7SGarlic Tseng {
1256ab7b4ee9SRyder Lee { ASYS_I2SO1_CON, 0, 0x1f },
1257ab7b4ee9SRyder Lee { ASYS_I2SIN1_CON, 0, 0x1f },
125843a6a7e7SGarlic Tseng },
125943a6a7e7SGarlic Tseng {
1260ab7b4ee9SRyder Lee { ASYS_I2SO2_CON, 5, 0x1f },
1261ab7b4ee9SRyder Lee { ASYS_I2SIN2_CON, 5, 0x1f },
126243a6a7e7SGarlic Tseng },
126343a6a7e7SGarlic Tseng {
1264ab7b4ee9SRyder Lee { ASYS_I2SO3_CON, 10, 0x1f },
1265ab7b4ee9SRyder Lee { ASYS_I2SIN3_CON, 10, 0x1f },
126643a6a7e7SGarlic Tseng },
126743a6a7e7SGarlic Tseng {
1268ab7b4ee9SRyder Lee { ASYS_I2SO4_CON, 15, 0x1f },
1269ab7b4ee9SRyder Lee { ASYS_I2SIN4_CON, 15, 0x1f },
127043a6a7e7SGarlic Tseng },
1271ab7b4ee9SRyder Lee /* TODO - extend control registers supported by newer SoCs */
127243a6a7e7SGarlic Tseng };
127343a6a7e7SGarlic Tseng
mt2701_asys_isr(int irq_id,void * dev)127443a6a7e7SGarlic Tseng static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)
127543a6a7e7SGarlic Tseng {
127643a6a7e7SGarlic Tseng int id;
127743a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev;
127843a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif;
127943a6a7e7SGarlic Tseng struct mtk_base_afe_irq *irq;
128043a6a7e7SGarlic Tseng u32 status;
128143a6a7e7SGarlic Tseng
128243a6a7e7SGarlic Tseng regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status);
128343a6a7e7SGarlic Tseng regmap_write(afe->regmap, ASYS_IRQ_CLR, status);
128443a6a7e7SGarlic Tseng
128543a6a7e7SGarlic Tseng for (id = 0; id < MT2701_MEMIF_NUM; ++id) {
128643a6a7e7SGarlic Tseng memif = &afe->memif[id];
128743a6a7e7SGarlic Tseng if (memif->irq_usage < 0)
128843a6a7e7SGarlic Tseng continue;
1289e4b31b81SRyder Lee
129043a6a7e7SGarlic Tseng irq = &afe->irqs[memif->irq_usage];
1291e4b31b81SRyder Lee if (status & 1 << irq->irq_data->irq_clr_shift)
129243a6a7e7SGarlic Tseng snd_pcm_period_elapsed(memif->substream);
129343a6a7e7SGarlic Tseng }
1294e4b31b81SRyder Lee
129543a6a7e7SGarlic Tseng return IRQ_HANDLED;
129643a6a7e7SGarlic Tseng }
129743a6a7e7SGarlic Tseng
mt2701_afe_runtime_suspend(struct device * dev)129843a6a7e7SGarlic Tseng static int mt2701_afe_runtime_suspend(struct device *dev)
129943a6a7e7SGarlic Tseng {
130043a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev_get_drvdata(dev);
130143a6a7e7SGarlic Tseng
1302d8d99d8eSRyder Lee return mt2701_afe_disable_clock(afe);
130343a6a7e7SGarlic Tseng }
130443a6a7e7SGarlic Tseng
mt2701_afe_runtime_resume(struct device * dev)130543a6a7e7SGarlic Tseng static int mt2701_afe_runtime_resume(struct device *dev)
130643a6a7e7SGarlic Tseng {
130743a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev_get_drvdata(dev);
130843a6a7e7SGarlic Tseng
130943a6a7e7SGarlic Tseng return mt2701_afe_enable_clock(afe);
131043a6a7e7SGarlic Tseng }
131143a6a7e7SGarlic Tseng
mt2701_afe_pcm_dev_probe(struct platform_device * pdev)1312dc2a17f4SRyder Lee static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
1313dc2a17f4SRyder Lee {
131443a6a7e7SGarlic Tseng struct mtk_base_afe *afe;
131543a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv;
131643a6a7e7SGarlic Tseng struct device *dev;
1317f6c1626eSRyder Lee int i, irq_id, ret;
131843a6a7e7SGarlic Tseng
131943a6a7e7SGarlic Tseng afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
132043a6a7e7SGarlic Tseng if (!afe)
132143a6a7e7SGarlic Tseng return -ENOMEM;
1322600b2fd4SRyder Lee
1323b02c5cc7SDan Carpenter afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
1324b02c5cc7SDan Carpenter GFP_KERNEL);
1325b02c5cc7SDan Carpenter if (!afe->platform_priv)
1326b02c5cc7SDan Carpenter return -ENOMEM;
132743a6a7e7SGarlic Tseng
1328600b2fd4SRyder Lee afe_priv = afe->platform_priv;
1329bfdc56e5SRyder Lee afe_priv->soc = of_device_get_match_data(&pdev->dev);
133043a6a7e7SGarlic Tseng afe->dev = &pdev->dev;
133143a6a7e7SGarlic Tseng dev = afe->dev;
133243a6a7e7SGarlic Tseng
1333a86854d0SKees Cook afe_priv->i2s_path = devm_kcalloc(dev,
1334a86854d0SKees Cook afe_priv->soc->i2s_num,
1335bfdc56e5SRyder Lee sizeof(struct mt2701_i2s_path),
1336bfdc56e5SRyder Lee GFP_KERNEL);
1337bfdc56e5SRyder Lee if (!afe_priv->i2s_path)
1338bfdc56e5SRyder Lee return -ENOMEM;
1339bfdc56e5SRyder Lee
1340f6c1626eSRyder Lee irq_id = platform_get_irq_byname(pdev, "asys");
1341cf9441adSStephen Boyd if (irq_id < 0)
1342f6c1626eSRyder Lee return irq_id;
1343f6c1626eSRyder Lee
134443a6a7e7SGarlic Tseng ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,
134543a6a7e7SGarlic Tseng IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
134643a6a7e7SGarlic Tseng if (ret) {
134743a6a7e7SGarlic Tseng dev_err(dev, "could not request_irq for asys-isr\n");
134843a6a7e7SGarlic Tseng return ret;
134943a6a7e7SGarlic Tseng }
135043a6a7e7SGarlic Tseng
1351dfa3cbb8SRyder Lee afe->regmap = syscon_node_to_regmap(dev->parent->of_node);
13523e8052d9SWei Yongjun if (IS_ERR(afe->regmap)) {
1353dfa3cbb8SRyder Lee dev_err(dev, "could not get regmap from parent\n");
13543e8052d9SWei Yongjun return PTR_ERR(afe->regmap);
1355dfa3cbb8SRyder Lee }
135643a6a7e7SGarlic Tseng
135743a6a7e7SGarlic Tseng mutex_init(&afe->irq_alloc_lock);
135843a6a7e7SGarlic Tseng
135943a6a7e7SGarlic Tseng /* memif initialize */
136043a6a7e7SGarlic Tseng afe->memif_size = MT2701_MEMIF_NUM;
136143a6a7e7SGarlic Tseng afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
136243a6a7e7SGarlic Tseng GFP_KERNEL);
136343a6a7e7SGarlic Tseng if (!afe->memif)
136443a6a7e7SGarlic Tseng return -ENOMEM;
136543a6a7e7SGarlic Tseng
136643a6a7e7SGarlic Tseng for (i = 0; i < afe->memif_size; i++) {
1367d9cdc133SPierre-Louis Bossart afe->memif[i].data = &memif_data_array[i];
136843a6a7e7SGarlic Tseng afe->memif[i].irq_usage = -1;
136943a6a7e7SGarlic Tseng }
137043a6a7e7SGarlic Tseng
137143a6a7e7SGarlic Tseng /* irq initialize */
137243a6a7e7SGarlic Tseng afe->irqs_size = MT2701_IRQ_ASYS_END;
137343a6a7e7SGarlic Tseng afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
137443a6a7e7SGarlic Tseng GFP_KERNEL);
137543a6a7e7SGarlic Tseng if (!afe->irqs)
137643a6a7e7SGarlic Tseng return -ENOMEM;
137743a6a7e7SGarlic Tseng
137843a6a7e7SGarlic Tseng for (i = 0; i < afe->irqs_size; i++)
137943a6a7e7SGarlic Tseng afe->irqs[i].irq_data = &irq_data[i];
138043a6a7e7SGarlic Tseng
138143a6a7e7SGarlic Tseng /* I2S initialize */
1382bfdc56e5SRyder Lee for (i = 0; i < afe_priv->soc->i2s_num; i++) {
1383ab7b4ee9SRyder Lee afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_PLAYBACK] =
1384ab7b4ee9SRyder Lee &mt2701_i2s_data[i][SNDRV_PCM_STREAM_PLAYBACK];
1385ab7b4ee9SRyder Lee afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_CAPTURE] =
1386ab7b4ee9SRyder Lee &mt2701_i2s_data[i][SNDRV_PCM_STREAM_CAPTURE];
138743a6a7e7SGarlic Tseng }
138843a6a7e7SGarlic Tseng
138943a6a7e7SGarlic Tseng afe->mtk_afe_hardware = &mt2701_afe_hardware;
139043a6a7e7SGarlic Tseng afe->memif_fs = mt2701_memif_fs;
139143a6a7e7SGarlic Tseng afe->irq_fs = mt2701_irq_fs;
139243a6a7e7SGarlic Tseng afe->reg_back_up_list = mt2701_afe_backup_list;
139343a6a7e7SGarlic Tseng afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list);
139443a6a7e7SGarlic Tseng afe->runtime_resume = mt2701_afe_runtime_resume;
139543a6a7e7SGarlic Tseng afe->runtime_suspend = mt2701_afe_runtime_suspend;
139643a6a7e7SGarlic Tseng
139743a6a7e7SGarlic Tseng /* initial audio related clock */
139843a6a7e7SGarlic Tseng ret = mt2701_init_clock(afe);
139943a6a7e7SGarlic Tseng if (ret) {
140043a6a7e7SGarlic Tseng dev_err(dev, "init clock error\n");
1401dc2a17f4SRyder Lee return ret;
140243a6a7e7SGarlic Tseng }
140343a6a7e7SGarlic Tseng
140443a6a7e7SGarlic Tseng platform_set_drvdata(pdev, afe);
140543a6a7e7SGarlic Tseng
1406dd6bb9b1SRyder Lee pm_runtime_enable(dev);
1407dd6bb9b1SRyder Lee if (!pm_runtime_enabled(dev)) {
1408dd6bb9b1SRyder Lee ret = mt2701_afe_runtime_resume(dev);
1409dd6bb9b1SRyder Lee if (ret)
1410dd6bb9b1SRyder Lee goto err_pm_disable;
1411dd6bb9b1SRyder Lee }
1412dd6bb9b1SRyder Lee pm_runtime_get_sync(dev);
1413dd6bb9b1SRyder Lee
1414f1b5bf07SKuninori Morimoto ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform,
1415f1b5bf07SKuninori Morimoto NULL, 0);
141643a6a7e7SGarlic Tseng if (ret) {
141743a6a7e7SGarlic Tseng dev_warn(dev, "err_platform\n");
141843a6a7e7SGarlic Tseng goto err_platform;
141943a6a7e7SGarlic Tseng }
142043a6a7e7SGarlic Tseng
142110abdc7cSRyder Lee ret = devm_snd_soc_register_component(&pdev->dev,
142210abdc7cSRyder Lee &mt2701_afe_pcm_dai_component,
142310abdc7cSRyder Lee mt2701_afe_pcm_dais,
142410abdc7cSRyder Lee ARRAY_SIZE(mt2701_afe_pcm_dais));
142543a6a7e7SGarlic Tseng if (ret) {
142643a6a7e7SGarlic Tseng dev_warn(dev, "err_dai_component\n");
1427f1b5bf07SKuninori Morimoto goto err_platform;
142843a6a7e7SGarlic Tseng }
142943a6a7e7SGarlic Tseng
143043a6a7e7SGarlic Tseng return 0;
143143a6a7e7SGarlic Tseng
143243a6a7e7SGarlic Tseng err_platform:
1433dd6bb9b1SRyder Lee pm_runtime_put_sync(dev);
143443a6a7e7SGarlic Tseng err_pm_disable:
1435dd6bb9b1SRyder Lee pm_runtime_disable(dev);
143643a6a7e7SGarlic Tseng
143743a6a7e7SGarlic Tseng return ret;
143843a6a7e7SGarlic Tseng }
143943a6a7e7SGarlic Tseng
mt2701_afe_pcm_dev_remove(struct platform_device * pdev)1440b3dff59eSUwe Kleine-König static void mt2701_afe_pcm_dev_remove(struct platform_device *pdev)
144143a6a7e7SGarlic Tseng {
1442dd6bb9b1SRyder Lee pm_runtime_put_sync(&pdev->dev);
144343a6a7e7SGarlic Tseng pm_runtime_disable(&pdev->dev);
144443a6a7e7SGarlic Tseng if (!pm_runtime_status_suspended(&pdev->dev))
144543a6a7e7SGarlic Tseng mt2701_afe_runtime_suspend(&pdev->dev);
144643a6a7e7SGarlic Tseng }
144743a6a7e7SGarlic Tseng
1448bfdc56e5SRyder Lee static const struct mt2701_soc_variants mt2701_soc_v1 = {
1449bfdc56e5SRyder Lee .i2s_num = 4,
1450bfdc56e5SRyder Lee };
1451bfdc56e5SRyder Lee
1452bfdc56e5SRyder Lee static const struct mt2701_soc_variants mt2701_soc_v2 = {
1453bfdc56e5SRyder Lee .has_one_heart_mode = true,
1454bfdc56e5SRyder Lee .i2s_num = 4,
1455bfdc56e5SRyder Lee };
1456bfdc56e5SRyder Lee
145743a6a7e7SGarlic Tseng static const struct of_device_id mt2701_afe_pcm_dt_match[] = {
1458bfdc56e5SRyder Lee { .compatible = "mediatek,mt2701-audio", .data = &mt2701_soc_v1 },
1459bfdc56e5SRyder Lee { .compatible = "mediatek,mt7622-audio", .data = &mt2701_soc_v2 },
146043a6a7e7SGarlic Tseng {},
146143a6a7e7SGarlic Tseng };
146243a6a7e7SGarlic Tseng MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match);
146343a6a7e7SGarlic Tseng
146443a6a7e7SGarlic Tseng static const struct dev_pm_ops mt2701_afe_pm_ops = {
146543a6a7e7SGarlic Tseng SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend,
146643a6a7e7SGarlic Tseng mt2701_afe_runtime_resume, NULL)
146743a6a7e7SGarlic Tseng };
146843a6a7e7SGarlic Tseng
146943a6a7e7SGarlic Tseng static struct platform_driver mt2701_afe_pcm_driver = {
147043a6a7e7SGarlic Tseng .driver = {
147143a6a7e7SGarlic Tseng .name = "mt2701-audio",
147243a6a7e7SGarlic Tseng .of_match_table = mt2701_afe_pcm_dt_match,
147343a6a7e7SGarlic Tseng .pm = &mt2701_afe_pm_ops,
147443a6a7e7SGarlic Tseng },
147543a6a7e7SGarlic Tseng .probe = mt2701_afe_pcm_dev_probe,
1476*130af75bSUwe Kleine-König .remove = mt2701_afe_pcm_dev_remove,
147743a6a7e7SGarlic Tseng };
147843a6a7e7SGarlic Tseng
147943a6a7e7SGarlic Tseng module_platform_driver(mt2701_afe_pcm_driver);
148043a6a7e7SGarlic Tseng
148143a6a7e7SGarlic Tseng MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701");
148243a6a7e7SGarlic Tseng MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
148343a6a7e7SGarlic Tseng MODULE_LICENSE("GPL v2");
1484