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