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