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> 2043a6a7e7SGarlic Tseng #include <linux/of.h> 2143a6a7e7SGarlic Tseng #include <linux/of_address.h> 2243a6a7e7SGarlic Tseng #include <linux/pm_runtime.h> 2343a6a7e7SGarlic Tseng #include <sound/soc.h> 2443a6a7e7SGarlic Tseng 2543a6a7e7SGarlic Tseng #include "mt2701-afe-common.h" 2643a6a7e7SGarlic Tseng 2743a6a7e7SGarlic Tseng #include "mt2701-afe-clock-ctrl.h" 2843a6a7e7SGarlic Tseng #include "../common/mtk-afe-platform-driver.h" 2943a6a7e7SGarlic Tseng #include "../common/mtk-afe-fe-dai.h" 3043a6a7e7SGarlic Tseng 3143a6a7e7SGarlic Tseng #define AFE_IRQ_STATUS_BITS 0xff 3243a6a7e7SGarlic Tseng 3343a6a7e7SGarlic Tseng static const struct snd_pcm_hardware mt2701_afe_hardware = { 3443a6a7e7SGarlic Tseng .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED 3543a6a7e7SGarlic Tseng | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID, 3643a6a7e7SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE 3743a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE, 3843a6a7e7SGarlic Tseng .period_bytes_min = 1024, 3943a6a7e7SGarlic Tseng .period_bytes_max = 1024 * 256, 4043a6a7e7SGarlic Tseng .periods_min = 4, 4143a6a7e7SGarlic Tseng .periods_max = 1024, 4243a6a7e7SGarlic Tseng .buffer_bytes_max = 1024 * 1024 * 16, 4343a6a7e7SGarlic Tseng .fifo_size = 0, 4443a6a7e7SGarlic Tseng }; 4543a6a7e7SGarlic Tseng 4643a6a7e7SGarlic Tseng struct mt2701_afe_rate { 4743a6a7e7SGarlic Tseng unsigned int rate; 4843a6a7e7SGarlic Tseng unsigned int regvalue; 4943a6a7e7SGarlic Tseng }; 5043a6a7e7SGarlic Tseng 5143a6a7e7SGarlic Tseng static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = { 5243a6a7e7SGarlic Tseng { .rate = 8000, .regvalue = 0 }, 5343a6a7e7SGarlic Tseng { .rate = 12000, .regvalue = 1 }, 5443a6a7e7SGarlic Tseng { .rate = 16000, .regvalue = 2 }, 5543a6a7e7SGarlic Tseng { .rate = 24000, .regvalue = 3 }, 5643a6a7e7SGarlic Tseng { .rate = 32000, .regvalue = 4 }, 5743a6a7e7SGarlic Tseng { .rate = 48000, .regvalue = 5 }, 5843a6a7e7SGarlic Tseng { .rate = 96000, .regvalue = 6 }, 5943a6a7e7SGarlic Tseng { .rate = 192000, .regvalue = 7 }, 6043a6a7e7SGarlic Tseng { .rate = 384000, .regvalue = 8 }, 6143a6a7e7SGarlic Tseng { .rate = 7350, .regvalue = 16 }, 6243a6a7e7SGarlic Tseng { .rate = 11025, .regvalue = 17 }, 6343a6a7e7SGarlic Tseng { .rate = 14700, .regvalue = 18 }, 6443a6a7e7SGarlic Tseng { .rate = 22050, .regvalue = 19 }, 6543a6a7e7SGarlic Tseng { .rate = 29400, .regvalue = 20 }, 6643a6a7e7SGarlic Tseng { .rate = 44100, .regvalue = 21 }, 6743a6a7e7SGarlic Tseng { .rate = 88200, .regvalue = 22 }, 6843a6a7e7SGarlic Tseng { .rate = 176400, .regvalue = 23 }, 6943a6a7e7SGarlic Tseng { .rate = 352800, .regvalue = 24 }, 7043a6a7e7SGarlic Tseng }; 7143a6a7e7SGarlic Tseng 7225d01dc6SWei Yongjun static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) 7343a6a7e7SGarlic Tseng { 7443a6a7e7SGarlic Tseng int val = num - MT2701_IO_I2S; 7543a6a7e7SGarlic Tseng 7643a6a7e7SGarlic Tseng if (val < 0 || val >= MT2701_I2S_NUM) { 7743a6a7e7SGarlic Tseng dev_err(afe->dev, "%s, num not available, num %d, val %d\n", 7843a6a7e7SGarlic Tseng __func__, num, val); 7943a6a7e7SGarlic Tseng return -EINVAL; 8043a6a7e7SGarlic Tseng } 8143a6a7e7SGarlic Tseng return val; 8243a6a7e7SGarlic Tseng } 8343a6a7e7SGarlic Tseng 8443a6a7e7SGarlic Tseng static int mt2701_afe_i2s_fs(unsigned int sample_rate) 8543a6a7e7SGarlic Tseng { 8643a6a7e7SGarlic Tseng int i; 8743a6a7e7SGarlic Tseng 8843a6a7e7SGarlic Tseng for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++) 8943a6a7e7SGarlic Tseng if (mt2701_afe_i2s_rates[i].rate == sample_rate) 9043a6a7e7SGarlic Tseng return mt2701_afe_i2s_rates[i].regvalue; 9143a6a7e7SGarlic Tseng 9243a6a7e7SGarlic Tseng return -EINVAL; 9343a6a7e7SGarlic Tseng } 9443a6a7e7SGarlic Tseng 9543a6a7e7SGarlic Tseng static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream, 9643a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 9743a6a7e7SGarlic Tseng { 9843a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 9943a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 10043a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 10143a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 10243a6a7e7SGarlic Tseng int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num; 10343a6a7e7SGarlic Tseng int ret = 0; 10443a6a7e7SGarlic Tseng 10543a6a7e7SGarlic Tseng if (i2s_num < 0) 10643a6a7e7SGarlic Tseng return i2s_num; 10743a6a7e7SGarlic Tseng 10843a6a7e7SGarlic Tseng /* enable mclk */ 10943a6a7e7SGarlic Tseng ret = clk_prepare_enable(afe_priv->clocks[clk_num]); 11043a6a7e7SGarlic Tseng if (ret) 11143a6a7e7SGarlic Tseng dev_err(afe->dev, "Failed to enable mclk for I2S: %d\n", 11243a6a7e7SGarlic Tseng i2s_num); 11343a6a7e7SGarlic Tseng 11443a6a7e7SGarlic Tseng return ret; 11543a6a7e7SGarlic Tseng } 11643a6a7e7SGarlic Tseng 11743a6a7e7SGarlic Tseng static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream, 11843a6a7e7SGarlic Tseng struct snd_soc_dai *dai, 11943a6a7e7SGarlic Tseng int dir_invert) 12043a6a7e7SGarlic Tseng { 12143a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 12243a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 12343a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 12443a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 12543a6a7e7SGarlic Tseng struct mt2701_i2s_path *i2s_path; 12643a6a7e7SGarlic Tseng const struct mt2701_i2s_data *i2s_data; 12743a6a7e7SGarlic Tseng int stream_dir = substream->stream; 12843a6a7e7SGarlic Tseng 12943a6a7e7SGarlic Tseng if (i2s_num < 0) 13043a6a7e7SGarlic Tseng return i2s_num; 13143a6a7e7SGarlic Tseng 13243a6a7e7SGarlic Tseng i2s_path = &afe_priv->i2s_path[i2s_num]; 13343a6a7e7SGarlic Tseng 13443a6a7e7SGarlic Tseng if (dir_invert) { 13543a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) 13643a6a7e7SGarlic Tseng stream_dir = SNDRV_PCM_STREAM_CAPTURE; 13743a6a7e7SGarlic Tseng else 13843a6a7e7SGarlic Tseng stream_dir = SNDRV_PCM_STREAM_PLAYBACK; 13943a6a7e7SGarlic Tseng } 14043a6a7e7SGarlic Tseng i2s_data = i2s_path->i2s_data[stream_dir]; 14143a6a7e7SGarlic Tseng 14243a6a7e7SGarlic Tseng i2s_path->on[stream_dir]--; 14343a6a7e7SGarlic Tseng if (i2s_path->on[stream_dir] < 0) { 14443a6a7e7SGarlic Tseng dev_warn(afe->dev, "i2s_path->on: %d, dir: %d\n", 14543a6a7e7SGarlic Tseng i2s_path->on[stream_dir], stream_dir); 14643a6a7e7SGarlic Tseng i2s_path->on[stream_dir] = 0; 14743a6a7e7SGarlic Tseng } 14843a6a7e7SGarlic Tseng if (i2s_path->on[stream_dir]) 14943a6a7e7SGarlic Tseng return 0; 15043a6a7e7SGarlic Tseng 15143a6a7e7SGarlic Tseng /* disable i2s */ 15243a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 15343a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_EN, 0); 15443a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 15543a6a7e7SGarlic Tseng 1 << i2s_data->i2s_pwn_shift, 15643a6a7e7SGarlic Tseng 1 << i2s_data->i2s_pwn_shift); 15743a6a7e7SGarlic Tseng return 0; 15843a6a7e7SGarlic Tseng } 15943a6a7e7SGarlic Tseng 16043a6a7e7SGarlic Tseng static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream, 16143a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 16243a6a7e7SGarlic Tseng { 16343a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 16443a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 16543a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 16643a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 16743a6a7e7SGarlic Tseng struct mt2701_i2s_path *i2s_path; 16843a6a7e7SGarlic Tseng int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num; 16943a6a7e7SGarlic Tseng 17043a6a7e7SGarlic Tseng if (i2s_num < 0) 17143a6a7e7SGarlic Tseng return; 17243a6a7e7SGarlic Tseng 17343a6a7e7SGarlic Tseng i2s_path = &afe_priv->i2s_path[i2s_num]; 17443a6a7e7SGarlic Tseng 17543a6a7e7SGarlic Tseng if (i2s_path->occupied[substream->stream]) 17643a6a7e7SGarlic Tseng i2s_path->occupied[substream->stream] = 0; 17743a6a7e7SGarlic Tseng else 17843a6a7e7SGarlic Tseng goto I2S_UNSTART; 17943a6a7e7SGarlic Tseng 18043a6a7e7SGarlic Tseng mt2701_afe_i2s_path_shutdown(substream, dai, 0); 18143a6a7e7SGarlic Tseng 18243a6a7e7SGarlic Tseng /* need to disable i2s-out path when disable i2s-in */ 18343a6a7e7SGarlic Tseng if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 18443a6a7e7SGarlic Tseng mt2701_afe_i2s_path_shutdown(substream, dai, 1); 18543a6a7e7SGarlic Tseng 18643a6a7e7SGarlic Tseng I2S_UNSTART: 18743a6a7e7SGarlic Tseng /* disable mclk */ 18843a6a7e7SGarlic Tseng clk_disable_unprepare(afe_priv->clocks[clk_num]); 18943a6a7e7SGarlic Tseng } 19043a6a7e7SGarlic Tseng 19143a6a7e7SGarlic Tseng static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream, 19243a6a7e7SGarlic Tseng struct snd_soc_dai *dai, 19343a6a7e7SGarlic Tseng int dir_invert) 19443a6a7e7SGarlic Tseng { 19543a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 19643a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 19743a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 19843a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 19943a6a7e7SGarlic Tseng struct mt2701_i2s_path *i2s_path; 20043a6a7e7SGarlic Tseng const struct mt2701_i2s_data *i2s_data; 20143a6a7e7SGarlic Tseng struct snd_pcm_runtime * const runtime = substream->runtime; 20243a6a7e7SGarlic Tseng int reg, fs, w_len = 1; /* now we support bck 64bits only */ 20343a6a7e7SGarlic Tseng int stream_dir = substream->stream; 20443a6a7e7SGarlic Tseng unsigned int mask = 0, val = 0; 20543a6a7e7SGarlic Tseng 20643a6a7e7SGarlic Tseng if (i2s_num < 0) 20743a6a7e7SGarlic Tseng return i2s_num; 20843a6a7e7SGarlic Tseng 20943a6a7e7SGarlic Tseng i2s_path = &afe_priv->i2s_path[i2s_num]; 21043a6a7e7SGarlic Tseng 21143a6a7e7SGarlic Tseng if (dir_invert) { 21243a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) 21343a6a7e7SGarlic Tseng stream_dir = SNDRV_PCM_STREAM_CAPTURE; 21443a6a7e7SGarlic Tseng else 21543a6a7e7SGarlic Tseng stream_dir = SNDRV_PCM_STREAM_PLAYBACK; 21643a6a7e7SGarlic Tseng } 21743a6a7e7SGarlic Tseng i2s_data = i2s_path->i2s_data[stream_dir]; 21843a6a7e7SGarlic Tseng 21943a6a7e7SGarlic Tseng /* no need to enable if already done */ 22043a6a7e7SGarlic Tseng i2s_path->on[stream_dir]++; 22143a6a7e7SGarlic Tseng 22243a6a7e7SGarlic Tseng if (i2s_path->on[stream_dir] != 1) 22343a6a7e7SGarlic Tseng return 0; 22443a6a7e7SGarlic Tseng 22543a6a7e7SGarlic Tseng fs = mt2701_afe_i2s_fs(runtime->rate); 22643a6a7e7SGarlic Tseng 22743a6a7e7SGarlic Tseng mask = ASYS_I2S_CON_FS | 22843a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */ 22943a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_MODE | 23043a6a7e7SGarlic Tseng ASYS_I2S_CON_WIDE_MODE; 23143a6a7e7SGarlic Tseng 23243a6a7e7SGarlic Tseng val = ASYS_I2S_CON_FS_SET(fs) | 23343a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_MODE | 23443a6a7e7SGarlic Tseng ASYS_I2S_CON_WIDE_MODE_SET(w_len); 23543a6a7e7SGarlic Tseng 23643a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) { 23743a6a7e7SGarlic Tseng mask |= ASYS_I2S_IN_PHASE_FIX; 23843a6a7e7SGarlic Tseng val |= ASYS_I2S_IN_PHASE_FIX; 23943a6a7e7SGarlic Tseng } 24043a6a7e7SGarlic Tseng 24143a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val); 24243a6a7e7SGarlic Tseng 24343a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) 24443a6a7e7SGarlic Tseng reg = ASMO_TIMING_CON1; 24543a6a7e7SGarlic Tseng else 24643a6a7e7SGarlic Tseng reg = ASMI_TIMING_CON1; 24743a6a7e7SGarlic Tseng 24843a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, reg, 24943a6a7e7SGarlic Tseng i2s_data->i2s_asrc_fs_mask 25043a6a7e7SGarlic Tseng << i2s_data->i2s_asrc_fs_shift, 25143a6a7e7SGarlic Tseng fs << i2s_data->i2s_asrc_fs_shift); 25243a6a7e7SGarlic Tseng 25343a6a7e7SGarlic Tseng /* enable i2s */ 25443a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 25543a6a7e7SGarlic Tseng 1 << i2s_data->i2s_pwn_shift, 25643a6a7e7SGarlic Tseng 0 << i2s_data->i2s_pwn_shift); 25743a6a7e7SGarlic Tseng 25843a6a7e7SGarlic Tseng /* reset i2s hw status before enable */ 25943a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 26043a6a7e7SGarlic Tseng ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET); 26143a6a7e7SGarlic Tseng udelay(1); 26243a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 26343a6a7e7SGarlic Tseng ASYS_I2S_CON_RESET, 0); 26443a6a7e7SGarlic Tseng udelay(1); 26543a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 26643a6a7e7SGarlic Tseng ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN); 26743a6a7e7SGarlic Tseng return 0; 26843a6a7e7SGarlic Tseng } 26943a6a7e7SGarlic Tseng 27043a6a7e7SGarlic Tseng static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream, 27143a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 27243a6a7e7SGarlic Tseng { 27343a6a7e7SGarlic Tseng int clk_domain; 27443a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 27543a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 27643a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 27743a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 27843a6a7e7SGarlic Tseng struct mt2701_i2s_path *i2s_path; 27943a6a7e7SGarlic Tseng int mclk_rate; 28043a6a7e7SGarlic Tseng 28143a6a7e7SGarlic Tseng if (i2s_num < 0) 28243a6a7e7SGarlic Tseng return i2s_num; 28343a6a7e7SGarlic Tseng 28443a6a7e7SGarlic Tseng i2s_path = &afe_priv->i2s_path[i2s_num]; 28543a6a7e7SGarlic Tseng mclk_rate = i2s_path->mclk_rate; 28643a6a7e7SGarlic Tseng 28743a6a7e7SGarlic Tseng if (i2s_path->occupied[substream->stream]) 28843a6a7e7SGarlic Tseng return -EBUSY; 28943a6a7e7SGarlic Tseng i2s_path->occupied[substream->stream] = 1; 29043a6a7e7SGarlic Tseng 29143a6a7e7SGarlic Tseng if (MT2701_PLL_DOMAIN_0_RATE % mclk_rate == 0) { 29243a6a7e7SGarlic Tseng clk_domain = 0; 29343a6a7e7SGarlic Tseng } else if (MT2701_PLL_DOMAIN_1_RATE % mclk_rate == 0) { 29443a6a7e7SGarlic Tseng clk_domain = 1; 29543a6a7e7SGarlic Tseng } else { 29643a6a7e7SGarlic Tseng dev_err(dai->dev, "%s() bad mclk rate %d\n", 29743a6a7e7SGarlic Tseng __func__, mclk_rate); 29843a6a7e7SGarlic Tseng return -EINVAL; 29943a6a7e7SGarlic Tseng } 30043a6a7e7SGarlic Tseng mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate); 30143a6a7e7SGarlic Tseng 30243a6a7e7SGarlic Tseng if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 30343a6a7e7SGarlic Tseng mt2701_i2s_path_prepare_enable(substream, dai, 0); 30443a6a7e7SGarlic Tseng } else { 30543a6a7e7SGarlic Tseng /* need to enable i2s-out path when enable i2s-in */ 30643a6a7e7SGarlic Tseng /* prepare for another direction "out" */ 30743a6a7e7SGarlic Tseng mt2701_i2s_path_prepare_enable(substream, dai, 1); 30843a6a7e7SGarlic Tseng /* prepare for "in" */ 30943a6a7e7SGarlic Tseng mt2701_i2s_path_prepare_enable(substream, dai, 0); 31043a6a7e7SGarlic Tseng } 31143a6a7e7SGarlic Tseng 31243a6a7e7SGarlic Tseng return 0; 31343a6a7e7SGarlic Tseng } 31443a6a7e7SGarlic Tseng 31543a6a7e7SGarlic Tseng static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 31643a6a7e7SGarlic Tseng unsigned int freq, int dir) 31743a6a7e7SGarlic Tseng { 31843a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev_get_drvdata(dai->dev); 31943a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 32043a6a7e7SGarlic Tseng int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 32143a6a7e7SGarlic Tseng 32243a6a7e7SGarlic Tseng if (i2s_num < 0) 32343a6a7e7SGarlic Tseng return i2s_num; 32443a6a7e7SGarlic Tseng 32543a6a7e7SGarlic Tseng /* mclk */ 32643a6a7e7SGarlic Tseng if (dir == SND_SOC_CLOCK_IN) { 32743a6a7e7SGarlic Tseng dev_warn(dai->dev, 32843a6a7e7SGarlic Tseng "%s() warning: mt2701 doesn't support mclk input\n", 32943a6a7e7SGarlic Tseng __func__); 33043a6a7e7SGarlic Tseng return -EINVAL; 33143a6a7e7SGarlic Tseng } 33243a6a7e7SGarlic Tseng afe_priv->i2s_path[i2s_num].mclk_rate = freq; 33343a6a7e7SGarlic Tseng return 0; 33443a6a7e7SGarlic Tseng } 33543a6a7e7SGarlic Tseng 3364bdc8d45SGarlic Tseng static int mt2701_btmrg_startup(struct snd_pcm_substream *substream, 3374bdc8d45SGarlic Tseng struct snd_soc_dai *dai) 3384bdc8d45SGarlic Tseng { 3394bdc8d45SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 3404bdc8d45SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 3414bdc8d45SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 3424bdc8d45SGarlic Tseng 3434bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 3444bdc8d45SGarlic Tseng AUDIO_TOP_CON4_PDN_MRGIF, 0); 3454bdc8d45SGarlic Tseng 3464bdc8d45SGarlic Tseng afe_priv->mrg_enable[substream->stream] = 1; 3474bdc8d45SGarlic Tseng return 0; 3484bdc8d45SGarlic Tseng } 3494bdc8d45SGarlic Tseng 3504bdc8d45SGarlic Tseng static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream, 3514bdc8d45SGarlic Tseng struct snd_pcm_hw_params *params, 3524bdc8d45SGarlic Tseng struct snd_soc_dai *dai) 3534bdc8d45SGarlic Tseng { 3544bdc8d45SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 3554bdc8d45SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 3564bdc8d45SGarlic Tseng int stream_fs; 3574bdc8d45SGarlic Tseng u32 val, msk; 3584bdc8d45SGarlic Tseng 3594bdc8d45SGarlic Tseng stream_fs = params_rate(params); 3604bdc8d45SGarlic Tseng 3614bdc8d45SGarlic Tseng if ((stream_fs != 8000) && (stream_fs != 16000)) { 3624bdc8d45SGarlic Tseng dev_err(afe->dev, "%s() btmgr not supprt this stream_fs %d\n", 3634bdc8d45SGarlic Tseng __func__, stream_fs); 3644bdc8d45SGarlic Tseng return -EINVAL; 3654bdc8d45SGarlic Tseng } 3664bdc8d45SGarlic Tseng 3674bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 3684bdc8d45SGarlic Tseng AFE_MRGIF_CON_I2S_MODE_MASK, 3694bdc8d45SGarlic Tseng AFE_MRGIF_CON_I2S_MODE_32K); 3704bdc8d45SGarlic Tseng 3714bdc8d45SGarlic Tseng val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY 3724bdc8d45SGarlic Tseng | AFE_DAIBT_CON0_MRG_USE; 3734bdc8d45SGarlic Tseng msk = val; 3744bdc8d45SGarlic Tseng 3754bdc8d45SGarlic Tseng if (stream_fs == 16000) 3764bdc8d45SGarlic Tseng val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN; 3774bdc8d45SGarlic Tseng 3784bdc8d45SGarlic Tseng msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN; 3794bdc8d45SGarlic Tseng 3804bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val); 3814bdc8d45SGarlic Tseng 3824bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, 3834bdc8d45SGarlic Tseng AFE_DAIBT_CON0_DAIBT_EN, 3844bdc8d45SGarlic Tseng AFE_DAIBT_CON0_DAIBT_EN); 3854bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 3864bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_I2S_EN, 3874bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_I2S_EN); 3884bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 3894bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_EN, 3904bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_EN); 3914bdc8d45SGarlic Tseng return 0; 3924bdc8d45SGarlic Tseng } 3934bdc8d45SGarlic Tseng 3944bdc8d45SGarlic Tseng static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream, 3954bdc8d45SGarlic Tseng struct snd_soc_dai *dai) 3964bdc8d45SGarlic Tseng { 3974bdc8d45SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 3984bdc8d45SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 3994bdc8d45SGarlic Tseng struct mt2701_afe_private *afe_priv = afe->platform_priv; 4004bdc8d45SGarlic Tseng 4014bdc8d45SGarlic Tseng /* if the other direction stream is not occupied */ 4024bdc8d45SGarlic Tseng if (!afe_priv->mrg_enable[!substream->stream]) { 4034bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, 4044bdc8d45SGarlic Tseng AFE_DAIBT_CON0_DAIBT_EN, 0); 4054bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 4064bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_EN, 0); 4074bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 4084bdc8d45SGarlic Tseng AFE_MRGIF_CON_MRG_I2S_EN, 0); 4094bdc8d45SGarlic Tseng regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 4104bdc8d45SGarlic Tseng AUDIO_TOP_CON4_PDN_MRGIF, 4114bdc8d45SGarlic Tseng AUDIO_TOP_CON4_PDN_MRGIF); 4124bdc8d45SGarlic Tseng } 4134bdc8d45SGarlic Tseng afe_priv->mrg_enable[substream->stream] = 0; 4144bdc8d45SGarlic Tseng } 4154bdc8d45SGarlic Tseng 41643a6a7e7SGarlic Tseng static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream, 41743a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 41843a6a7e7SGarlic Tseng { 41943a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 42043a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 42143a6a7e7SGarlic Tseng int stream_dir = substream->stream; 42243a6a7e7SGarlic Tseng int memif_num = rtd->cpu_dai->id; 42343a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif_tmp; 42443a6a7e7SGarlic Tseng 42543a6a7e7SGarlic Tseng /* can't run single DL & DLM at the same time */ 42643a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) { 42743a6a7e7SGarlic Tseng memif_tmp = &afe->memif[MT2701_MEMIF_DLM]; 42843a6a7e7SGarlic Tseng if (memif_tmp->substream) { 42943a6a7e7SGarlic Tseng dev_warn(afe->dev, "%s memif is not available, stream_dir %d, memif_num %d\n", 43043a6a7e7SGarlic Tseng __func__, stream_dir, memif_num); 43143a6a7e7SGarlic Tseng return -EBUSY; 43243a6a7e7SGarlic Tseng } 43343a6a7e7SGarlic Tseng } 43443a6a7e7SGarlic Tseng return mtk_afe_fe_startup(substream, dai); 43543a6a7e7SGarlic Tseng } 43643a6a7e7SGarlic Tseng 43743a6a7e7SGarlic Tseng static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream, 43843a6a7e7SGarlic Tseng struct snd_pcm_hw_params *params, 43943a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 44043a6a7e7SGarlic Tseng { 44143a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 44243a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 44343a6a7e7SGarlic Tseng int stream_dir = substream->stream; 44443a6a7e7SGarlic Tseng 44543a6a7e7SGarlic Tseng /* single DL use PAIR_INTERLEAVE */ 44643a6a7e7SGarlic Tseng if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) { 44743a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, 44843a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE, 44943a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_MASK, 45043a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE); 45143a6a7e7SGarlic Tseng } 45243a6a7e7SGarlic Tseng return mtk_afe_fe_hw_params(substream, params, dai); 45343a6a7e7SGarlic Tseng } 45443a6a7e7SGarlic Tseng 45543a6a7e7SGarlic Tseng static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream, 45643a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 45743a6a7e7SGarlic Tseng { 45843a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 45943a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 46043a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif_tmp; 46143a6a7e7SGarlic Tseng const struct mtk_base_memif_data *memif_data; 46243a6a7e7SGarlic Tseng int i; 46343a6a7e7SGarlic Tseng 46443a6a7e7SGarlic Tseng for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) { 46543a6a7e7SGarlic Tseng memif_tmp = &afe->memif[i]; 46643a6a7e7SGarlic Tseng if (memif_tmp->substream) 46743a6a7e7SGarlic Tseng return -EBUSY; 46843a6a7e7SGarlic Tseng } 46943a6a7e7SGarlic Tseng 47043a6a7e7SGarlic Tseng /* enable agent for all signal DL (due to hw design) */ 47143a6a7e7SGarlic Tseng for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) { 47243a6a7e7SGarlic Tseng memif_data = afe->memif[i].data; 47343a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, 47443a6a7e7SGarlic Tseng memif_data->agent_disable_reg, 47543a6a7e7SGarlic Tseng 1 << memif_data->agent_disable_shift, 47643a6a7e7SGarlic Tseng 0 << memif_data->agent_disable_shift); 47743a6a7e7SGarlic Tseng } 47843a6a7e7SGarlic Tseng 47943a6a7e7SGarlic Tseng return mtk_afe_fe_startup(substream, dai); 48043a6a7e7SGarlic Tseng } 48143a6a7e7SGarlic Tseng 48243a6a7e7SGarlic Tseng static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream, 48343a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 48443a6a7e7SGarlic Tseng { 48543a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 48643a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 48743a6a7e7SGarlic Tseng const struct mtk_base_memif_data *memif_data; 48843a6a7e7SGarlic Tseng int i; 48943a6a7e7SGarlic Tseng 49043a6a7e7SGarlic Tseng for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) { 49143a6a7e7SGarlic Tseng memif_data = afe->memif[i].data; 49243a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, 49343a6a7e7SGarlic Tseng memif_data->agent_disable_reg, 49443a6a7e7SGarlic Tseng 1 << memif_data->agent_disable_shift, 49543a6a7e7SGarlic Tseng 1 << memif_data->agent_disable_shift); 49643a6a7e7SGarlic Tseng } 49743a6a7e7SGarlic Tseng return mtk_afe_fe_shutdown(substream, dai); 49843a6a7e7SGarlic Tseng } 49943a6a7e7SGarlic Tseng 50043a6a7e7SGarlic Tseng static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream, 50143a6a7e7SGarlic Tseng struct snd_pcm_hw_params *params, 50243a6a7e7SGarlic Tseng struct snd_soc_dai *dai) 50343a6a7e7SGarlic Tseng { 50443a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 50543a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 50643a6a7e7SGarlic Tseng int channels = params_channels(params); 50743a6a7e7SGarlic Tseng 50843a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, 50943a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE, 51043a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_MASK, 51143a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE); 51243a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, 51343a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE, 51443a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK, 51543a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_32BYTES); 51643a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, 51743a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE, 51843a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK, 51943a6a7e7SGarlic Tseng AFE_MEMIF_PBUF_SIZE_DLM_CH(channels)); 52043a6a7e7SGarlic Tseng 52143a6a7e7SGarlic Tseng return mtk_afe_fe_hw_params(substream, params, dai); 52243a6a7e7SGarlic Tseng } 52343a6a7e7SGarlic Tseng 52443a6a7e7SGarlic Tseng static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream, 52543a6a7e7SGarlic Tseng int cmd, struct snd_soc_dai *dai) 52643a6a7e7SGarlic Tseng { 52743a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 52843a6a7e7SGarlic Tseng struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); 52943a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1]; 53043a6a7e7SGarlic Tseng 53143a6a7e7SGarlic Tseng switch (cmd) { 53243a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_START: 53343a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_RESUME: 53443a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg, 53543a6a7e7SGarlic Tseng 1 << memif_tmp->data->enable_shift, 53643a6a7e7SGarlic Tseng 1 << memif_tmp->data->enable_shift); 53743a6a7e7SGarlic Tseng mtk_afe_fe_trigger(substream, cmd, dai); 53843a6a7e7SGarlic Tseng return 0; 53943a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_STOP: 54043a6a7e7SGarlic Tseng case SNDRV_PCM_TRIGGER_SUSPEND: 54143a6a7e7SGarlic Tseng mtk_afe_fe_trigger(substream, cmd, dai); 54243a6a7e7SGarlic Tseng regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg, 54343a6a7e7SGarlic Tseng 1 << memif_tmp->data->enable_shift, 0); 54443a6a7e7SGarlic Tseng 54543a6a7e7SGarlic Tseng return 0; 54643a6a7e7SGarlic Tseng default: 54743a6a7e7SGarlic Tseng return -EINVAL; 54843a6a7e7SGarlic Tseng } 54943a6a7e7SGarlic Tseng } 55043a6a7e7SGarlic Tseng 55143a6a7e7SGarlic Tseng static int mt2701_memif_fs(struct snd_pcm_substream *substream, 55243a6a7e7SGarlic Tseng unsigned int rate) 55343a6a7e7SGarlic Tseng { 55443a6a7e7SGarlic Tseng struct snd_soc_pcm_runtime *rtd = substream->private_data; 55543a6a7e7SGarlic Tseng int fs; 55643a6a7e7SGarlic Tseng 55743a6a7e7SGarlic Tseng if (rtd->cpu_dai->id != MT2701_MEMIF_ULBT) 55843a6a7e7SGarlic Tseng fs = mt2701_afe_i2s_fs(rate); 55943a6a7e7SGarlic Tseng else 56043a6a7e7SGarlic Tseng fs = (rate == 16000 ? 1 : 0); 56143a6a7e7SGarlic Tseng return fs; 56243a6a7e7SGarlic Tseng } 56343a6a7e7SGarlic Tseng 56443a6a7e7SGarlic Tseng static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) 56543a6a7e7SGarlic Tseng { 56643a6a7e7SGarlic Tseng return mt2701_afe_i2s_fs(rate); 56743a6a7e7SGarlic Tseng } 56843a6a7e7SGarlic Tseng 56943a6a7e7SGarlic Tseng /* FE DAIs */ 57043a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = { 57143a6a7e7SGarlic Tseng .startup = mt2701_simple_fe_startup, 57243a6a7e7SGarlic Tseng .shutdown = mtk_afe_fe_shutdown, 57343a6a7e7SGarlic Tseng .hw_params = mt2701_simple_fe_hw_params, 57443a6a7e7SGarlic Tseng .hw_free = mtk_afe_fe_hw_free, 57543a6a7e7SGarlic Tseng .prepare = mtk_afe_fe_prepare, 57643a6a7e7SGarlic Tseng .trigger = mtk_afe_fe_trigger, 57743a6a7e7SGarlic Tseng 57843a6a7e7SGarlic Tseng }; 57943a6a7e7SGarlic Tseng 58043a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = { 58143a6a7e7SGarlic Tseng .startup = mt2701_dlm_fe_startup, 58243a6a7e7SGarlic Tseng .shutdown = mt2701_dlm_fe_shutdown, 58343a6a7e7SGarlic Tseng .hw_params = mt2701_dlm_fe_hw_params, 58443a6a7e7SGarlic Tseng .hw_free = mtk_afe_fe_hw_free, 58543a6a7e7SGarlic Tseng .prepare = mtk_afe_fe_prepare, 58643a6a7e7SGarlic Tseng .trigger = mt2701_dlm_fe_trigger, 58743a6a7e7SGarlic Tseng }; 58843a6a7e7SGarlic Tseng 58943a6a7e7SGarlic Tseng /* I2S BE DAIs */ 59043a6a7e7SGarlic Tseng static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = { 59143a6a7e7SGarlic Tseng .startup = mt2701_afe_i2s_startup, 59243a6a7e7SGarlic Tseng .shutdown = mt2701_afe_i2s_shutdown, 59343a6a7e7SGarlic Tseng .prepare = mt2701_afe_i2s_prepare, 59443a6a7e7SGarlic Tseng .set_sysclk = mt2701_afe_i2s_set_sysclk, 59543a6a7e7SGarlic Tseng }; 59643a6a7e7SGarlic Tseng 5974bdc8d45SGarlic Tseng /* MRG BE DAIs */ 598549acff9SGustavo A. R. Silva static const struct snd_soc_dai_ops mt2701_btmrg_ops = { 5994bdc8d45SGarlic Tseng .startup = mt2701_btmrg_startup, 6004bdc8d45SGarlic Tseng .shutdown = mt2701_btmrg_shutdown, 6014bdc8d45SGarlic Tseng .hw_params = mt2701_btmrg_hw_params, 6024bdc8d45SGarlic Tseng }; 6034bdc8d45SGarlic Tseng 60443a6a7e7SGarlic Tseng static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { 60543a6a7e7SGarlic Tseng /* FE DAIs: memory intefaces to CPU */ 60643a6a7e7SGarlic Tseng { 6078625c1dbSRyder Lee .name = "PCMO0", 6088625c1dbSRyder Lee .id = MT2701_MEMIF_DL1, 6098625c1dbSRyder Lee .suspend = mtk_afe_dai_suspend, 6108625c1dbSRyder Lee .resume = mtk_afe_dai_resume, 6118625c1dbSRyder Lee .playback = { 6128625c1dbSRyder Lee .stream_name = "DL1", 6138625c1dbSRyder Lee .channels_min = 1, 6148625c1dbSRyder Lee .channels_max = 2, 6158625c1dbSRyder Lee .rates = SNDRV_PCM_RATE_8000_192000, 6168625c1dbSRyder Lee .formats = (SNDRV_PCM_FMTBIT_S16_LE 6178625c1dbSRyder Lee | SNDRV_PCM_FMTBIT_S24_LE 6188625c1dbSRyder Lee | SNDRV_PCM_FMTBIT_S32_LE) 6198625c1dbSRyder Lee }, 6208625c1dbSRyder Lee .ops = &mt2701_single_memif_dai_ops, 6218625c1dbSRyder Lee }, 6228625c1dbSRyder Lee { 62343a6a7e7SGarlic Tseng .name = "PCM_multi", 62443a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DLM, 62543a6a7e7SGarlic Tseng .suspend = mtk_afe_dai_suspend, 62643a6a7e7SGarlic Tseng .resume = mtk_afe_dai_resume, 62743a6a7e7SGarlic Tseng .playback = { 62843a6a7e7SGarlic Tseng .stream_name = "DLM", 62943a6a7e7SGarlic Tseng .channels_min = 1, 63043a6a7e7SGarlic Tseng .channels_max = 8, 63143a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 63243a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 63343a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 63443a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 63543a6a7e7SGarlic Tseng 63643a6a7e7SGarlic Tseng }, 63743a6a7e7SGarlic Tseng .ops = &mt2701_dlm_memif_dai_ops, 63843a6a7e7SGarlic Tseng }, 63943a6a7e7SGarlic Tseng { 64043a6a7e7SGarlic Tseng .name = "PCM0", 64143a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL1, 64243a6a7e7SGarlic Tseng .suspend = mtk_afe_dai_suspend, 64343a6a7e7SGarlic Tseng .resume = mtk_afe_dai_resume, 64443a6a7e7SGarlic Tseng .capture = { 64543a6a7e7SGarlic Tseng .stream_name = "UL1", 64643a6a7e7SGarlic Tseng .channels_min = 1, 64743a6a7e7SGarlic Tseng .channels_max = 2, 64843a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_48000, 64943a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 65043a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 65143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 65243a6a7e7SGarlic Tseng }, 65343a6a7e7SGarlic Tseng .ops = &mt2701_single_memif_dai_ops, 65443a6a7e7SGarlic Tseng }, 65543a6a7e7SGarlic Tseng { 65643a6a7e7SGarlic Tseng .name = "PCM1", 65743a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL2, 65843a6a7e7SGarlic Tseng .suspend = mtk_afe_dai_suspend, 65943a6a7e7SGarlic Tseng .resume = mtk_afe_dai_resume, 66043a6a7e7SGarlic Tseng .capture = { 66143a6a7e7SGarlic Tseng .stream_name = "UL2", 66243a6a7e7SGarlic Tseng .channels_min = 1, 66343a6a7e7SGarlic Tseng .channels_max = 2, 66443a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 66543a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 66643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 66743a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 66843a6a7e7SGarlic Tseng 66943a6a7e7SGarlic Tseng }, 67043a6a7e7SGarlic Tseng .ops = &mt2701_single_memif_dai_ops, 67143a6a7e7SGarlic Tseng }, 6724bdc8d45SGarlic Tseng { 6734bdc8d45SGarlic Tseng .name = "PCM_BT_DL", 6744bdc8d45SGarlic Tseng .id = MT2701_MEMIF_DLBT, 6754bdc8d45SGarlic Tseng .suspend = mtk_afe_dai_suspend, 6764bdc8d45SGarlic Tseng .resume = mtk_afe_dai_resume, 6774bdc8d45SGarlic Tseng .playback = { 6784bdc8d45SGarlic Tseng .stream_name = "DLBT", 6794bdc8d45SGarlic Tseng .channels_min = 1, 6804bdc8d45SGarlic Tseng .channels_max = 1, 6814bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000 6824bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000), 6834bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE, 6844bdc8d45SGarlic Tseng }, 6854bdc8d45SGarlic Tseng .ops = &mt2701_single_memif_dai_ops, 6864bdc8d45SGarlic Tseng }, 6874bdc8d45SGarlic Tseng { 6884bdc8d45SGarlic Tseng .name = "PCM_BT_UL", 6894bdc8d45SGarlic Tseng .id = MT2701_MEMIF_ULBT, 6904bdc8d45SGarlic Tseng .suspend = mtk_afe_dai_suspend, 6914bdc8d45SGarlic Tseng .resume = mtk_afe_dai_resume, 6924bdc8d45SGarlic Tseng .capture = { 6934bdc8d45SGarlic Tseng .stream_name = "ULBT", 6944bdc8d45SGarlic Tseng .channels_min = 1, 6954bdc8d45SGarlic Tseng .channels_max = 1, 6964bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000 6974bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000), 6984bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE, 6994bdc8d45SGarlic Tseng }, 7004bdc8d45SGarlic Tseng .ops = &mt2701_single_memif_dai_ops, 7014bdc8d45SGarlic Tseng }, 70243a6a7e7SGarlic Tseng /* BE DAIs */ 70343a6a7e7SGarlic Tseng { 70443a6a7e7SGarlic Tseng .name = "I2S0", 70543a6a7e7SGarlic Tseng .id = MT2701_IO_I2S, 70643a6a7e7SGarlic Tseng .playback = { 70743a6a7e7SGarlic Tseng .stream_name = "I2S0 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 }, 71643a6a7e7SGarlic Tseng .capture = { 71743a6a7e7SGarlic Tseng .stream_name = "I2S0 Capture", 71843a6a7e7SGarlic Tseng .channels_min = 1, 71943a6a7e7SGarlic Tseng .channels_max = 2, 72043a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 72143a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 72243a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 72343a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 72443a6a7e7SGarlic Tseng 72543a6a7e7SGarlic Tseng }, 72643a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops, 72743a6a7e7SGarlic Tseng .symmetric_rates = 1, 72843a6a7e7SGarlic Tseng }, 72943a6a7e7SGarlic Tseng { 73043a6a7e7SGarlic Tseng .name = "I2S1", 73143a6a7e7SGarlic Tseng .id = MT2701_IO_2ND_I2S, 73243a6a7e7SGarlic Tseng .playback = { 73343a6a7e7SGarlic Tseng .stream_name = "I2S1 Playback", 73443a6a7e7SGarlic Tseng .channels_min = 1, 73543a6a7e7SGarlic Tseng .channels_max = 2, 73643a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 73743a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 73843a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 73943a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 74043a6a7e7SGarlic Tseng }, 74143a6a7e7SGarlic Tseng .capture = { 74243a6a7e7SGarlic Tseng .stream_name = "I2S1 Capture", 74343a6a7e7SGarlic Tseng .channels_min = 1, 74443a6a7e7SGarlic Tseng .channels_max = 2, 74543a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 74643a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 74743a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 74843a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 74943a6a7e7SGarlic Tseng }, 75043a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops, 75143a6a7e7SGarlic Tseng .symmetric_rates = 1, 75243a6a7e7SGarlic Tseng }, 75343a6a7e7SGarlic Tseng { 75443a6a7e7SGarlic Tseng .name = "I2S2", 75543a6a7e7SGarlic Tseng .id = MT2701_IO_3RD_I2S, 75643a6a7e7SGarlic Tseng .playback = { 75743a6a7e7SGarlic Tseng .stream_name = "I2S2 Playback", 75843a6a7e7SGarlic Tseng .channels_min = 1, 75943a6a7e7SGarlic Tseng .channels_max = 2, 76043a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 76143a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 76243a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 76343a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 76443a6a7e7SGarlic Tseng }, 76543a6a7e7SGarlic Tseng .capture = { 76643a6a7e7SGarlic Tseng .stream_name = "I2S2 Capture", 76743a6a7e7SGarlic Tseng .channels_min = 1, 76843a6a7e7SGarlic Tseng .channels_max = 2, 76943a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 77043a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 77143a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 77243a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 77343a6a7e7SGarlic Tseng }, 77443a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops, 77543a6a7e7SGarlic Tseng .symmetric_rates = 1, 77643a6a7e7SGarlic Tseng }, 77743a6a7e7SGarlic Tseng { 77843a6a7e7SGarlic Tseng .name = "I2S3", 77943a6a7e7SGarlic Tseng .id = MT2701_IO_4TH_I2S, 78043a6a7e7SGarlic Tseng .playback = { 78143a6a7e7SGarlic Tseng .stream_name = "I2S3 Playback", 78243a6a7e7SGarlic Tseng .channels_min = 1, 78343a6a7e7SGarlic Tseng .channels_max = 2, 78443a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 78543a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 78643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 78743a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 78843a6a7e7SGarlic Tseng }, 78943a6a7e7SGarlic Tseng .capture = { 79043a6a7e7SGarlic Tseng .stream_name = "I2S3 Capture", 79143a6a7e7SGarlic Tseng .channels_min = 1, 79243a6a7e7SGarlic Tseng .channels_max = 2, 79343a6a7e7SGarlic Tseng .rates = SNDRV_PCM_RATE_8000_192000, 79443a6a7e7SGarlic Tseng .formats = (SNDRV_PCM_FMTBIT_S16_LE 79543a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S24_LE 79643a6a7e7SGarlic Tseng | SNDRV_PCM_FMTBIT_S32_LE) 79743a6a7e7SGarlic Tseng }, 79843a6a7e7SGarlic Tseng .ops = &mt2701_afe_i2s_ops, 79943a6a7e7SGarlic Tseng .symmetric_rates = 1, 80043a6a7e7SGarlic Tseng }, 8014bdc8d45SGarlic Tseng { 8024bdc8d45SGarlic Tseng .name = "MRG BT", 8034bdc8d45SGarlic Tseng .id = MT2701_IO_MRG, 8044bdc8d45SGarlic Tseng .playback = { 8054bdc8d45SGarlic Tseng .stream_name = "BT Playback", 8064bdc8d45SGarlic Tseng .channels_min = 1, 8074bdc8d45SGarlic Tseng .channels_max = 1, 8084bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000 8094bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000), 8104bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE, 8114bdc8d45SGarlic Tseng }, 8124bdc8d45SGarlic Tseng .capture = { 8134bdc8d45SGarlic Tseng .stream_name = "BT Capture", 8144bdc8d45SGarlic Tseng .channels_min = 1, 8154bdc8d45SGarlic Tseng .channels_max = 1, 8164bdc8d45SGarlic Tseng .rates = (SNDRV_PCM_RATE_8000 8174bdc8d45SGarlic Tseng | SNDRV_PCM_RATE_16000), 8184bdc8d45SGarlic Tseng .formats = SNDRV_PCM_FMTBIT_S16_LE, 8194bdc8d45SGarlic Tseng }, 8204bdc8d45SGarlic Tseng .ops = &mt2701_btmrg_ops, 8214bdc8d45SGarlic Tseng .symmetric_rates = 1, 8224bdc8d45SGarlic Tseng } 82343a6a7e7SGarlic Tseng }; 82443a6a7e7SGarlic Tseng 82543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = { 82643a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0), 82743a6a7e7SGarlic Tseng }; 82843a6a7e7SGarlic Tseng 82943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o01_mix[] = { 83043a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0), 83143a6a7e7SGarlic Tseng }; 83243a6a7e7SGarlic Tseng 83343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o02_mix[] = { 83443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0), 83543a6a7e7SGarlic Tseng }; 83643a6a7e7SGarlic Tseng 83743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o03_mix[] = { 83843a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0), 83943a6a7e7SGarlic Tseng }; 84043a6a7e7SGarlic Tseng 84143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o14_mix[] = { 84243a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0), 84343a6a7e7SGarlic Tseng }; 84443a6a7e7SGarlic Tseng 84543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o15_mix[] = { 84643a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0), 84743a6a7e7SGarlic Tseng }; 84843a6a7e7SGarlic Tseng 84943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o16_mix[] = { 85043a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0), 85143a6a7e7SGarlic Tseng }; 85243a6a7e7SGarlic Tseng 85343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o17_mix[] = { 85443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0), 85543a6a7e7SGarlic Tseng }; 85643a6a7e7SGarlic Tseng 85743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o18_mix[] = { 85843a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0), 85943a6a7e7SGarlic Tseng }; 86043a6a7e7SGarlic Tseng 86143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o19_mix[] = { 86243a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0), 86343a6a7e7SGarlic Tseng }; 86443a6a7e7SGarlic Tseng 86543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o20_mix[] = { 86643a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0), 86743a6a7e7SGarlic Tseng }; 86843a6a7e7SGarlic Tseng 86943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o21_mix[] = { 87043a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0), 87143a6a7e7SGarlic Tseng }; 87243a6a7e7SGarlic Tseng 87343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = { 87443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0), 87543a6a7e7SGarlic Tseng }; 87643a6a7e7SGarlic Tseng 87743a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o23_mix[] = { 87843a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I20 Switch", AFE_CONN23, 20, 1, 0), 87943a6a7e7SGarlic Tseng }; 88043a6a7e7SGarlic Tseng 88143a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o24_mix[] = { 88243a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I21 Switch", AFE_CONN24, 21, 1, 0), 88343a6a7e7SGarlic Tseng }; 88443a6a7e7SGarlic Tseng 88543a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = { 88643a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0), 88743a6a7e7SGarlic Tseng }; 88843a6a7e7SGarlic Tseng 88943a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_i02_mix[] = { 89043a6a7e7SGarlic Tseng SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0), 89143a6a7e7SGarlic Tseng }; 89243a6a7e7SGarlic Tseng 89343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = { 89443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch", 89543a6a7e7SGarlic Tseng ASYS_I2SO1_CON, 26, 1, 0), 89643a6a7e7SGarlic Tseng }; 89743a6a7e7SGarlic Tseng 89843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = { 89943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch", 90043a6a7e7SGarlic Tseng ASYS_I2SO2_CON, 26, 1, 0), 90143a6a7e7SGarlic Tseng }; 90243a6a7e7SGarlic Tseng 90343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = { 90443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch", 90543a6a7e7SGarlic Tseng PWR2_TOP_CON, 17, 1, 0), 90643a6a7e7SGarlic Tseng }; 90743a6a7e7SGarlic Tseng 90843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = { 90943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch", 91043a6a7e7SGarlic Tseng PWR2_TOP_CON, 18, 1, 0), 91143a6a7e7SGarlic Tseng }; 91243a6a7e7SGarlic Tseng 91343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = { 91443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S4 Out Switch", 91543a6a7e7SGarlic Tseng PWR2_TOP_CON, 19, 1, 0), 91643a6a7e7SGarlic Tseng }; 91743a6a7e7SGarlic Tseng 91843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc0[] = { 91943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Asrc0 out Switch", AUDIO_TOP_CON4, 14, 1, 92043a6a7e7SGarlic Tseng 1), 92143a6a7e7SGarlic Tseng }; 92243a6a7e7SGarlic Tseng 92343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc1[] = { 92443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Asrc1 out Switch", AUDIO_TOP_CON4, 15, 1, 92543a6a7e7SGarlic Tseng 1), 92643a6a7e7SGarlic Tseng }; 92743a6a7e7SGarlic Tseng 92843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc2[] = { 92943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Asrc2 out Switch", PWR2_TOP_CON, 6, 1, 93043a6a7e7SGarlic Tseng 1), 93143a6a7e7SGarlic Tseng }; 93243a6a7e7SGarlic Tseng 93343a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc3[] = { 93443a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Asrc3 out Switch", PWR2_TOP_CON, 7, 1, 93543a6a7e7SGarlic Tseng 1), 93643a6a7e7SGarlic Tseng }; 93743a6a7e7SGarlic Tseng 93843a6a7e7SGarlic Tseng static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc4[] = { 93943a6a7e7SGarlic Tseng SOC_DAPM_SINGLE_AUTODISABLE("Asrc4 out Switch", PWR2_TOP_CON, 8, 1, 94043a6a7e7SGarlic Tseng 1), 94143a6a7e7SGarlic Tseng }; 94243a6a7e7SGarlic Tseng 94343a6a7e7SGarlic Tseng static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { 94443a6a7e7SGarlic Tseng /* inter-connections */ 94543a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), 94643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0), 94743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix, 94843a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_i02_mix)), 94943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0), 95043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0), 95143a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0), 95243a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0), 95343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0), 95443a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0), 95543a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0), 95643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0), 95743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0), 95843a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0), 95943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0), 96043a6a7e7SGarlic Tseng 96143a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix, 96243a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o00_mix)), 96343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix, 96443a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o01_mix)), 96543a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix, 96643a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o02_mix)), 96743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix, 96843a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o03_mix)), 96943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix, 97043a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o14_mix)), 97143a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix, 97243a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o15_mix)), 97343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix, 97443a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o16_mix)), 97543a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix, 97643a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o17_mix)), 97743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix, 97843a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o18_mix)), 97943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix, 98043a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o19_mix)), 98143a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix, 98243a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o20_mix)), 98343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix, 98443a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o21_mix)), 98543a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix, 98643a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o22_mix)), 98743a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix, 98843a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_o31_mix)), 98943a6a7e7SGarlic Tseng 99043a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0, 99143a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s0, 99243a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)), 99343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0, 99443a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s1, 99543a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)), 99643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0, 99743a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s2, 99843a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)), 99943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0, 100043a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_i2s3, 100143a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)), 100243a6a7e7SGarlic Tseng 100343a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("ASRC_O0", SND_SOC_NOPM, 0, 0, 100443a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_asrc0, 100543a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc0)), 100643a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("ASRC_O1", SND_SOC_NOPM, 0, 0, 100743a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_asrc1, 100843a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc1)), 100943a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("ASRC_O2", SND_SOC_NOPM, 0, 0, 101043a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_asrc2, 101143a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc2)), 101243a6a7e7SGarlic Tseng SND_SOC_DAPM_MIXER("ASRC_O3", SND_SOC_NOPM, 0, 0, 101343a6a7e7SGarlic Tseng mt2701_afe_multi_ch_out_asrc3, 101443a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc3)), 101543a6a7e7SGarlic Tseng }; 101643a6a7e7SGarlic Tseng 101743a6a7e7SGarlic Tseng static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { 101843a6a7e7SGarlic Tseng {"I12", NULL, "DL1"}, 101943a6a7e7SGarlic Tseng {"I13", NULL, "DL1"}, 102043a6a7e7SGarlic Tseng {"I35", NULL, "DLBT"}, 102143a6a7e7SGarlic Tseng 102243a6a7e7SGarlic Tseng {"I2S0 Playback", NULL, "O15"}, 102343a6a7e7SGarlic Tseng {"I2S0 Playback", NULL, "O16"}, 102443a6a7e7SGarlic Tseng 102543a6a7e7SGarlic Tseng {"I2S1 Playback", NULL, "O17"}, 102643a6a7e7SGarlic Tseng {"I2S1 Playback", NULL, "O18"}, 102743a6a7e7SGarlic Tseng {"I2S2 Playback", NULL, "O19"}, 102843a6a7e7SGarlic Tseng {"I2S2 Playback", NULL, "O20"}, 102943a6a7e7SGarlic Tseng {"I2S3 Playback", NULL, "O21"}, 103043a6a7e7SGarlic Tseng {"I2S3 Playback", NULL, "O22"}, 103143a6a7e7SGarlic Tseng {"BT Playback", NULL, "O31"}, 103243a6a7e7SGarlic Tseng 103343a6a7e7SGarlic Tseng {"UL1", NULL, "O00"}, 103443a6a7e7SGarlic Tseng {"UL1", NULL, "O01"}, 103543a6a7e7SGarlic Tseng {"UL2", NULL, "O02"}, 103643a6a7e7SGarlic Tseng {"UL2", NULL, "O03"}, 103743a6a7e7SGarlic Tseng {"ULBT", NULL, "O14"}, 103843a6a7e7SGarlic Tseng 103943a6a7e7SGarlic Tseng {"I00", NULL, "I2S0 Capture"}, 104043a6a7e7SGarlic Tseng {"I01", NULL, "I2S0 Capture"}, 104143a6a7e7SGarlic Tseng 104243a6a7e7SGarlic Tseng {"I02", NULL, "I2S1 Capture"}, 104343a6a7e7SGarlic Tseng {"I03", NULL, "I2S1 Capture"}, 104443a6a7e7SGarlic Tseng /* I02,03 link to UL2, also need to open I2S0 */ 104543a6a7e7SGarlic Tseng {"I02", "I2S0 Switch", "I2S0 Capture"}, 104643a6a7e7SGarlic Tseng 104743a6a7e7SGarlic Tseng {"I26", NULL, "BT Capture"}, 104843a6a7e7SGarlic Tseng 104943a6a7e7SGarlic Tseng {"ASRC_O0", "Asrc0 out Switch", "DLM"}, 105043a6a7e7SGarlic Tseng {"ASRC_O1", "Asrc1 out Switch", "DLM"}, 105143a6a7e7SGarlic Tseng {"ASRC_O2", "Asrc2 out Switch", "DLM"}, 105243a6a7e7SGarlic Tseng {"ASRC_O3", "Asrc3 out Switch", "DLM"}, 105343a6a7e7SGarlic Tseng 105443a6a7e7SGarlic Tseng {"I12I13", "Multich I2S0 Out Switch", "ASRC_O0"}, 105543a6a7e7SGarlic Tseng {"I14I15", "Multich I2S1 Out Switch", "ASRC_O1"}, 105643a6a7e7SGarlic Tseng {"I16I17", "Multich I2S2 Out Switch", "ASRC_O2"}, 105743a6a7e7SGarlic Tseng {"I18I19", "Multich I2S3 Out Switch", "ASRC_O3"}, 105843a6a7e7SGarlic Tseng 105943a6a7e7SGarlic Tseng { "I12", NULL, "I12I13" }, 106043a6a7e7SGarlic Tseng { "I13", NULL, "I12I13" }, 106143a6a7e7SGarlic Tseng { "I14", NULL, "I14I15" }, 106243a6a7e7SGarlic Tseng { "I15", NULL, "I14I15" }, 106343a6a7e7SGarlic Tseng { "I16", NULL, "I16I17" }, 106443a6a7e7SGarlic Tseng { "I17", NULL, "I16I17" }, 106543a6a7e7SGarlic Tseng { "I18", NULL, "I18I19" }, 106643a6a7e7SGarlic Tseng { "I19", NULL, "I18I19" }, 106743a6a7e7SGarlic Tseng 106843a6a7e7SGarlic Tseng { "O00", "I00 Switch", "I00" }, 106943a6a7e7SGarlic Tseng { "O01", "I01 Switch", "I01" }, 107043a6a7e7SGarlic Tseng { "O02", "I02 Switch", "I02" }, 107143a6a7e7SGarlic Tseng { "O03", "I03 Switch", "I03" }, 107243a6a7e7SGarlic Tseng { "O14", "I26 Switch", "I26" }, 107343a6a7e7SGarlic Tseng { "O15", "I12 Switch", "I12" }, 107443a6a7e7SGarlic Tseng { "O16", "I13 Switch", "I13" }, 107543a6a7e7SGarlic Tseng { "O17", "I14 Switch", "I14" }, 107643a6a7e7SGarlic Tseng { "O18", "I15 Switch", "I15" }, 107743a6a7e7SGarlic Tseng { "O19", "I16 Switch", "I16" }, 107843a6a7e7SGarlic Tseng { "O20", "I17 Switch", "I17" }, 107943a6a7e7SGarlic Tseng { "O21", "I18 Switch", "I18" }, 108043a6a7e7SGarlic Tseng { "O22", "I19 Switch", "I19" }, 108143a6a7e7SGarlic Tseng { "O31", "I35 Switch", "I35" }, 108243a6a7e7SGarlic Tseng 108343a6a7e7SGarlic Tseng }; 108443a6a7e7SGarlic Tseng 108543a6a7e7SGarlic Tseng static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = { 108643a6a7e7SGarlic Tseng .name = "mt2701-afe-pcm-dai", 108743a6a7e7SGarlic Tseng .dapm_widgets = mt2701_afe_pcm_widgets, 108843a6a7e7SGarlic Tseng .num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets), 108943a6a7e7SGarlic Tseng .dapm_routes = mt2701_afe_pcm_routes, 109043a6a7e7SGarlic Tseng .num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes), 109143a6a7e7SGarlic Tseng }; 109243a6a7e7SGarlic Tseng 109343a6a7e7SGarlic Tseng static const struct mtk_base_memif_data memif_data[MT2701_MEMIF_NUM] = { 109443a6a7e7SGarlic Tseng { 109543a6a7e7SGarlic Tseng .name = "DL1", 109643a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL1, 109743a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL1_BASE, 109843a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL1_CUR, 109943a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1, 110043a6a7e7SGarlic Tseng .fs_shift = 0, 110143a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 110243a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3, 110343a6a7e7SGarlic Tseng .mono_shift = 16, 110443a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 110543a6a7e7SGarlic Tseng .enable_shift = 1, 110643a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 110743a6a7e7SGarlic Tseng .hd_shift = 0, 110843a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 110943a6a7e7SGarlic Tseng .agent_disable_shift = 6, 111043a6a7e7SGarlic Tseng .msb_reg = -1, 111143a6a7e7SGarlic Tseng .msb_shift = -1, 111243a6a7e7SGarlic Tseng }, 111343a6a7e7SGarlic Tseng { 111443a6a7e7SGarlic Tseng .name = "DL2", 111543a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL2, 111643a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL2_BASE, 111743a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL2_CUR, 111843a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1, 111943a6a7e7SGarlic Tseng .fs_shift = 5, 112043a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 112143a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3, 112243a6a7e7SGarlic Tseng .mono_shift = 17, 112343a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 112443a6a7e7SGarlic Tseng .enable_shift = 2, 112543a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 112643a6a7e7SGarlic Tseng .hd_shift = 2, 112743a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 112843a6a7e7SGarlic Tseng .agent_disable_shift = 7, 112943a6a7e7SGarlic Tseng .msb_reg = -1, 113043a6a7e7SGarlic Tseng .msb_shift = -1, 113143a6a7e7SGarlic Tseng }, 113243a6a7e7SGarlic Tseng { 113343a6a7e7SGarlic Tseng .name = "DL3", 113443a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL3, 113543a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL3_BASE, 113643a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL3_CUR, 113743a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1, 113843a6a7e7SGarlic Tseng .fs_shift = 10, 113943a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 114043a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3, 114143a6a7e7SGarlic Tseng .mono_shift = 18, 114243a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 114343a6a7e7SGarlic Tseng .enable_shift = 3, 114443a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 114543a6a7e7SGarlic Tseng .hd_shift = 4, 114643a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 114743a6a7e7SGarlic Tseng .agent_disable_shift = 8, 114843a6a7e7SGarlic Tseng .msb_reg = -1, 114943a6a7e7SGarlic Tseng .msb_shift = -1, 115043a6a7e7SGarlic Tseng }, 115143a6a7e7SGarlic Tseng { 115243a6a7e7SGarlic Tseng .name = "DL4", 115343a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL4, 115443a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL4_BASE, 115543a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL4_CUR, 115643a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1, 115743a6a7e7SGarlic Tseng .fs_shift = 15, 115843a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 115943a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3, 116043a6a7e7SGarlic Tseng .mono_shift = 19, 116143a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 116243a6a7e7SGarlic Tseng .enable_shift = 4, 116343a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 116443a6a7e7SGarlic Tseng .hd_shift = 6, 116543a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 116643a6a7e7SGarlic Tseng .agent_disable_shift = 9, 116743a6a7e7SGarlic Tseng .msb_reg = -1, 116843a6a7e7SGarlic Tseng .msb_shift = -1, 116943a6a7e7SGarlic Tseng }, 117043a6a7e7SGarlic Tseng { 117143a6a7e7SGarlic Tseng .name = "DL5", 117243a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DL5, 117343a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DL5_BASE, 117443a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DL5_CUR, 117543a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1, 117643a6a7e7SGarlic Tseng .fs_shift = 20, 117743a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 117843a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3, 117943a6a7e7SGarlic Tseng .mono_shift = 20, 118043a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 118143a6a7e7SGarlic Tseng .enable_shift = 5, 118243a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 118343a6a7e7SGarlic Tseng .hd_shift = 8, 118443a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 118543a6a7e7SGarlic Tseng .agent_disable_shift = 10, 118643a6a7e7SGarlic Tseng .msb_reg = -1, 118743a6a7e7SGarlic Tseng .msb_shift = -1, 118843a6a7e7SGarlic Tseng }, 118943a6a7e7SGarlic Tseng { 119043a6a7e7SGarlic Tseng .name = "DLM", 119143a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DLM, 119243a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DLMCH_BASE, 119343a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DLMCH_CUR, 119443a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON1, 119543a6a7e7SGarlic Tseng .fs_shift = 0, 119643a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 119743a6a7e7SGarlic Tseng .mono_reg = -1, 119843a6a7e7SGarlic Tseng .mono_shift = -1, 119943a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 120043a6a7e7SGarlic Tseng .enable_shift = 7, 120143a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_PBUF_SIZE, 120243a6a7e7SGarlic Tseng .hd_shift = 28, 120343a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 120443a6a7e7SGarlic Tseng .agent_disable_shift = 12, 120543a6a7e7SGarlic Tseng .msb_reg = -1, 120643a6a7e7SGarlic Tseng .msb_shift = -1, 120743a6a7e7SGarlic Tseng }, 120843a6a7e7SGarlic Tseng { 120943a6a7e7SGarlic Tseng .name = "UL1", 121043a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL1, 121143a6a7e7SGarlic Tseng .reg_ofs_base = AFE_VUL_BASE, 121243a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_VUL_CUR, 121343a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2, 121443a6a7e7SGarlic Tseng .fs_shift = 0, 121543a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 121643a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4, 121743a6a7e7SGarlic Tseng .mono_shift = 0, 121843a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 121943a6a7e7SGarlic Tseng .enable_shift = 10, 122043a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON1, 122143a6a7e7SGarlic Tseng .hd_shift = 0, 122243a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 122343a6a7e7SGarlic Tseng .agent_disable_shift = 0, 122443a6a7e7SGarlic Tseng .msb_reg = -1, 122543a6a7e7SGarlic Tseng .msb_shift = -1, 122643a6a7e7SGarlic Tseng }, 122743a6a7e7SGarlic Tseng { 122843a6a7e7SGarlic Tseng .name = "UL2", 122943a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL2, 123043a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL2_BASE, 123143a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL2_CUR, 123243a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2, 123343a6a7e7SGarlic Tseng .fs_shift = 5, 123443a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 123543a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4, 123643a6a7e7SGarlic Tseng .mono_shift = 2, 123743a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 123843a6a7e7SGarlic Tseng .enable_shift = 11, 123943a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON1, 124043a6a7e7SGarlic Tseng .hd_shift = 2, 124143a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 124243a6a7e7SGarlic Tseng .agent_disable_shift = 1, 124343a6a7e7SGarlic Tseng .msb_reg = -1, 124443a6a7e7SGarlic Tseng .msb_shift = -1, 124543a6a7e7SGarlic Tseng }, 124643a6a7e7SGarlic Tseng { 124743a6a7e7SGarlic Tseng .name = "UL3", 124843a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL3, 124943a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL3_BASE, 125043a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL3_CUR, 125143a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2, 125243a6a7e7SGarlic Tseng .fs_shift = 10, 125343a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 125443a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4, 125543a6a7e7SGarlic Tseng .mono_shift = 4, 125643a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 125743a6a7e7SGarlic Tseng .enable_shift = 12, 125843a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 125943a6a7e7SGarlic Tseng .hd_shift = 0, 126043a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 126143a6a7e7SGarlic Tseng .agent_disable_shift = 2, 126243a6a7e7SGarlic Tseng .msb_reg = -1, 126343a6a7e7SGarlic Tseng .msb_shift = -1, 126443a6a7e7SGarlic Tseng }, 126543a6a7e7SGarlic Tseng { 126643a6a7e7SGarlic Tseng .name = "UL4", 126743a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL4, 126843a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL4_BASE, 126943a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL4_CUR, 127043a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2, 127143a6a7e7SGarlic Tseng .fs_shift = 15, 127243a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 127343a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4, 127443a6a7e7SGarlic Tseng .mono_shift = 6, 127543a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 127643a6a7e7SGarlic Tseng .enable_shift = 13, 127743a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 127843a6a7e7SGarlic Tseng .hd_shift = 6, 127943a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 128043a6a7e7SGarlic Tseng .agent_disable_shift = 3, 128143a6a7e7SGarlic Tseng .msb_reg = -1, 128243a6a7e7SGarlic Tseng .msb_shift = -1, 128343a6a7e7SGarlic Tseng }, 128443a6a7e7SGarlic Tseng { 128543a6a7e7SGarlic Tseng .name = "UL5", 128643a6a7e7SGarlic Tseng .id = MT2701_MEMIF_UL5, 128743a6a7e7SGarlic Tseng .reg_ofs_base = AFE_UL5_BASE, 128843a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_UL5_CUR, 128943a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2, 129043a6a7e7SGarlic Tseng .fs_shift = 20, 129143a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON4, 129243a6a7e7SGarlic Tseng .mono_shift = 8, 129343a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 129443a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 129543a6a7e7SGarlic Tseng .enable_shift = 14, 129643a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 129743a6a7e7SGarlic Tseng .hd_shift = 8, 129843a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 129943a6a7e7SGarlic Tseng .agent_disable_shift = 4, 130043a6a7e7SGarlic Tseng .msb_reg = -1, 130143a6a7e7SGarlic Tseng .msb_shift = -1, 130243a6a7e7SGarlic Tseng }, 130343a6a7e7SGarlic Tseng { 130443a6a7e7SGarlic Tseng .name = "DLBT", 130543a6a7e7SGarlic Tseng .id = MT2701_MEMIF_DLBT, 130643a6a7e7SGarlic Tseng .reg_ofs_base = AFE_ARB1_BASE, 130743a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_ARB1_CUR, 130843a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON3, 130943a6a7e7SGarlic Tseng .fs_shift = 10, 131043a6a7e7SGarlic Tseng .fs_maskbit = 0x1f, 131143a6a7e7SGarlic Tseng .mono_reg = AFE_DAC_CON3, 131243a6a7e7SGarlic Tseng .mono_shift = 22, 131343a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 131443a6a7e7SGarlic Tseng .enable_shift = 8, 131543a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON0, 131643a6a7e7SGarlic Tseng .hd_shift = 14, 131743a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 131843a6a7e7SGarlic Tseng .agent_disable_shift = 13, 131943a6a7e7SGarlic Tseng .msb_reg = -1, 132043a6a7e7SGarlic Tseng .msb_shift = -1, 132143a6a7e7SGarlic Tseng }, 132243a6a7e7SGarlic Tseng { 132343a6a7e7SGarlic Tseng .name = "ULBT", 132443a6a7e7SGarlic Tseng .id = MT2701_MEMIF_ULBT, 132543a6a7e7SGarlic Tseng .reg_ofs_base = AFE_DAI_BASE, 132643a6a7e7SGarlic Tseng .reg_ofs_cur = AFE_DAI_CUR, 132743a6a7e7SGarlic Tseng .fs_reg = AFE_DAC_CON2, 132843a6a7e7SGarlic Tseng .fs_shift = 30, 132943a6a7e7SGarlic Tseng .fs_maskbit = 0x1, 133043a6a7e7SGarlic Tseng .mono_reg = -1, 133143a6a7e7SGarlic Tseng .mono_shift = -1, 133243a6a7e7SGarlic Tseng .enable_reg = AFE_DAC_CON0, 133343a6a7e7SGarlic Tseng .enable_shift = 17, 133443a6a7e7SGarlic Tseng .hd_reg = AFE_MEMIF_HD_CON1, 133543a6a7e7SGarlic Tseng .hd_shift = 20, 133643a6a7e7SGarlic Tseng .agent_disable_reg = AUDIO_TOP_CON5, 133743a6a7e7SGarlic Tseng .agent_disable_shift = 16, 133843a6a7e7SGarlic Tseng .msb_reg = -1, 133943a6a7e7SGarlic Tseng .msb_shift = -1, 134043a6a7e7SGarlic Tseng }, 134143a6a7e7SGarlic Tseng }; 134243a6a7e7SGarlic Tseng 134343a6a7e7SGarlic Tseng static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = { 134443a6a7e7SGarlic Tseng { 134543a6a7e7SGarlic Tseng .id = MT2701_IRQ_ASYS_IRQ1, 134643a6a7e7SGarlic Tseng .irq_cnt_reg = ASYS_IRQ1_CON, 134743a6a7e7SGarlic Tseng .irq_cnt_shift = 0, 134843a6a7e7SGarlic Tseng .irq_cnt_maskbit = 0xffffff, 134943a6a7e7SGarlic Tseng .irq_fs_reg = ASYS_IRQ1_CON, 135043a6a7e7SGarlic Tseng .irq_fs_shift = 24, 135143a6a7e7SGarlic Tseng .irq_fs_maskbit = 0x1f, 135243a6a7e7SGarlic Tseng .irq_en_reg = ASYS_IRQ1_CON, 135343a6a7e7SGarlic Tseng .irq_en_shift = 31, 135443a6a7e7SGarlic Tseng .irq_clr_reg = ASYS_IRQ_CLR, 135543a6a7e7SGarlic Tseng .irq_clr_shift = 0, 135643a6a7e7SGarlic Tseng }, 135743a6a7e7SGarlic Tseng { 135843a6a7e7SGarlic Tseng .id = MT2701_IRQ_ASYS_IRQ2, 135943a6a7e7SGarlic Tseng .irq_cnt_reg = ASYS_IRQ2_CON, 136043a6a7e7SGarlic Tseng .irq_cnt_shift = 0, 136143a6a7e7SGarlic Tseng .irq_cnt_maskbit = 0xffffff, 136243a6a7e7SGarlic Tseng .irq_fs_reg = ASYS_IRQ2_CON, 136343a6a7e7SGarlic Tseng .irq_fs_shift = 24, 136443a6a7e7SGarlic Tseng .irq_fs_maskbit = 0x1f, 136543a6a7e7SGarlic Tseng .irq_en_reg = ASYS_IRQ2_CON, 136643a6a7e7SGarlic Tseng .irq_en_shift = 31, 136743a6a7e7SGarlic Tseng .irq_clr_reg = ASYS_IRQ_CLR, 136843a6a7e7SGarlic Tseng .irq_clr_shift = 1, 136943a6a7e7SGarlic Tseng }, 137043a6a7e7SGarlic Tseng { 137143a6a7e7SGarlic Tseng .id = MT2701_IRQ_ASYS_IRQ3, 137243a6a7e7SGarlic Tseng .irq_cnt_reg = ASYS_IRQ3_CON, 137343a6a7e7SGarlic Tseng .irq_cnt_shift = 0, 137443a6a7e7SGarlic Tseng .irq_cnt_maskbit = 0xffffff, 137543a6a7e7SGarlic Tseng .irq_fs_reg = ASYS_IRQ3_CON, 137643a6a7e7SGarlic Tseng .irq_fs_shift = 24, 137743a6a7e7SGarlic Tseng .irq_fs_maskbit = 0x1f, 137843a6a7e7SGarlic Tseng .irq_en_reg = ASYS_IRQ3_CON, 137943a6a7e7SGarlic Tseng .irq_en_shift = 31, 138043a6a7e7SGarlic Tseng .irq_clr_reg = ASYS_IRQ_CLR, 138143a6a7e7SGarlic Tseng .irq_clr_shift = 2, 138243a6a7e7SGarlic Tseng } 138343a6a7e7SGarlic Tseng }; 138443a6a7e7SGarlic Tseng 138543a6a7e7SGarlic Tseng static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { 138643a6a7e7SGarlic Tseng { 138743a6a7e7SGarlic Tseng { 138843a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SO1_CON, 138943a6a7e7SGarlic Tseng .i2s_pwn_shift = 6, 139043a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 0, 139143a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 139243a6a7e7SGarlic Tseng 139343a6a7e7SGarlic Tseng }, 139443a6a7e7SGarlic Tseng { 139543a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SIN1_CON, 139643a6a7e7SGarlic Tseng .i2s_pwn_shift = 0, 139743a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 0, 139843a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 139943a6a7e7SGarlic Tseng 140043a6a7e7SGarlic Tseng }, 140143a6a7e7SGarlic Tseng }, 140243a6a7e7SGarlic Tseng { 140343a6a7e7SGarlic Tseng { 140443a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SO2_CON, 140543a6a7e7SGarlic Tseng .i2s_pwn_shift = 7, 140643a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 5, 140743a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 140843a6a7e7SGarlic Tseng 140943a6a7e7SGarlic Tseng }, 141043a6a7e7SGarlic Tseng { 141143a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SIN2_CON, 141243a6a7e7SGarlic Tseng .i2s_pwn_shift = 1, 141343a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 5, 141443a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 141543a6a7e7SGarlic Tseng 141643a6a7e7SGarlic Tseng }, 141743a6a7e7SGarlic Tseng }, 141843a6a7e7SGarlic Tseng { 141943a6a7e7SGarlic Tseng { 142043a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SO3_CON, 142143a6a7e7SGarlic Tseng .i2s_pwn_shift = 8, 142243a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 10, 142343a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 142443a6a7e7SGarlic Tseng 142543a6a7e7SGarlic Tseng }, 142643a6a7e7SGarlic Tseng { 142743a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SIN3_CON, 142843a6a7e7SGarlic Tseng .i2s_pwn_shift = 2, 142943a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 10, 143043a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 143143a6a7e7SGarlic Tseng 143243a6a7e7SGarlic Tseng }, 143343a6a7e7SGarlic Tseng }, 143443a6a7e7SGarlic Tseng { 143543a6a7e7SGarlic Tseng { 143643a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SO4_CON, 143743a6a7e7SGarlic Tseng .i2s_pwn_shift = 9, 143843a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 15, 143943a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 144043a6a7e7SGarlic Tseng 144143a6a7e7SGarlic Tseng }, 144243a6a7e7SGarlic Tseng { 144343a6a7e7SGarlic Tseng .i2s_ctrl_reg = ASYS_I2SIN4_CON, 144443a6a7e7SGarlic Tseng .i2s_pwn_shift = 3, 144543a6a7e7SGarlic Tseng .i2s_asrc_fs_shift = 15, 144643a6a7e7SGarlic Tseng .i2s_asrc_fs_mask = 0x1f, 144743a6a7e7SGarlic Tseng 144843a6a7e7SGarlic Tseng }, 144943a6a7e7SGarlic Tseng }, 145043a6a7e7SGarlic Tseng }; 145143a6a7e7SGarlic Tseng 145243a6a7e7SGarlic Tseng static const struct regmap_config mt2701_afe_regmap_config = { 145343a6a7e7SGarlic Tseng .reg_bits = 32, 145443a6a7e7SGarlic Tseng .reg_stride = 4, 145543a6a7e7SGarlic Tseng .val_bits = 32, 145643a6a7e7SGarlic Tseng .max_register = AFE_END_ADDR, 145743a6a7e7SGarlic Tseng .cache_type = REGCACHE_NONE, 145843a6a7e7SGarlic Tseng }; 145943a6a7e7SGarlic Tseng 146043a6a7e7SGarlic Tseng static irqreturn_t mt2701_asys_isr(int irq_id, void *dev) 146143a6a7e7SGarlic Tseng { 146243a6a7e7SGarlic Tseng int id; 146343a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev; 146443a6a7e7SGarlic Tseng struct mtk_base_afe_memif *memif; 146543a6a7e7SGarlic Tseng struct mtk_base_afe_irq *irq; 146643a6a7e7SGarlic Tseng u32 status; 146743a6a7e7SGarlic Tseng 146843a6a7e7SGarlic Tseng regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status); 146943a6a7e7SGarlic Tseng regmap_write(afe->regmap, ASYS_IRQ_CLR, status); 147043a6a7e7SGarlic Tseng 147143a6a7e7SGarlic Tseng for (id = 0; id < MT2701_MEMIF_NUM; ++id) { 147243a6a7e7SGarlic Tseng memif = &afe->memif[id]; 147343a6a7e7SGarlic Tseng if (memif->irq_usage < 0) 147443a6a7e7SGarlic Tseng continue; 147543a6a7e7SGarlic Tseng irq = &afe->irqs[memif->irq_usage]; 147643a6a7e7SGarlic Tseng if (status & 1 << (irq->irq_data->irq_clr_shift)) 147743a6a7e7SGarlic Tseng snd_pcm_period_elapsed(memif->substream); 147843a6a7e7SGarlic Tseng } 147943a6a7e7SGarlic Tseng return IRQ_HANDLED; 148043a6a7e7SGarlic Tseng } 148143a6a7e7SGarlic Tseng 148243a6a7e7SGarlic Tseng static int mt2701_afe_runtime_suspend(struct device *dev) 148343a6a7e7SGarlic Tseng { 148443a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev_get_drvdata(dev); 148543a6a7e7SGarlic Tseng 148643a6a7e7SGarlic Tseng mt2701_afe_disable_clock(afe); 148743a6a7e7SGarlic Tseng return 0; 148843a6a7e7SGarlic Tseng } 148943a6a7e7SGarlic Tseng 149043a6a7e7SGarlic Tseng static int mt2701_afe_runtime_resume(struct device *dev) 149143a6a7e7SGarlic Tseng { 149243a6a7e7SGarlic Tseng struct mtk_base_afe *afe = dev_get_drvdata(dev); 149343a6a7e7SGarlic Tseng 149443a6a7e7SGarlic Tseng return mt2701_afe_enable_clock(afe); 149543a6a7e7SGarlic Tseng } 149643a6a7e7SGarlic Tseng 149743a6a7e7SGarlic Tseng static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) 149843a6a7e7SGarlic Tseng { 149943a6a7e7SGarlic Tseng struct mtk_base_afe *afe; 150043a6a7e7SGarlic Tseng struct mt2701_afe_private *afe_priv; 150143a6a7e7SGarlic Tseng struct resource *res; 150243a6a7e7SGarlic Tseng struct device *dev; 1503f6c1626eSRyder Lee int i, irq_id, ret; 150443a6a7e7SGarlic Tseng 150543a6a7e7SGarlic Tseng afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); 150643a6a7e7SGarlic Tseng if (!afe) 150743a6a7e7SGarlic Tseng return -ENOMEM; 1508b02c5cc7SDan Carpenter afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), 1509b02c5cc7SDan Carpenter GFP_KERNEL); 1510b02c5cc7SDan Carpenter if (!afe->platform_priv) 1511b02c5cc7SDan Carpenter return -ENOMEM; 1512b02c5cc7SDan Carpenter afe_priv = afe->platform_priv; 151343a6a7e7SGarlic Tseng 151443a6a7e7SGarlic Tseng afe->dev = &pdev->dev; 151543a6a7e7SGarlic Tseng dev = afe->dev; 151643a6a7e7SGarlic Tseng 1517f6c1626eSRyder Lee irq_id = platform_get_irq_byname(pdev, "asys"); 1518f6c1626eSRyder Lee if (irq_id < 0) { 1519f6c1626eSRyder Lee dev_err(dev, "unable to get ASYS IRQ\n"); 1520f6c1626eSRyder Lee return irq_id; 152143a6a7e7SGarlic Tseng } 1522f6c1626eSRyder Lee 152343a6a7e7SGarlic Tseng ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, 152443a6a7e7SGarlic Tseng IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); 152543a6a7e7SGarlic Tseng if (ret) { 152643a6a7e7SGarlic Tseng dev_err(dev, "could not request_irq for asys-isr\n"); 152743a6a7e7SGarlic Tseng return ret; 152843a6a7e7SGarlic Tseng } 152943a6a7e7SGarlic Tseng 153043a6a7e7SGarlic Tseng res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 153143a6a7e7SGarlic Tseng 153243a6a7e7SGarlic Tseng afe->base_addr = devm_ioremap_resource(&pdev->dev, res); 153343a6a7e7SGarlic Tseng 153443a6a7e7SGarlic Tseng if (IS_ERR(afe->base_addr)) 153543a6a7e7SGarlic Tseng return PTR_ERR(afe->base_addr); 153643a6a7e7SGarlic Tseng 153743a6a7e7SGarlic Tseng afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, 153843a6a7e7SGarlic Tseng &mt2701_afe_regmap_config); 153943a6a7e7SGarlic Tseng if (IS_ERR(afe->regmap)) 154043a6a7e7SGarlic Tseng return PTR_ERR(afe->regmap); 154143a6a7e7SGarlic Tseng 154243a6a7e7SGarlic Tseng mutex_init(&afe->irq_alloc_lock); 154343a6a7e7SGarlic Tseng 154443a6a7e7SGarlic Tseng /* memif initialize */ 154543a6a7e7SGarlic Tseng afe->memif_size = MT2701_MEMIF_NUM; 154643a6a7e7SGarlic Tseng afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), 154743a6a7e7SGarlic Tseng GFP_KERNEL); 154843a6a7e7SGarlic Tseng 154943a6a7e7SGarlic Tseng if (!afe->memif) 155043a6a7e7SGarlic Tseng return -ENOMEM; 155143a6a7e7SGarlic Tseng 155243a6a7e7SGarlic Tseng for (i = 0; i < afe->memif_size; i++) { 155343a6a7e7SGarlic Tseng afe->memif[i].data = &memif_data[i]; 155443a6a7e7SGarlic Tseng afe->memif[i].irq_usage = -1; 155543a6a7e7SGarlic Tseng } 155643a6a7e7SGarlic Tseng 155743a6a7e7SGarlic Tseng /* irq initialize */ 155843a6a7e7SGarlic Tseng afe->irqs_size = MT2701_IRQ_ASYS_END; 155943a6a7e7SGarlic Tseng afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), 156043a6a7e7SGarlic Tseng GFP_KERNEL); 156143a6a7e7SGarlic Tseng 156243a6a7e7SGarlic Tseng if (!afe->irqs) 156343a6a7e7SGarlic Tseng return -ENOMEM; 156443a6a7e7SGarlic Tseng 156543a6a7e7SGarlic Tseng for (i = 0; i < afe->irqs_size; i++) 156643a6a7e7SGarlic Tseng afe->irqs[i].irq_data = &irq_data[i]; 156743a6a7e7SGarlic Tseng 156843a6a7e7SGarlic Tseng /* I2S initialize */ 156943a6a7e7SGarlic Tseng for (i = 0; i < MT2701_I2S_NUM; i++) { 157043a6a7e7SGarlic Tseng afe_priv->i2s_path[i].i2s_data[I2S_OUT] 157143a6a7e7SGarlic Tseng = &mt2701_i2s_data[i][I2S_OUT]; 157243a6a7e7SGarlic Tseng afe_priv->i2s_path[i].i2s_data[I2S_IN] 157343a6a7e7SGarlic Tseng = &mt2701_i2s_data[i][I2S_IN]; 157443a6a7e7SGarlic Tseng } 157543a6a7e7SGarlic Tseng 157643a6a7e7SGarlic Tseng afe->mtk_afe_hardware = &mt2701_afe_hardware; 157743a6a7e7SGarlic Tseng afe->memif_fs = mt2701_memif_fs; 157843a6a7e7SGarlic Tseng afe->irq_fs = mt2701_irq_fs; 157943a6a7e7SGarlic Tseng 158043a6a7e7SGarlic Tseng afe->reg_back_up_list = mt2701_afe_backup_list; 158143a6a7e7SGarlic Tseng afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list); 158243a6a7e7SGarlic Tseng afe->runtime_resume = mt2701_afe_runtime_resume; 158343a6a7e7SGarlic Tseng afe->runtime_suspend = mt2701_afe_runtime_suspend; 158443a6a7e7SGarlic Tseng 158543a6a7e7SGarlic Tseng /* initial audio related clock */ 158643a6a7e7SGarlic Tseng ret = mt2701_init_clock(afe); 158743a6a7e7SGarlic Tseng if (ret) { 158843a6a7e7SGarlic Tseng dev_err(dev, "init clock error\n"); 158943a6a7e7SGarlic Tseng return ret; 159043a6a7e7SGarlic Tseng } 159143a6a7e7SGarlic Tseng 159243a6a7e7SGarlic Tseng platform_set_drvdata(pdev, afe); 159343a6a7e7SGarlic Tseng 1594*dd6bb9b1SRyder Lee pm_runtime_enable(dev); 1595*dd6bb9b1SRyder Lee if (!pm_runtime_enabled(dev)) { 1596*dd6bb9b1SRyder Lee ret = mt2701_afe_runtime_resume(dev); 1597*dd6bb9b1SRyder Lee if (ret) 1598*dd6bb9b1SRyder Lee goto err_pm_disable; 1599*dd6bb9b1SRyder Lee } 1600*dd6bb9b1SRyder Lee pm_runtime_get_sync(dev); 1601*dd6bb9b1SRyder Lee 1602*dd6bb9b1SRyder Lee ret = snd_soc_register_platform(dev, &mtk_afe_pcm_platform); 160343a6a7e7SGarlic Tseng if (ret) { 160443a6a7e7SGarlic Tseng dev_warn(dev, "err_platform\n"); 160543a6a7e7SGarlic Tseng goto err_platform; 160643a6a7e7SGarlic Tseng } 160743a6a7e7SGarlic Tseng 160843a6a7e7SGarlic Tseng ret = snd_soc_register_component(&pdev->dev, 160943a6a7e7SGarlic Tseng &mt2701_afe_pcm_dai_component, 161043a6a7e7SGarlic Tseng mt2701_afe_pcm_dais, 161143a6a7e7SGarlic Tseng ARRAY_SIZE(mt2701_afe_pcm_dais)); 161243a6a7e7SGarlic Tseng if (ret) { 161343a6a7e7SGarlic Tseng dev_warn(dev, "err_dai_component\n"); 161443a6a7e7SGarlic Tseng goto err_dai_component; 161543a6a7e7SGarlic Tseng } 161643a6a7e7SGarlic Tseng 161743a6a7e7SGarlic Tseng return 0; 161843a6a7e7SGarlic Tseng 161943a6a7e7SGarlic Tseng err_dai_component: 1620*dd6bb9b1SRyder Lee snd_soc_unregister_platform(dev); 162143a6a7e7SGarlic Tseng err_platform: 1622*dd6bb9b1SRyder Lee pm_runtime_put_sync(dev); 162343a6a7e7SGarlic Tseng err_pm_disable: 1624*dd6bb9b1SRyder Lee pm_runtime_disable(dev); 162543a6a7e7SGarlic Tseng 162643a6a7e7SGarlic Tseng return ret; 162743a6a7e7SGarlic Tseng } 162843a6a7e7SGarlic Tseng 162943a6a7e7SGarlic Tseng static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev) 163043a6a7e7SGarlic Tseng { 1631*dd6bb9b1SRyder Lee pm_runtime_put_sync(&pdev->dev); 163243a6a7e7SGarlic Tseng pm_runtime_disable(&pdev->dev); 163343a6a7e7SGarlic Tseng if (!pm_runtime_status_suspended(&pdev->dev)) 163443a6a7e7SGarlic Tseng mt2701_afe_runtime_suspend(&pdev->dev); 163543a6a7e7SGarlic Tseng 163643a6a7e7SGarlic Tseng snd_soc_unregister_component(&pdev->dev); 163743a6a7e7SGarlic Tseng snd_soc_unregister_platform(&pdev->dev); 1638*dd6bb9b1SRyder Lee 163943a6a7e7SGarlic Tseng return 0; 164043a6a7e7SGarlic Tseng } 164143a6a7e7SGarlic Tseng 164243a6a7e7SGarlic Tseng static const struct of_device_id mt2701_afe_pcm_dt_match[] = { 164343a6a7e7SGarlic Tseng { .compatible = "mediatek,mt2701-audio", }, 164443a6a7e7SGarlic Tseng {}, 164543a6a7e7SGarlic Tseng }; 164643a6a7e7SGarlic Tseng MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match); 164743a6a7e7SGarlic Tseng 164843a6a7e7SGarlic Tseng static const struct dev_pm_ops mt2701_afe_pm_ops = { 164943a6a7e7SGarlic Tseng SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend, 165043a6a7e7SGarlic Tseng mt2701_afe_runtime_resume, NULL) 165143a6a7e7SGarlic Tseng }; 165243a6a7e7SGarlic Tseng 165343a6a7e7SGarlic Tseng static struct platform_driver mt2701_afe_pcm_driver = { 165443a6a7e7SGarlic Tseng .driver = { 165543a6a7e7SGarlic Tseng .name = "mt2701-audio", 165643a6a7e7SGarlic Tseng .of_match_table = mt2701_afe_pcm_dt_match, 165743a6a7e7SGarlic Tseng #ifdef CONFIG_PM 165843a6a7e7SGarlic Tseng .pm = &mt2701_afe_pm_ops, 165943a6a7e7SGarlic Tseng #endif 166043a6a7e7SGarlic Tseng }, 166143a6a7e7SGarlic Tseng .probe = mt2701_afe_pcm_dev_probe, 166243a6a7e7SGarlic Tseng .remove = mt2701_afe_pcm_dev_remove, 166343a6a7e7SGarlic Tseng }; 166443a6a7e7SGarlic Tseng 166543a6a7e7SGarlic Tseng module_platform_driver(mt2701_afe_pcm_driver); 166643a6a7e7SGarlic Tseng 166743a6a7e7SGarlic Tseng MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701"); 166843a6a7e7SGarlic Tseng MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); 166943a6a7e7SGarlic Tseng MODULE_LICENSE("GPL v2"); 167043a6a7e7SGarlic Tseng 1671