162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Mediatek ALSA SoC AFE platform driver for 2701 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2016 MediaTek Inc. 662306a36Sopenharmony_ci * Author: Garlic Tseng <garlic.tseng@mediatek.com> 762306a36Sopenharmony_ci * Ir Lian <ir.lian@mediatek.com> 862306a36Sopenharmony_ci * Ryder Lee <ryder.lee@mediatek.com> 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/delay.h> 1262306a36Sopenharmony_ci#include <linux/module.h> 1362306a36Sopenharmony_ci#include <linux/mfd/syscon.h> 1462306a36Sopenharmony_ci#include <linux/of.h> 1562306a36Sopenharmony_ci#include <linux/of_address.h> 1662306a36Sopenharmony_ci#include <linux/of_device.h> 1762306a36Sopenharmony_ci#include <linux/pm_runtime.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "mt2701-afe-common.h" 2062306a36Sopenharmony_ci#include "mt2701-afe-clock-ctrl.h" 2162306a36Sopenharmony_ci#include "../common/mtk-afe-platform-driver.h" 2262306a36Sopenharmony_ci#include "../common/mtk-afe-fe-dai.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic const struct snd_pcm_hardware mt2701_afe_hardware = { 2562306a36Sopenharmony_ci .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED 2662306a36Sopenharmony_ci | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID, 2762306a36Sopenharmony_ci .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE 2862306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE, 2962306a36Sopenharmony_ci .period_bytes_min = 1024, 3062306a36Sopenharmony_ci .period_bytes_max = 1024 * 256, 3162306a36Sopenharmony_ci .periods_min = 4, 3262306a36Sopenharmony_ci .periods_max = 1024, 3362306a36Sopenharmony_ci .buffer_bytes_max = 1024 * 1024, 3462306a36Sopenharmony_ci .fifo_size = 0, 3562306a36Sopenharmony_ci}; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistruct mt2701_afe_rate { 3862306a36Sopenharmony_ci unsigned int rate; 3962306a36Sopenharmony_ci unsigned int regvalue; 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = { 4362306a36Sopenharmony_ci { .rate = 8000, .regvalue = 0 }, 4462306a36Sopenharmony_ci { .rate = 12000, .regvalue = 1 }, 4562306a36Sopenharmony_ci { .rate = 16000, .regvalue = 2 }, 4662306a36Sopenharmony_ci { .rate = 24000, .regvalue = 3 }, 4762306a36Sopenharmony_ci { .rate = 32000, .regvalue = 4 }, 4862306a36Sopenharmony_ci { .rate = 48000, .regvalue = 5 }, 4962306a36Sopenharmony_ci { .rate = 96000, .regvalue = 6 }, 5062306a36Sopenharmony_ci { .rate = 192000, .regvalue = 7 }, 5162306a36Sopenharmony_ci { .rate = 384000, .regvalue = 8 }, 5262306a36Sopenharmony_ci { .rate = 7350, .regvalue = 16 }, 5362306a36Sopenharmony_ci { .rate = 11025, .regvalue = 17 }, 5462306a36Sopenharmony_ci { .rate = 14700, .regvalue = 18 }, 5562306a36Sopenharmony_ci { .rate = 22050, .regvalue = 19 }, 5662306a36Sopenharmony_ci { .rate = 29400, .regvalue = 20 }, 5762306a36Sopenharmony_ci { .rate = 44100, .regvalue = 21 }, 5862306a36Sopenharmony_ci { .rate = 88200, .regvalue = 22 }, 5962306a36Sopenharmony_ci { .rate = 176400, .regvalue = 23 }, 6062306a36Sopenharmony_ci { .rate = 352800, .regvalue = 24 }, 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic const unsigned int mt2701_afe_backup_list[] = { 6462306a36Sopenharmony_ci AUDIO_TOP_CON0, 6562306a36Sopenharmony_ci AUDIO_TOP_CON4, 6662306a36Sopenharmony_ci AUDIO_TOP_CON5, 6762306a36Sopenharmony_ci ASYS_TOP_CON, 6862306a36Sopenharmony_ci AFE_CONN0, 6962306a36Sopenharmony_ci AFE_CONN1, 7062306a36Sopenharmony_ci AFE_CONN2, 7162306a36Sopenharmony_ci AFE_CONN3, 7262306a36Sopenharmony_ci AFE_CONN15, 7362306a36Sopenharmony_ci AFE_CONN16, 7462306a36Sopenharmony_ci AFE_CONN17, 7562306a36Sopenharmony_ci AFE_CONN18, 7662306a36Sopenharmony_ci AFE_CONN19, 7762306a36Sopenharmony_ci AFE_CONN20, 7862306a36Sopenharmony_ci AFE_CONN21, 7962306a36Sopenharmony_ci AFE_CONN22, 8062306a36Sopenharmony_ci AFE_DAC_CON0, 8162306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE, 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 8762306a36Sopenharmony_ci int val = num - MT2701_IO_I2S; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci if (val < 0 || val >= afe_priv->soc->i2s_num) { 9062306a36Sopenharmony_ci dev_err(afe->dev, "%s, num not available, num %d, val %d\n", 9162306a36Sopenharmony_ci __func__, num, val); 9262306a36Sopenharmony_ci return -EINVAL; 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci return val; 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic int mt2701_afe_i2s_fs(unsigned int sample_rate) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci int i; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++) 10262306a36Sopenharmony_ci if (mt2701_afe_i2s_rates[i].rate == sample_rate) 10362306a36Sopenharmony_ci return mt2701_afe_i2s_rates[i].regvalue; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci return -EINVAL; 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream, 10962306a36Sopenharmony_ci struct snd_soc_dai *dai) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 11262306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 11362306a36Sopenharmony_ci int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 11462306a36Sopenharmony_ci bool mode = afe_priv->soc->has_one_heart_mode; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci if (i2s_num < 0) 11762306a36Sopenharmony_ci return i2s_num; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci return mt2701_afe_enable_mclk(afe, mode ? 1 : i2s_num); 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic int mt2701_afe_i2s_path_disable(struct mtk_base_afe *afe, 12362306a36Sopenharmony_ci struct mt2701_i2s_path *i2s_path, 12462306a36Sopenharmony_ci int stream_dir) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir]; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci if (--i2s_path->on[stream_dir] < 0) 12962306a36Sopenharmony_ci i2s_path->on[stream_dir] = 0; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci if (i2s_path->on[stream_dir]) 13262306a36Sopenharmony_ci return 0; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* disable i2s */ 13562306a36Sopenharmony_ci regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 13662306a36Sopenharmony_ci ASYS_I2S_CON_I2S_EN, 0); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci mt2701_afe_disable_i2s(afe, i2s_path, stream_dir); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci return 0; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream, 14462306a36Sopenharmony_ci struct snd_soc_dai *dai) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 14762306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 14862306a36Sopenharmony_ci int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 14962306a36Sopenharmony_ci struct mt2701_i2s_path *i2s_path; 15062306a36Sopenharmony_ci bool mode = afe_priv->soc->has_one_heart_mode; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci if (i2s_num < 0) 15362306a36Sopenharmony_ci return; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci i2s_path = &afe_priv->i2s_path[i2s_num]; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci if (i2s_path->occupied[substream->stream]) 15862306a36Sopenharmony_ci i2s_path->occupied[substream->stream] = 0; 15962306a36Sopenharmony_ci else 16062306a36Sopenharmony_ci goto exit; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci mt2701_afe_i2s_path_disable(afe, i2s_path, substream->stream); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci /* need to disable i2s-out path when disable i2s-in */ 16562306a36Sopenharmony_ci if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 16662306a36Sopenharmony_ci mt2701_afe_i2s_path_disable(afe, i2s_path, !substream->stream); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ciexit: 16962306a36Sopenharmony_ci /* disable mclk */ 17062306a36Sopenharmony_ci mt2701_afe_disable_mclk(afe, mode ? 1 : i2s_num); 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic int mt2701_i2s_path_enable(struct mtk_base_afe *afe, 17462306a36Sopenharmony_ci struct mt2701_i2s_path *i2s_path, 17562306a36Sopenharmony_ci int stream_dir, int rate) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir]; 17862306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 17962306a36Sopenharmony_ci int reg, fs, w_len = 1; /* now we support bck 64bits only */ 18062306a36Sopenharmony_ci unsigned int mask, val; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* no need to enable if already done */ 18362306a36Sopenharmony_ci if (++i2s_path->on[stream_dir] != 1) 18462306a36Sopenharmony_ci return 0; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci fs = mt2701_afe_i2s_fs(rate); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci mask = ASYS_I2S_CON_FS | 18962306a36Sopenharmony_ci ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */ 19062306a36Sopenharmony_ci ASYS_I2S_CON_I2S_MODE | 19162306a36Sopenharmony_ci ASYS_I2S_CON_WIDE_MODE; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci val = ASYS_I2S_CON_FS_SET(fs) | 19462306a36Sopenharmony_ci ASYS_I2S_CON_I2S_MODE | 19562306a36Sopenharmony_ci ASYS_I2S_CON_WIDE_MODE_SET(w_len); 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) { 19862306a36Sopenharmony_ci mask |= ASYS_I2S_IN_PHASE_FIX; 19962306a36Sopenharmony_ci val |= ASYS_I2S_IN_PHASE_FIX; 20062306a36Sopenharmony_ci reg = ASMI_TIMING_CON1; 20162306a36Sopenharmony_ci } else { 20262306a36Sopenharmony_ci if (afe_priv->soc->has_one_heart_mode) { 20362306a36Sopenharmony_ci mask |= ASYS_I2S_CON_ONE_HEART_MODE; 20462306a36Sopenharmony_ci val |= ASYS_I2S_CON_ONE_HEART_MODE; 20562306a36Sopenharmony_ci } 20662306a36Sopenharmony_ci reg = ASMO_TIMING_CON1; 20762306a36Sopenharmony_ci } 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci regmap_update_bits(afe->regmap, reg, 21262306a36Sopenharmony_ci i2s_data->i2s_asrc_fs_mask 21362306a36Sopenharmony_ci << i2s_data->i2s_asrc_fs_shift, 21462306a36Sopenharmony_ci fs << i2s_data->i2s_asrc_fs_shift); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci /* enable i2s */ 21762306a36Sopenharmony_ci mt2701_afe_enable_i2s(afe, i2s_path, stream_dir); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci /* reset i2s hw status before enable */ 22062306a36Sopenharmony_ci regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 22162306a36Sopenharmony_ci ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET); 22262306a36Sopenharmony_ci udelay(1); 22362306a36Sopenharmony_ci regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 22462306a36Sopenharmony_ci ASYS_I2S_CON_RESET, 0); 22562306a36Sopenharmony_ci udelay(1); 22662306a36Sopenharmony_ci regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, 22762306a36Sopenharmony_ci ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN); 22862306a36Sopenharmony_ci return 0; 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream, 23262306a36Sopenharmony_ci struct snd_soc_dai *dai) 23362306a36Sopenharmony_ci{ 23462306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 23562306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 23662306a36Sopenharmony_ci int ret, i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 23762306a36Sopenharmony_ci struct mt2701_i2s_path *i2s_path; 23862306a36Sopenharmony_ci bool mode = afe_priv->soc->has_one_heart_mode; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (i2s_num < 0) 24162306a36Sopenharmony_ci return i2s_num; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci i2s_path = &afe_priv->i2s_path[i2s_num]; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci if (i2s_path->occupied[substream->stream]) 24662306a36Sopenharmony_ci return -EBUSY; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci ret = mt2701_mclk_configuration(afe, mode ? 1 : i2s_num); 24962306a36Sopenharmony_ci if (ret) 25062306a36Sopenharmony_ci return ret; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci i2s_path->occupied[substream->stream] = 1; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* need to enable i2s-out path when enable i2s-in */ 25562306a36Sopenharmony_ci if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 25662306a36Sopenharmony_ci mt2701_i2s_path_enable(afe, i2s_path, !substream->stream, 25762306a36Sopenharmony_ci substream->runtime->rate); 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci mt2701_i2s_path_enable(afe, i2s_path, substream->stream, 26062306a36Sopenharmony_ci substream->runtime->rate); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci return 0; 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, 26662306a36Sopenharmony_ci unsigned int freq, int dir) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 26962306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 27062306a36Sopenharmony_ci int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); 27162306a36Sopenharmony_ci bool mode = afe_priv->soc->has_one_heart_mode; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci if (i2s_num < 0) 27462306a36Sopenharmony_ci return i2s_num; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci /* mclk */ 27762306a36Sopenharmony_ci if (dir == SND_SOC_CLOCK_IN) { 27862306a36Sopenharmony_ci dev_warn(dai->dev, "The SoCs doesn't support mclk input\n"); 27962306a36Sopenharmony_ci return -EINVAL; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci afe_priv->i2s_path[mode ? 1 : i2s_num].mclk_rate = freq; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci return 0; 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic int mt2701_btmrg_startup(struct snd_pcm_substream *substream, 28862306a36Sopenharmony_ci struct snd_soc_dai *dai) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 29162306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 29262306a36Sopenharmony_ci int ret; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci ret = mt2701_enable_btmrg_clk(afe); 29562306a36Sopenharmony_ci if (ret) 29662306a36Sopenharmony_ci return ret; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci afe_priv->mrg_enable[substream->stream] = 1; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci return 0; 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream, 30462306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 30562306a36Sopenharmony_ci struct snd_soc_dai *dai) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 30862306a36Sopenharmony_ci int stream_fs; 30962306a36Sopenharmony_ci u32 val, msk; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci stream_fs = params_rate(params); 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci if (stream_fs != 8000 && stream_fs != 16000) { 31462306a36Sopenharmony_ci dev_err(afe->dev, "unsupported rate %d\n", stream_fs); 31562306a36Sopenharmony_ci return -EINVAL; 31662306a36Sopenharmony_ci } 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 31962306a36Sopenharmony_ci AFE_MRGIF_CON_I2S_MODE_MASK, 32062306a36Sopenharmony_ci AFE_MRGIF_CON_I2S_MODE_32K); 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY 32362306a36Sopenharmony_ci | AFE_DAIBT_CON0_MRG_USE; 32462306a36Sopenharmony_ci msk = val; 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci if (stream_fs == 16000) 32762306a36Sopenharmony_ci val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, 33462306a36Sopenharmony_ci AFE_DAIBT_CON0_DAIBT_EN, 33562306a36Sopenharmony_ci AFE_DAIBT_CON0_DAIBT_EN); 33662306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 33762306a36Sopenharmony_ci AFE_MRGIF_CON_MRG_I2S_EN, 33862306a36Sopenharmony_ci AFE_MRGIF_CON_MRG_I2S_EN); 33962306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 34062306a36Sopenharmony_ci AFE_MRGIF_CON_MRG_EN, 34162306a36Sopenharmony_ci AFE_MRGIF_CON_MRG_EN); 34262306a36Sopenharmony_ci return 0; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream, 34662306a36Sopenharmony_ci struct snd_soc_dai *dai) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 34962306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv = afe->platform_priv; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci /* if the other direction stream is not occupied */ 35262306a36Sopenharmony_ci if (!afe_priv->mrg_enable[!substream->stream]) { 35362306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, 35462306a36Sopenharmony_ci AFE_DAIBT_CON0_DAIBT_EN, 0); 35562306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 35662306a36Sopenharmony_ci AFE_MRGIF_CON_MRG_EN, 0); 35762306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_MRGIF_CON, 35862306a36Sopenharmony_ci AFE_MRGIF_CON_MRG_I2S_EN, 0); 35962306a36Sopenharmony_ci mt2701_disable_btmrg_clk(afe); 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci afe_priv->mrg_enable[substream->stream] = 0; 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cistatic int mt2701_simple_fe_startup(struct snd_pcm_substream *substream, 36662306a36Sopenharmony_ci struct snd_soc_dai *dai) 36762306a36Sopenharmony_ci{ 36862306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 36962306a36Sopenharmony_ci struct mtk_base_afe_memif *memif_tmp; 37062306a36Sopenharmony_ci int stream_dir = substream->stream; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci /* can't run single DL & DLM at the same time */ 37362306a36Sopenharmony_ci if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) { 37462306a36Sopenharmony_ci memif_tmp = &afe->memif[MT2701_MEMIF_DLM]; 37562306a36Sopenharmony_ci if (memif_tmp->substream) { 37662306a36Sopenharmony_ci dev_warn(afe->dev, "memif is not available"); 37762306a36Sopenharmony_ci return -EBUSY; 37862306a36Sopenharmony_ci } 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci return mtk_afe_fe_startup(substream, dai); 38262306a36Sopenharmony_ci} 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_cistatic int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream, 38562306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 38662306a36Sopenharmony_ci struct snd_soc_dai *dai) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 38962306a36Sopenharmony_ci int stream_dir = substream->stream; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci /* single DL use PAIR_INTERLEAVE */ 39262306a36Sopenharmony_ci if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) 39362306a36Sopenharmony_ci regmap_update_bits(afe->regmap, 39462306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE, 39562306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_DLM_MASK, 39662306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci return mtk_afe_fe_hw_params(substream, params, dai); 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream, 40262306a36Sopenharmony_ci struct snd_soc_dai *dai) 40362306a36Sopenharmony_ci{ 40462306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 40562306a36Sopenharmony_ci struct mtk_base_afe_memif *memif_tmp; 40662306a36Sopenharmony_ci const struct mtk_base_memif_data *memif_data; 40762306a36Sopenharmony_ci int i; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) { 41062306a36Sopenharmony_ci memif_tmp = &afe->memif[i]; 41162306a36Sopenharmony_ci if (memif_tmp->substream) 41262306a36Sopenharmony_ci return -EBUSY; 41362306a36Sopenharmony_ci } 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci /* enable agent for all signal DL (due to hw design) */ 41662306a36Sopenharmony_ci for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) { 41762306a36Sopenharmony_ci memif_data = afe->memif[i].data; 41862306a36Sopenharmony_ci regmap_update_bits(afe->regmap, 41962306a36Sopenharmony_ci memif_data->agent_disable_reg, 42062306a36Sopenharmony_ci 1 << memif_data->agent_disable_shift, 42162306a36Sopenharmony_ci 0 << memif_data->agent_disable_shift); 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci return mtk_afe_fe_startup(substream, dai); 42562306a36Sopenharmony_ci} 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_cistatic void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream, 42862306a36Sopenharmony_ci struct snd_soc_dai *dai) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 43162306a36Sopenharmony_ci const struct mtk_base_memif_data *memif_data; 43262306a36Sopenharmony_ci int i; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) { 43562306a36Sopenharmony_ci memif_data = afe->memif[i].data; 43662306a36Sopenharmony_ci regmap_update_bits(afe->regmap, 43762306a36Sopenharmony_ci memif_data->agent_disable_reg, 43862306a36Sopenharmony_ci 1 << memif_data->agent_disable_shift, 43962306a36Sopenharmony_ci 1 << memif_data->agent_disable_shift); 44062306a36Sopenharmony_ci } 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci return mtk_afe_fe_shutdown(substream, dai); 44362306a36Sopenharmony_ci} 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_cistatic int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream, 44662306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 44762306a36Sopenharmony_ci struct snd_soc_dai *dai) 44862306a36Sopenharmony_ci{ 44962306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 45062306a36Sopenharmony_ci int channels = params_channels(params); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci regmap_update_bits(afe->regmap, 45362306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE, 45462306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_DLM_MASK, 45562306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE); 45662306a36Sopenharmony_ci regmap_update_bits(afe->regmap, 45762306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE, 45862306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK, 45962306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_DLM_32BYTES); 46062306a36Sopenharmony_ci regmap_update_bits(afe->regmap, 46162306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE, 46262306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK, 46362306a36Sopenharmony_ci AFE_MEMIF_PBUF_SIZE_DLM_CH(channels)); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci return mtk_afe_fe_hw_params(substream, params, dai); 46662306a36Sopenharmony_ci} 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cistatic int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream, 46962306a36Sopenharmony_ci int cmd, struct snd_soc_dai *dai) 47062306a36Sopenharmony_ci{ 47162306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 47262306a36Sopenharmony_ci struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1]; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci switch (cmd) { 47562306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_START: 47662306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_RESUME: 47762306a36Sopenharmony_ci regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg, 47862306a36Sopenharmony_ci 1 << memif_tmp->data->enable_shift, 47962306a36Sopenharmony_ci 1 << memif_tmp->data->enable_shift); 48062306a36Sopenharmony_ci mtk_afe_fe_trigger(substream, cmd, dai); 48162306a36Sopenharmony_ci return 0; 48262306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_STOP: 48362306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_SUSPEND: 48462306a36Sopenharmony_ci mtk_afe_fe_trigger(substream, cmd, dai); 48562306a36Sopenharmony_ci regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg, 48662306a36Sopenharmony_ci 1 << memif_tmp->data->enable_shift, 0); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci return 0; 48962306a36Sopenharmony_ci default: 49062306a36Sopenharmony_ci return -EINVAL; 49162306a36Sopenharmony_ci } 49262306a36Sopenharmony_ci} 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_cistatic int mt2701_memif_fs(struct snd_pcm_substream *substream, 49562306a36Sopenharmony_ci unsigned int rate) 49662306a36Sopenharmony_ci{ 49762306a36Sopenharmony_ci struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 49862306a36Sopenharmony_ci int fs; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci if (asoc_rtd_to_cpu(rtd, 0)->id != MT2701_MEMIF_ULBT) 50162306a36Sopenharmony_ci fs = mt2701_afe_i2s_fs(rate); 50262306a36Sopenharmony_ci else 50362306a36Sopenharmony_ci fs = (rate == 16000 ? 1 : 0); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci return fs; 50662306a36Sopenharmony_ci} 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_cistatic int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate) 50962306a36Sopenharmony_ci{ 51062306a36Sopenharmony_ci return mt2701_afe_i2s_fs(rate); 51162306a36Sopenharmony_ci} 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci/* FE DAIs */ 51462306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = { 51562306a36Sopenharmony_ci .startup = mt2701_simple_fe_startup, 51662306a36Sopenharmony_ci .shutdown = mtk_afe_fe_shutdown, 51762306a36Sopenharmony_ci .hw_params = mt2701_simple_fe_hw_params, 51862306a36Sopenharmony_ci .hw_free = mtk_afe_fe_hw_free, 51962306a36Sopenharmony_ci .prepare = mtk_afe_fe_prepare, 52062306a36Sopenharmony_ci .trigger = mtk_afe_fe_trigger, 52162306a36Sopenharmony_ci}; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = { 52462306a36Sopenharmony_ci .startup = mt2701_dlm_fe_startup, 52562306a36Sopenharmony_ci .shutdown = mt2701_dlm_fe_shutdown, 52662306a36Sopenharmony_ci .hw_params = mt2701_dlm_fe_hw_params, 52762306a36Sopenharmony_ci .hw_free = mtk_afe_fe_hw_free, 52862306a36Sopenharmony_ci .prepare = mtk_afe_fe_prepare, 52962306a36Sopenharmony_ci .trigger = mt2701_dlm_fe_trigger, 53062306a36Sopenharmony_ci}; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci/* I2S BE DAIs */ 53362306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mt2701_afe_i2s_ops = { 53462306a36Sopenharmony_ci .startup = mt2701_afe_i2s_startup, 53562306a36Sopenharmony_ci .shutdown = mt2701_afe_i2s_shutdown, 53662306a36Sopenharmony_ci .prepare = mt2701_afe_i2s_prepare, 53762306a36Sopenharmony_ci .set_sysclk = mt2701_afe_i2s_set_sysclk, 53862306a36Sopenharmony_ci}; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci/* MRG BE DAIs */ 54162306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mt2701_btmrg_ops = { 54262306a36Sopenharmony_ci .startup = mt2701_btmrg_startup, 54362306a36Sopenharmony_ci .shutdown = mt2701_btmrg_shutdown, 54462306a36Sopenharmony_ci .hw_params = mt2701_btmrg_hw_params, 54562306a36Sopenharmony_ci}; 54662306a36Sopenharmony_ci 54762306a36Sopenharmony_cistatic struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = { 54862306a36Sopenharmony_ci /* FE DAIs: memory intefaces to CPU */ 54962306a36Sopenharmony_ci { 55062306a36Sopenharmony_ci .name = "PCMO0", 55162306a36Sopenharmony_ci .id = MT2701_MEMIF_DL1, 55262306a36Sopenharmony_ci .playback = { 55362306a36Sopenharmony_ci .stream_name = "DL1", 55462306a36Sopenharmony_ci .channels_min = 1, 55562306a36Sopenharmony_ci .channels_max = 2, 55662306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 55762306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 55862306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 55962306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 56062306a36Sopenharmony_ci }, 56162306a36Sopenharmony_ci .ops = &mt2701_single_memif_dai_ops, 56262306a36Sopenharmony_ci }, 56362306a36Sopenharmony_ci { 56462306a36Sopenharmony_ci .name = "PCM_multi", 56562306a36Sopenharmony_ci .id = MT2701_MEMIF_DLM, 56662306a36Sopenharmony_ci .playback = { 56762306a36Sopenharmony_ci .stream_name = "DLM", 56862306a36Sopenharmony_ci .channels_min = 1, 56962306a36Sopenharmony_ci .channels_max = 8, 57062306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 57162306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 57262306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 57362306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci }, 57662306a36Sopenharmony_ci .ops = &mt2701_dlm_memif_dai_ops, 57762306a36Sopenharmony_ci }, 57862306a36Sopenharmony_ci { 57962306a36Sopenharmony_ci .name = "PCM0", 58062306a36Sopenharmony_ci .id = MT2701_MEMIF_UL1, 58162306a36Sopenharmony_ci .capture = { 58262306a36Sopenharmony_ci .stream_name = "UL1", 58362306a36Sopenharmony_ci .channels_min = 1, 58462306a36Sopenharmony_ci .channels_max = 2, 58562306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_48000, 58662306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 58762306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 58862306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 58962306a36Sopenharmony_ci }, 59062306a36Sopenharmony_ci .ops = &mt2701_single_memif_dai_ops, 59162306a36Sopenharmony_ci }, 59262306a36Sopenharmony_ci { 59362306a36Sopenharmony_ci .name = "PCM1", 59462306a36Sopenharmony_ci .id = MT2701_MEMIF_UL2, 59562306a36Sopenharmony_ci .capture = { 59662306a36Sopenharmony_ci .stream_name = "UL2", 59762306a36Sopenharmony_ci .channels_min = 1, 59862306a36Sopenharmony_ci .channels_max = 2, 59962306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 60062306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 60162306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 60262306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ci }, 60562306a36Sopenharmony_ci .ops = &mt2701_single_memif_dai_ops, 60662306a36Sopenharmony_ci }, 60762306a36Sopenharmony_ci { 60862306a36Sopenharmony_ci .name = "PCM_BT_DL", 60962306a36Sopenharmony_ci .id = MT2701_MEMIF_DLBT, 61062306a36Sopenharmony_ci .playback = { 61162306a36Sopenharmony_ci .stream_name = "DLBT", 61262306a36Sopenharmony_ci .channels_min = 1, 61362306a36Sopenharmony_ci .channels_max = 1, 61462306a36Sopenharmony_ci .rates = (SNDRV_PCM_RATE_8000 61562306a36Sopenharmony_ci | SNDRV_PCM_RATE_16000), 61662306a36Sopenharmony_ci .formats = SNDRV_PCM_FMTBIT_S16_LE, 61762306a36Sopenharmony_ci }, 61862306a36Sopenharmony_ci .ops = &mt2701_single_memif_dai_ops, 61962306a36Sopenharmony_ci }, 62062306a36Sopenharmony_ci { 62162306a36Sopenharmony_ci .name = "PCM_BT_UL", 62262306a36Sopenharmony_ci .id = MT2701_MEMIF_ULBT, 62362306a36Sopenharmony_ci .capture = { 62462306a36Sopenharmony_ci .stream_name = "ULBT", 62562306a36Sopenharmony_ci .channels_min = 1, 62662306a36Sopenharmony_ci .channels_max = 1, 62762306a36Sopenharmony_ci .rates = (SNDRV_PCM_RATE_8000 62862306a36Sopenharmony_ci | SNDRV_PCM_RATE_16000), 62962306a36Sopenharmony_ci .formats = SNDRV_PCM_FMTBIT_S16_LE, 63062306a36Sopenharmony_ci }, 63162306a36Sopenharmony_ci .ops = &mt2701_single_memif_dai_ops, 63262306a36Sopenharmony_ci }, 63362306a36Sopenharmony_ci /* BE DAIs */ 63462306a36Sopenharmony_ci { 63562306a36Sopenharmony_ci .name = "I2S0", 63662306a36Sopenharmony_ci .id = MT2701_IO_I2S, 63762306a36Sopenharmony_ci .playback = { 63862306a36Sopenharmony_ci .stream_name = "I2S0 Playback", 63962306a36Sopenharmony_ci .channels_min = 1, 64062306a36Sopenharmony_ci .channels_max = 2, 64162306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 64262306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 64362306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 64462306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci }, 64762306a36Sopenharmony_ci .capture = { 64862306a36Sopenharmony_ci .stream_name = "I2S0 Capture", 64962306a36Sopenharmony_ci .channels_min = 1, 65062306a36Sopenharmony_ci .channels_max = 2, 65162306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 65262306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 65362306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 65462306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci }, 65762306a36Sopenharmony_ci .ops = &mt2701_afe_i2s_ops, 65862306a36Sopenharmony_ci .symmetric_rate = 1, 65962306a36Sopenharmony_ci }, 66062306a36Sopenharmony_ci { 66162306a36Sopenharmony_ci .name = "I2S1", 66262306a36Sopenharmony_ci .id = MT2701_IO_2ND_I2S, 66362306a36Sopenharmony_ci .playback = { 66462306a36Sopenharmony_ci .stream_name = "I2S1 Playback", 66562306a36Sopenharmony_ci .channels_min = 1, 66662306a36Sopenharmony_ci .channels_max = 2, 66762306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 66862306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 66962306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 67062306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 67162306a36Sopenharmony_ci }, 67262306a36Sopenharmony_ci .capture = { 67362306a36Sopenharmony_ci .stream_name = "I2S1 Capture", 67462306a36Sopenharmony_ci .channels_min = 1, 67562306a36Sopenharmony_ci .channels_max = 2, 67662306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 67762306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 67862306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 67962306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 68062306a36Sopenharmony_ci }, 68162306a36Sopenharmony_ci .ops = &mt2701_afe_i2s_ops, 68262306a36Sopenharmony_ci .symmetric_rate = 1, 68362306a36Sopenharmony_ci }, 68462306a36Sopenharmony_ci { 68562306a36Sopenharmony_ci .name = "I2S2", 68662306a36Sopenharmony_ci .id = MT2701_IO_3RD_I2S, 68762306a36Sopenharmony_ci .playback = { 68862306a36Sopenharmony_ci .stream_name = "I2S2 Playback", 68962306a36Sopenharmony_ci .channels_min = 1, 69062306a36Sopenharmony_ci .channels_max = 2, 69162306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 69262306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 69362306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 69462306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 69562306a36Sopenharmony_ci }, 69662306a36Sopenharmony_ci .capture = { 69762306a36Sopenharmony_ci .stream_name = "I2S2 Capture", 69862306a36Sopenharmony_ci .channels_min = 1, 69962306a36Sopenharmony_ci .channels_max = 2, 70062306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 70162306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 70262306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 70362306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 70462306a36Sopenharmony_ci }, 70562306a36Sopenharmony_ci .ops = &mt2701_afe_i2s_ops, 70662306a36Sopenharmony_ci .symmetric_rate = 1, 70762306a36Sopenharmony_ci }, 70862306a36Sopenharmony_ci { 70962306a36Sopenharmony_ci .name = "I2S3", 71062306a36Sopenharmony_ci .id = MT2701_IO_4TH_I2S, 71162306a36Sopenharmony_ci .playback = { 71262306a36Sopenharmony_ci .stream_name = "I2S3 Playback", 71362306a36Sopenharmony_ci .channels_min = 1, 71462306a36Sopenharmony_ci .channels_max = 2, 71562306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 71662306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 71762306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 71862306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 71962306a36Sopenharmony_ci }, 72062306a36Sopenharmony_ci .capture = { 72162306a36Sopenharmony_ci .stream_name = "I2S3 Capture", 72262306a36Sopenharmony_ci .channels_min = 1, 72362306a36Sopenharmony_ci .channels_max = 2, 72462306a36Sopenharmony_ci .rates = SNDRV_PCM_RATE_8000_192000, 72562306a36Sopenharmony_ci .formats = (SNDRV_PCM_FMTBIT_S16_LE 72662306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S24_LE 72762306a36Sopenharmony_ci | SNDRV_PCM_FMTBIT_S32_LE) 72862306a36Sopenharmony_ci }, 72962306a36Sopenharmony_ci .ops = &mt2701_afe_i2s_ops, 73062306a36Sopenharmony_ci .symmetric_rate = 1, 73162306a36Sopenharmony_ci }, 73262306a36Sopenharmony_ci { 73362306a36Sopenharmony_ci .name = "MRG BT", 73462306a36Sopenharmony_ci .id = MT2701_IO_MRG, 73562306a36Sopenharmony_ci .playback = { 73662306a36Sopenharmony_ci .stream_name = "BT Playback", 73762306a36Sopenharmony_ci .channels_min = 1, 73862306a36Sopenharmony_ci .channels_max = 1, 73962306a36Sopenharmony_ci .rates = (SNDRV_PCM_RATE_8000 74062306a36Sopenharmony_ci | SNDRV_PCM_RATE_16000), 74162306a36Sopenharmony_ci .formats = SNDRV_PCM_FMTBIT_S16_LE, 74262306a36Sopenharmony_ci }, 74362306a36Sopenharmony_ci .capture = { 74462306a36Sopenharmony_ci .stream_name = "BT Capture", 74562306a36Sopenharmony_ci .channels_min = 1, 74662306a36Sopenharmony_ci .channels_max = 1, 74762306a36Sopenharmony_ci .rates = (SNDRV_PCM_RATE_8000 74862306a36Sopenharmony_ci | SNDRV_PCM_RATE_16000), 74962306a36Sopenharmony_ci .formats = SNDRV_PCM_FMTBIT_S16_LE, 75062306a36Sopenharmony_ci }, 75162306a36Sopenharmony_ci .ops = &mt2701_btmrg_ops, 75262306a36Sopenharmony_ci .symmetric_rate = 1, 75362306a36Sopenharmony_ci } 75462306a36Sopenharmony_ci}; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o00_mix[] = { 75762306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0), 75862306a36Sopenharmony_ci}; 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o01_mix[] = { 76162306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0), 76262306a36Sopenharmony_ci}; 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o02_mix[] = { 76562306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0), 76662306a36Sopenharmony_ci}; 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o03_mix[] = { 76962306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0), 77062306a36Sopenharmony_ci}; 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o14_mix[] = { 77362306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0), 77462306a36Sopenharmony_ci}; 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o15_mix[] = { 77762306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0), 77862306a36Sopenharmony_ci}; 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o16_mix[] = { 78162306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0), 78262306a36Sopenharmony_ci}; 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o17_mix[] = { 78562306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0), 78662306a36Sopenharmony_ci}; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o18_mix[] = { 78962306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0), 79062306a36Sopenharmony_ci}; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o19_mix[] = { 79362306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0), 79462306a36Sopenharmony_ci}; 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o20_mix[] = { 79762306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0), 79862306a36Sopenharmony_ci}; 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o21_mix[] = { 80162306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0), 80262306a36Sopenharmony_ci}; 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o22_mix[] = { 80562306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0), 80662306a36Sopenharmony_ci}; 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_o31_mix[] = { 80962306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0), 81062306a36Sopenharmony_ci}; 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_i02_mix[] = { 81362306a36Sopenharmony_ci SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0), 81462306a36Sopenharmony_ci}; 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = { 81762306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch", 81862306a36Sopenharmony_ci ASYS_I2SO1_CON, 26, 1, 0), 81962306a36Sopenharmony_ci}; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = { 82262306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch", 82362306a36Sopenharmony_ci ASYS_I2SO2_CON, 26, 1, 0), 82462306a36Sopenharmony_ci}; 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = { 82762306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch", 82862306a36Sopenharmony_ci PWR2_TOP_CON, 17, 1, 0), 82962306a36Sopenharmony_ci}; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_cistatic const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = { 83262306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch", 83362306a36Sopenharmony_ci PWR2_TOP_CON, 18, 1, 0), 83462306a36Sopenharmony_ci}; 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { 83762306a36Sopenharmony_ci /* inter-connections */ 83862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), 83962306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0), 84062306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix, 84162306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_i02_mix)), 84262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0), 84362306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0), 84462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0), 84562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0), 84662306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0), 84762306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0), 84862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0), 84962306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0), 85062306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0), 85162306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0), 85262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0), 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix, 85562306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o00_mix)), 85662306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix, 85762306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o01_mix)), 85862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix, 85962306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o02_mix)), 86062306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix, 86162306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o03_mix)), 86262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix, 86362306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o14_mix)), 86462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix, 86562306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o15_mix)), 86662306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix, 86762306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o16_mix)), 86862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix, 86962306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o17_mix)), 87062306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix, 87162306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o18_mix)), 87262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix, 87362306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o19_mix)), 87462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix, 87562306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o20_mix)), 87662306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix, 87762306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o21_mix)), 87862306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix, 87962306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o22_mix)), 88062306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix, 88162306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_o31_mix)), 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0, 88462306a36Sopenharmony_ci mt2701_afe_multi_ch_out_i2s0, 88562306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)), 88662306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0, 88762306a36Sopenharmony_ci mt2701_afe_multi_ch_out_i2s1, 88862306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)), 88962306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0, 89062306a36Sopenharmony_ci mt2701_afe_multi_ch_out_i2s2, 89162306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)), 89262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0, 89362306a36Sopenharmony_ci mt2701_afe_multi_ch_out_i2s3, 89462306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)), 89562306a36Sopenharmony_ci}; 89662306a36Sopenharmony_ci 89762306a36Sopenharmony_cistatic const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { 89862306a36Sopenharmony_ci {"I12", NULL, "DL1"}, 89962306a36Sopenharmony_ci {"I13", NULL, "DL1"}, 90062306a36Sopenharmony_ci {"I35", NULL, "DLBT"}, 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci {"I2S0 Playback", NULL, "O15"}, 90362306a36Sopenharmony_ci {"I2S0 Playback", NULL, "O16"}, 90462306a36Sopenharmony_ci {"I2S1 Playback", NULL, "O17"}, 90562306a36Sopenharmony_ci {"I2S1 Playback", NULL, "O18"}, 90662306a36Sopenharmony_ci {"I2S2 Playback", NULL, "O19"}, 90762306a36Sopenharmony_ci {"I2S2 Playback", NULL, "O20"}, 90862306a36Sopenharmony_ci {"I2S3 Playback", NULL, "O21"}, 90962306a36Sopenharmony_ci {"I2S3 Playback", NULL, "O22"}, 91062306a36Sopenharmony_ci {"BT Playback", NULL, "O31"}, 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci {"UL1", NULL, "O00"}, 91362306a36Sopenharmony_ci {"UL1", NULL, "O01"}, 91462306a36Sopenharmony_ci {"UL2", NULL, "O02"}, 91562306a36Sopenharmony_ci {"UL2", NULL, "O03"}, 91662306a36Sopenharmony_ci {"ULBT", NULL, "O14"}, 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci {"I00", NULL, "I2S0 Capture"}, 91962306a36Sopenharmony_ci {"I01", NULL, "I2S0 Capture"}, 92062306a36Sopenharmony_ci {"I02", NULL, "I2S1 Capture"}, 92162306a36Sopenharmony_ci {"I03", NULL, "I2S1 Capture"}, 92262306a36Sopenharmony_ci /* I02,03 link to UL2, also need to open I2S0 */ 92362306a36Sopenharmony_ci {"I02", "I2S0 Switch", "I2S0 Capture"}, 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci {"I26", NULL, "BT Capture"}, 92662306a36Sopenharmony_ci 92762306a36Sopenharmony_ci {"I12I13", "Multich I2S0 Out Switch", "DLM"}, 92862306a36Sopenharmony_ci {"I14I15", "Multich I2S1 Out Switch", "DLM"}, 92962306a36Sopenharmony_ci {"I16I17", "Multich I2S2 Out Switch", "DLM"}, 93062306a36Sopenharmony_ci {"I18I19", "Multich I2S3 Out Switch", "DLM"}, 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci { "I12", NULL, "I12I13" }, 93362306a36Sopenharmony_ci { "I13", NULL, "I12I13" }, 93462306a36Sopenharmony_ci { "I14", NULL, "I14I15" }, 93562306a36Sopenharmony_ci { "I15", NULL, "I14I15" }, 93662306a36Sopenharmony_ci { "I16", NULL, "I16I17" }, 93762306a36Sopenharmony_ci { "I17", NULL, "I16I17" }, 93862306a36Sopenharmony_ci { "I18", NULL, "I18I19" }, 93962306a36Sopenharmony_ci { "I19", NULL, "I18I19" }, 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci { "O00", "I00 Switch", "I00" }, 94262306a36Sopenharmony_ci { "O01", "I01 Switch", "I01" }, 94362306a36Sopenharmony_ci { "O02", "I02 Switch", "I02" }, 94462306a36Sopenharmony_ci { "O03", "I03 Switch", "I03" }, 94562306a36Sopenharmony_ci { "O14", "I26 Switch", "I26" }, 94662306a36Sopenharmony_ci { "O15", "I12 Switch", "I12" }, 94762306a36Sopenharmony_ci { "O16", "I13 Switch", "I13" }, 94862306a36Sopenharmony_ci { "O17", "I14 Switch", "I14" }, 94962306a36Sopenharmony_ci { "O18", "I15 Switch", "I15" }, 95062306a36Sopenharmony_ci { "O19", "I16 Switch", "I16" }, 95162306a36Sopenharmony_ci { "O20", "I17 Switch", "I17" }, 95262306a36Sopenharmony_ci { "O21", "I18 Switch", "I18" }, 95362306a36Sopenharmony_ci { "O22", "I19 Switch", "I19" }, 95462306a36Sopenharmony_ci { "O31", "I35 Switch", "I35" }, 95562306a36Sopenharmony_ci}; 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_cistatic int mt2701_afe_pcm_probe(struct snd_soc_component *component) 95862306a36Sopenharmony_ci{ 95962306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_ci snd_soc_component_init_regmap(component, afe->regmap); 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci return 0; 96462306a36Sopenharmony_ci} 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_cistatic const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = { 96762306a36Sopenharmony_ci .probe = mt2701_afe_pcm_probe, 96862306a36Sopenharmony_ci .name = "mt2701-afe-pcm-dai", 96962306a36Sopenharmony_ci .dapm_widgets = mt2701_afe_pcm_widgets, 97062306a36Sopenharmony_ci .num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets), 97162306a36Sopenharmony_ci .dapm_routes = mt2701_afe_pcm_routes, 97262306a36Sopenharmony_ci .num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes), 97362306a36Sopenharmony_ci .suspend = mtk_afe_suspend, 97462306a36Sopenharmony_ci .resume = mtk_afe_resume, 97562306a36Sopenharmony_ci}; 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_cistatic const struct mtk_base_memif_data memif_data_array[MT2701_MEMIF_NUM] = { 97862306a36Sopenharmony_ci { 97962306a36Sopenharmony_ci .name = "DL1", 98062306a36Sopenharmony_ci .id = MT2701_MEMIF_DL1, 98162306a36Sopenharmony_ci .reg_ofs_base = AFE_DL1_BASE, 98262306a36Sopenharmony_ci .reg_ofs_cur = AFE_DL1_CUR, 98362306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON1, 98462306a36Sopenharmony_ci .fs_shift = 0, 98562306a36Sopenharmony_ci .fs_maskbit = 0x1f, 98662306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON3, 98762306a36Sopenharmony_ci .mono_shift = 16, 98862306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 98962306a36Sopenharmony_ci .enable_shift = 1, 99062306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 99162306a36Sopenharmony_ci .hd_shift = 0, 99262306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 99362306a36Sopenharmony_ci .agent_disable_shift = 6, 99462306a36Sopenharmony_ci .msb_reg = -1, 99562306a36Sopenharmony_ci }, 99662306a36Sopenharmony_ci { 99762306a36Sopenharmony_ci .name = "DL2", 99862306a36Sopenharmony_ci .id = MT2701_MEMIF_DL2, 99962306a36Sopenharmony_ci .reg_ofs_base = AFE_DL2_BASE, 100062306a36Sopenharmony_ci .reg_ofs_cur = AFE_DL2_CUR, 100162306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON1, 100262306a36Sopenharmony_ci .fs_shift = 5, 100362306a36Sopenharmony_ci .fs_maskbit = 0x1f, 100462306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON3, 100562306a36Sopenharmony_ci .mono_shift = 17, 100662306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 100762306a36Sopenharmony_ci .enable_shift = 2, 100862306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 100962306a36Sopenharmony_ci .hd_shift = 2, 101062306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 101162306a36Sopenharmony_ci .agent_disable_shift = 7, 101262306a36Sopenharmony_ci .msb_reg = -1, 101362306a36Sopenharmony_ci }, 101462306a36Sopenharmony_ci { 101562306a36Sopenharmony_ci .name = "DL3", 101662306a36Sopenharmony_ci .id = MT2701_MEMIF_DL3, 101762306a36Sopenharmony_ci .reg_ofs_base = AFE_DL3_BASE, 101862306a36Sopenharmony_ci .reg_ofs_cur = AFE_DL3_CUR, 101962306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON1, 102062306a36Sopenharmony_ci .fs_shift = 10, 102162306a36Sopenharmony_ci .fs_maskbit = 0x1f, 102262306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON3, 102362306a36Sopenharmony_ci .mono_shift = 18, 102462306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 102562306a36Sopenharmony_ci .enable_shift = 3, 102662306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 102762306a36Sopenharmony_ci .hd_shift = 4, 102862306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 102962306a36Sopenharmony_ci .agent_disable_shift = 8, 103062306a36Sopenharmony_ci .msb_reg = -1, 103162306a36Sopenharmony_ci }, 103262306a36Sopenharmony_ci { 103362306a36Sopenharmony_ci .name = "DL4", 103462306a36Sopenharmony_ci .id = MT2701_MEMIF_DL4, 103562306a36Sopenharmony_ci .reg_ofs_base = AFE_DL4_BASE, 103662306a36Sopenharmony_ci .reg_ofs_cur = AFE_DL4_CUR, 103762306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON1, 103862306a36Sopenharmony_ci .fs_shift = 15, 103962306a36Sopenharmony_ci .fs_maskbit = 0x1f, 104062306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON3, 104162306a36Sopenharmony_ci .mono_shift = 19, 104262306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 104362306a36Sopenharmony_ci .enable_shift = 4, 104462306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 104562306a36Sopenharmony_ci .hd_shift = 6, 104662306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 104762306a36Sopenharmony_ci .agent_disable_shift = 9, 104862306a36Sopenharmony_ci .msb_reg = -1, 104962306a36Sopenharmony_ci }, 105062306a36Sopenharmony_ci { 105162306a36Sopenharmony_ci .name = "DL5", 105262306a36Sopenharmony_ci .id = MT2701_MEMIF_DL5, 105362306a36Sopenharmony_ci .reg_ofs_base = AFE_DL5_BASE, 105462306a36Sopenharmony_ci .reg_ofs_cur = AFE_DL5_CUR, 105562306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON1, 105662306a36Sopenharmony_ci .fs_shift = 20, 105762306a36Sopenharmony_ci .fs_maskbit = 0x1f, 105862306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON3, 105962306a36Sopenharmony_ci .mono_shift = 20, 106062306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 106162306a36Sopenharmony_ci .enable_shift = 5, 106262306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 106362306a36Sopenharmony_ci .hd_shift = 8, 106462306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 106562306a36Sopenharmony_ci .agent_disable_shift = 10, 106662306a36Sopenharmony_ci .msb_reg = -1, 106762306a36Sopenharmony_ci }, 106862306a36Sopenharmony_ci { 106962306a36Sopenharmony_ci .name = "DLM", 107062306a36Sopenharmony_ci .id = MT2701_MEMIF_DLM, 107162306a36Sopenharmony_ci .reg_ofs_base = AFE_DLMCH_BASE, 107262306a36Sopenharmony_ci .reg_ofs_cur = AFE_DLMCH_CUR, 107362306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON1, 107462306a36Sopenharmony_ci .fs_shift = 0, 107562306a36Sopenharmony_ci .fs_maskbit = 0x1f, 107662306a36Sopenharmony_ci .mono_reg = -1, 107762306a36Sopenharmony_ci .mono_shift = -1, 107862306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 107962306a36Sopenharmony_ci .enable_shift = 7, 108062306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_PBUF_SIZE, 108162306a36Sopenharmony_ci .hd_shift = 28, 108262306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 108362306a36Sopenharmony_ci .agent_disable_shift = 12, 108462306a36Sopenharmony_ci .msb_reg = -1, 108562306a36Sopenharmony_ci }, 108662306a36Sopenharmony_ci { 108762306a36Sopenharmony_ci .name = "UL1", 108862306a36Sopenharmony_ci .id = MT2701_MEMIF_UL1, 108962306a36Sopenharmony_ci .reg_ofs_base = AFE_VUL_BASE, 109062306a36Sopenharmony_ci .reg_ofs_cur = AFE_VUL_CUR, 109162306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON2, 109262306a36Sopenharmony_ci .fs_shift = 0, 109362306a36Sopenharmony_ci .fs_maskbit = 0x1f, 109462306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON4, 109562306a36Sopenharmony_ci .mono_shift = 0, 109662306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 109762306a36Sopenharmony_ci .enable_shift = 10, 109862306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON1, 109962306a36Sopenharmony_ci .hd_shift = 0, 110062306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 110162306a36Sopenharmony_ci .agent_disable_shift = 0, 110262306a36Sopenharmony_ci .msb_reg = -1, 110362306a36Sopenharmony_ci }, 110462306a36Sopenharmony_ci { 110562306a36Sopenharmony_ci .name = "UL2", 110662306a36Sopenharmony_ci .id = MT2701_MEMIF_UL2, 110762306a36Sopenharmony_ci .reg_ofs_base = AFE_UL2_BASE, 110862306a36Sopenharmony_ci .reg_ofs_cur = AFE_UL2_CUR, 110962306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON2, 111062306a36Sopenharmony_ci .fs_shift = 5, 111162306a36Sopenharmony_ci .fs_maskbit = 0x1f, 111262306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON4, 111362306a36Sopenharmony_ci .mono_shift = 2, 111462306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 111562306a36Sopenharmony_ci .enable_shift = 11, 111662306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON1, 111762306a36Sopenharmony_ci .hd_shift = 2, 111862306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 111962306a36Sopenharmony_ci .agent_disable_shift = 1, 112062306a36Sopenharmony_ci .msb_reg = -1, 112162306a36Sopenharmony_ci }, 112262306a36Sopenharmony_ci { 112362306a36Sopenharmony_ci .name = "UL3", 112462306a36Sopenharmony_ci .id = MT2701_MEMIF_UL3, 112562306a36Sopenharmony_ci .reg_ofs_base = AFE_UL3_BASE, 112662306a36Sopenharmony_ci .reg_ofs_cur = AFE_UL3_CUR, 112762306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON2, 112862306a36Sopenharmony_ci .fs_shift = 10, 112962306a36Sopenharmony_ci .fs_maskbit = 0x1f, 113062306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON4, 113162306a36Sopenharmony_ci .mono_shift = 4, 113262306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 113362306a36Sopenharmony_ci .enable_shift = 12, 113462306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 113562306a36Sopenharmony_ci .hd_shift = 0, 113662306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 113762306a36Sopenharmony_ci .agent_disable_shift = 2, 113862306a36Sopenharmony_ci .msb_reg = -1, 113962306a36Sopenharmony_ci }, 114062306a36Sopenharmony_ci { 114162306a36Sopenharmony_ci .name = "UL4", 114262306a36Sopenharmony_ci .id = MT2701_MEMIF_UL4, 114362306a36Sopenharmony_ci .reg_ofs_base = AFE_UL4_BASE, 114462306a36Sopenharmony_ci .reg_ofs_cur = AFE_UL4_CUR, 114562306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON2, 114662306a36Sopenharmony_ci .fs_shift = 15, 114762306a36Sopenharmony_ci .fs_maskbit = 0x1f, 114862306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON4, 114962306a36Sopenharmony_ci .mono_shift = 6, 115062306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 115162306a36Sopenharmony_ci .enable_shift = 13, 115262306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 115362306a36Sopenharmony_ci .hd_shift = 6, 115462306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 115562306a36Sopenharmony_ci .agent_disable_shift = 3, 115662306a36Sopenharmony_ci .msb_reg = -1, 115762306a36Sopenharmony_ci }, 115862306a36Sopenharmony_ci { 115962306a36Sopenharmony_ci .name = "UL5", 116062306a36Sopenharmony_ci .id = MT2701_MEMIF_UL5, 116162306a36Sopenharmony_ci .reg_ofs_base = AFE_UL5_BASE, 116262306a36Sopenharmony_ci .reg_ofs_cur = AFE_UL5_CUR, 116362306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON2, 116462306a36Sopenharmony_ci .fs_shift = 20, 116562306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON4, 116662306a36Sopenharmony_ci .mono_shift = 8, 116762306a36Sopenharmony_ci .fs_maskbit = 0x1f, 116862306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 116962306a36Sopenharmony_ci .enable_shift = 14, 117062306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 117162306a36Sopenharmony_ci .hd_shift = 8, 117262306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 117362306a36Sopenharmony_ci .agent_disable_shift = 4, 117462306a36Sopenharmony_ci .msb_reg = -1, 117562306a36Sopenharmony_ci }, 117662306a36Sopenharmony_ci { 117762306a36Sopenharmony_ci .name = "DLBT", 117862306a36Sopenharmony_ci .id = MT2701_MEMIF_DLBT, 117962306a36Sopenharmony_ci .reg_ofs_base = AFE_ARB1_BASE, 118062306a36Sopenharmony_ci .reg_ofs_cur = AFE_ARB1_CUR, 118162306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON3, 118262306a36Sopenharmony_ci .fs_shift = 10, 118362306a36Sopenharmony_ci .fs_maskbit = 0x1f, 118462306a36Sopenharmony_ci .mono_reg = AFE_DAC_CON3, 118562306a36Sopenharmony_ci .mono_shift = 22, 118662306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 118762306a36Sopenharmony_ci .enable_shift = 8, 118862306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON0, 118962306a36Sopenharmony_ci .hd_shift = 14, 119062306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 119162306a36Sopenharmony_ci .agent_disable_shift = 13, 119262306a36Sopenharmony_ci .msb_reg = -1, 119362306a36Sopenharmony_ci }, 119462306a36Sopenharmony_ci { 119562306a36Sopenharmony_ci .name = "ULBT", 119662306a36Sopenharmony_ci .id = MT2701_MEMIF_ULBT, 119762306a36Sopenharmony_ci .reg_ofs_base = AFE_DAI_BASE, 119862306a36Sopenharmony_ci .reg_ofs_cur = AFE_DAI_CUR, 119962306a36Sopenharmony_ci .fs_reg = AFE_DAC_CON2, 120062306a36Sopenharmony_ci .fs_shift = 30, 120162306a36Sopenharmony_ci .fs_maskbit = 0x1, 120262306a36Sopenharmony_ci .mono_reg = -1, 120362306a36Sopenharmony_ci .mono_shift = -1, 120462306a36Sopenharmony_ci .enable_reg = AFE_DAC_CON0, 120562306a36Sopenharmony_ci .enable_shift = 17, 120662306a36Sopenharmony_ci .hd_reg = AFE_MEMIF_HD_CON1, 120762306a36Sopenharmony_ci .hd_shift = 20, 120862306a36Sopenharmony_ci .agent_disable_reg = AUDIO_TOP_CON5, 120962306a36Sopenharmony_ci .agent_disable_shift = 16, 121062306a36Sopenharmony_ci .msb_reg = -1, 121162306a36Sopenharmony_ci }, 121262306a36Sopenharmony_ci}; 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_cistatic const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = { 121562306a36Sopenharmony_ci { 121662306a36Sopenharmony_ci .id = MT2701_IRQ_ASYS_IRQ1, 121762306a36Sopenharmony_ci .irq_cnt_reg = ASYS_IRQ1_CON, 121862306a36Sopenharmony_ci .irq_cnt_shift = 0, 121962306a36Sopenharmony_ci .irq_cnt_maskbit = 0xffffff, 122062306a36Sopenharmony_ci .irq_fs_reg = ASYS_IRQ1_CON, 122162306a36Sopenharmony_ci .irq_fs_shift = 24, 122262306a36Sopenharmony_ci .irq_fs_maskbit = 0x1f, 122362306a36Sopenharmony_ci .irq_en_reg = ASYS_IRQ1_CON, 122462306a36Sopenharmony_ci .irq_en_shift = 31, 122562306a36Sopenharmony_ci .irq_clr_reg = ASYS_IRQ_CLR, 122662306a36Sopenharmony_ci .irq_clr_shift = 0, 122762306a36Sopenharmony_ci }, 122862306a36Sopenharmony_ci { 122962306a36Sopenharmony_ci .id = MT2701_IRQ_ASYS_IRQ2, 123062306a36Sopenharmony_ci .irq_cnt_reg = ASYS_IRQ2_CON, 123162306a36Sopenharmony_ci .irq_cnt_shift = 0, 123262306a36Sopenharmony_ci .irq_cnt_maskbit = 0xffffff, 123362306a36Sopenharmony_ci .irq_fs_reg = ASYS_IRQ2_CON, 123462306a36Sopenharmony_ci .irq_fs_shift = 24, 123562306a36Sopenharmony_ci .irq_fs_maskbit = 0x1f, 123662306a36Sopenharmony_ci .irq_en_reg = ASYS_IRQ2_CON, 123762306a36Sopenharmony_ci .irq_en_shift = 31, 123862306a36Sopenharmony_ci .irq_clr_reg = ASYS_IRQ_CLR, 123962306a36Sopenharmony_ci .irq_clr_shift = 1, 124062306a36Sopenharmony_ci }, 124162306a36Sopenharmony_ci { 124262306a36Sopenharmony_ci .id = MT2701_IRQ_ASYS_IRQ3, 124362306a36Sopenharmony_ci .irq_cnt_reg = ASYS_IRQ3_CON, 124462306a36Sopenharmony_ci .irq_cnt_shift = 0, 124562306a36Sopenharmony_ci .irq_cnt_maskbit = 0xffffff, 124662306a36Sopenharmony_ci .irq_fs_reg = ASYS_IRQ3_CON, 124762306a36Sopenharmony_ci .irq_fs_shift = 24, 124862306a36Sopenharmony_ci .irq_fs_maskbit = 0x1f, 124962306a36Sopenharmony_ci .irq_en_reg = ASYS_IRQ3_CON, 125062306a36Sopenharmony_ci .irq_en_shift = 31, 125162306a36Sopenharmony_ci .irq_clr_reg = ASYS_IRQ_CLR, 125262306a36Sopenharmony_ci .irq_clr_shift = 2, 125362306a36Sopenharmony_ci } 125462306a36Sopenharmony_ci}; 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_cistatic const struct mt2701_i2s_data mt2701_i2s_data[][2] = { 125762306a36Sopenharmony_ci { 125862306a36Sopenharmony_ci { ASYS_I2SO1_CON, 0, 0x1f }, 125962306a36Sopenharmony_ci { ASYS_I2SIN1_CON, 0, 0x1f }, 126062306a36Sopenharmony_ci }, 126162306a36Sopenharmony_ci { 126262306a36Sopenharmony_ci { ASYS_I2SO2_CON, 5, 0x1f }, 126362306a36Sopenharmony_ci { ASYS_I2SIN2_CON, 5, 0x1f }, 126462306a36Sopenharmony_ci }, 126562306a36Sopenharmony_ci { 126662306a36Sopenharmony_ci { ASYS_I2SO3_CON, 10, 0x1f }, 126762306a36Sopenharmony_ci { ASYS_I2SIN3_CON, 10, 0x1f }, 126862306a36Sopenharmony_ci }, 126962306a36Sopenharmony_ci { 127062306a36Sopenharmony_ci { ASYS_I2SO4_CON, 15, 0x1f }, 127162306a36Sopenharmony_ci { ASYS_I2SIN4_CON, 15, 0x1f }, 127262306a36Sopenharmony_ci }, 127362306a36Sopenharmony_ci /* TODO - extend control registers supported by newer SoCs */ 127462306a36Sopenharmony_ci}; 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_cistatic irqreturn_t mt2701_asys_isr(int irq_id, void *dev) 127762306a36Sopenharmony_ci{ 127862306a36Sopenharmony_ci int id; 127962306a36Sopenharmony_ci struct mtk_base_afe *afe = dev; 128062306a36Sopenharmony_ci struct mtk_base_afe_memif *memif; 128162306a36Sopenharmony_ci struct mtk_base_afe_irq *irq; 128262306a36Sopenharmony_ci u32 status; 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status); 128562306a36Sopenharmony_ci regmap_write(afe->regmap, ASYS_IRQ_CLR, status); 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_ci for (id = 0; id < MT2701_MEMIF_NUM; ++id) { 128862306a36Sopenharmony_ci memif = &afe->memif[id]; 128962306a36Sopenharmony_ci if (memif->irq_usage < 0) 129062306a36Sopenharmony_ci continue; 129162306a36Sopenharmony_ci 129262306a36Sopenharmony_ci irq = &afe->irqs[memif->irq_usage]; 129362306a36Sopenharmony_ci if (status & 1 << irq->irq_data->irq_clr_shift) 129462306a36Sopenharmony_ci snd_pcm_period_elapsed(memif->substream); 129562306a36Sopenharmony_ci } 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci return IRQ_HANDLED; 129862306a36Sopenharmony_ci} 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_cistatic int mt2701_afe_runtime_suspend(struct device *dev) 130162306a36Sopenharmony_ci{ 130262306a36Sopenharmony_ci struct mtk_base_afe *afe = dev_get_drvdata(dev); 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci return mt2701_afe_disable_clock(afe); 130562306a36Sopenharmony_ci} 130662306a36Sopenharmony_ci 130762306a36Sopenharmony_cistatic int mt2701_afe_runtime_resume(struct device *dev) 130862306a36Sopenharmony_ci{ 130962306a36Sopenharmony_ci struct mtk_base_afe *afe = dev_get_drvdata(dev); 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_ci return mt2701_afe_enable_clock(afe); 131262306a36Sopenharmony_ci} 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_cistatic int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) 131562306a36Sopenharmony_ci{ 131662306a36Sopenharmony_ci struct mtk_base_afe *afe; 131762306a36Sopenharmony_ci struct mt2701_afe_private *afe_priv; 131862306a36Sopenharmony_ci struct device *dev; 131962306a36Sopenharmony_ci int i, irq_id, ret; 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); 132262306a36Sopenharmony_ci if (!afe) 132362306a36Sopenharmony_ci return -ENOMEM; 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), 132662306a36Sopenharmony_ci GFP_KERNEL); 132762306a36Sopenharmony_ci if (!afe->platform_priv) 132862306a36Sopenharmony_ci return -ENOMEM; 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci afe_priv = afe->platform_priv; 133162306a36Sopenharmony_ci afe_priv->soc = of_device_get_match_data(&pdev->dev); 133262306a36Sopenharmony_ci afe->dev = &pdev->dev; 133362306a36Sopenharmony_ci dev = afe->dev; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci afe_priv->i2s_path = devm_kcalloc(dev, 133662306a36Sopenharmony_ci afe_priv->soc->i2s_num, 133762306a36Sopenharmony_ci sizeof(struct mt2701_i2s_path), 133862306a36Sopenharmony_ci GFP_KERNEL); 133962306a36Sopenharmony_ci if (!afe_priv->i2s_path) 134062306a36Sopenharmony_ci return -ENOMEM; 134162306a36Sopenharmony_ci 134262306a36Sopenharmony_ci irq_id = platform_get_irq_byname(pdev, "asys"); 134362306a36Sopenharmony_ci if (irq_id < 0) 134462306a36Sopenharmony_ci return irq_id; 134562306a36Sopenharmony_ci 134662306a36Sopenharmony_ci ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, 134762306a36Sopenharmony_ci IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); 134862306a36Sopenharmony_ci if (ret) { 134962306a36Sopenharmony_ci dev_err(dev, "could not request_irq for asys-isr\n"); 135062306a36Sopenharmony_ci return ret; 135162306a36Sopenharmony_ci } 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_ci afe->regmap = syscon_node_to_regmap(dev->parent->of_node); 135462306a36Sopenharmony_ci if (IS_ERR(afe->regmap)) { 135562306a36Sopenharmony_ci dev_err(dev, "could not get regmap from parent\n"); 135662306a36Sopenharmony_ci return PTR_ERR(afe->regmap); 135762306a36Sopenharmony_ci } 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci mutex_init(&afe->irq_alloc_lock); 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci /* memif initialize */ 136262306a36Sopenharmony_ci afe->memif_size = MT2701_MEMIF_NUM; 136362306a36Sopenharmony_ci afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), 136462306a36Sopenharmony_ci GFP_KERNEL); 136562306a36Sopenharmony_ci if (!afe->memif) 136662306a36Sopenharmony_ci return -ENOMEM; 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci for (i = 0; i < afe->memif_size; i++) { 136962306a36Sopenharmony_ci afe->memif[i].data = &memif_data_array[i]; 137062306a36Sopenharmony_ci afe->memif[i].irq_usage = -1; 137162306a36Sopenharmony_ci } 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci /* irq initialize */ 137462306a36Sopenharmony_ci afe->irqs_size = MT2701_IRQ_ASYS_END; 137562306a36Sopenharmony_ci afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), 137662306a36Sopenharmony_ci GFP_KERNEL); 137762306a36Sopenharmony_ci if (!afe->irqs) 137862306a36Sopenharmony_ci return -ENOMEM; 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci for (i = 0; i < afe->irqs_size; i++) 138162306a36Sopenharmony_ci afe->irqs[i].irq_data = &irq_data[i]; 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci /* I2S initialize */ 138462306a36Sopenharmony_ci for (i = 0; i < afe_priv->soc->i2s_num; i++) { 138562306a36Sopenharmony_ci afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_PLAYBACK] = 138662306a36Sopenharmony_ci &mt2701_i2s_data[i][SNDRV_PCM_STREAM_PLAYBACK]; 138762306a36Sopenharmony_ci afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_CAPTURE] = 138862306a36Sopenharmony_ci &mt2701_i2s_data[i][SNDRV_PCM_STREAM_CAPTURE]; 138962306a36Sopenharmony_ci } 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ci afe->mtk_afe_hardware = &mt2701_afe_hardware; 139262306a36Sopenharmony_ci afe->memif_fs = mt2701_memif_fs; 139362306a36Sopenharmony_ci afe->irq_fs = mt2701_irq_fs; 139462306a36Sopenharmony_ci afe->reg_back_up_list = mt2701_afe_backup_list; 139562306a36Sopenharmony_ci afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list); 139662306a36Sopenharmony_ci afe->runtime_resume = mt2701_afe_runtime_resume; 139762306a36Sopenharmony_ci afe->runtime_suspend = mt2701_afe_runtime_suspend; 139862306a36Sopenharmony_ci 139962306a36Sopenharmony_ci /* initial audio related clock */ 140062306a36Sopenharmony_ci ret = mt2701_init_clock(afe); 140162306a36Sopenharmony_ci if (ret) { 140262306a36Sopenharmony_ci dev_err(dev, "init clock error\n"); 140362306a36Sopenharmony_ci return ret; 140462306a36Sopenharmony_ci } 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ci platform_set_drvdata(pdev, afe); 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci pm_runtime_enable(dev); 140962306a36Sopenharmony_ci if (!pm_runtime_enabled(dev)) { 141062306a36Sopenharmony_ci ret = mt2701_afe_runtime_resume(dev); 141162306a36Sopenharmony_ci if (ret) 141262306a36Sopenharmony_ci goto err_pm_disable; 141362306a36Sopenharmony_ci } 141462306a36Sopenharmony_ci pm_runtime_get_sync(dev); 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_ci ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform, 141762306a36Sopenharmony_ci NULL, 0); 141862306a36Sopenharmony_ci if (ret) { 141962306a36Sopenharmony_ci dev_warn(dev, "err_platform\n"); 142062306a36Sopenharmony_ci goto err_platform; 142162306a36Sopenharmony_ci } 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci ret = devm_snd_soc_register_component(&pdev->dev, 142462306a36Sopenharmony_ci &mt2701_afe_pcm_dai_component, 142562306a36Sopenharmony_ci mt2701_afe_pcm_dais, 142662306a36Sopenharmony_ci ARRAY_SIZE(mt2701_afe_pcm_dais)); 142762306a36Sopenharmony_ci if (ret) { 142862306a36Sopenharmony_ci dev_warn(dev, "err_dai_component\n"); 142962306a36Sopenharmony_ci goto err_platform; 143062306a36Sopenharmony_ci } 143162306a36Sopenharmony_ci 143262306a36Sopenharmony_ci return 0; 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_cierr_platform: 143562306a36Sopenharmony_ci pm_runtime_put_sync(dev); 143662306a36Sopenharmony_cierr_pm_disable: 143762306a36Sopenharmony_ci pm_runtime_disable(dev); 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_ci return ret; 144062306a36Sopenharmony_ci} 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_cistatic void mt2701_afe_pcm_dev_remove(struct platform_device *pdev) 144362306a36Sopenharmony_ci{ 144462306a36Sopenharmony_ci pm_runtime_put_sync(&pdev->dev); 144562306a36Sopenharmony_ci pm_runtime_disable(&pdev->dev); 144662306a36Sopenharmony_ci if (!pm_runtime_status_suspended(&pdev->dev)) 144762306a36Sopenharmony_ci mt2701_afe_runtime_suspend(&pdev->dev); 144862306a36Sopenharmony_ci} 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_cistatic const struct mt2701_soc_variants mt2701_soc_v1 = { 145162306a36Sopenharmony_ci .i2s_num = 4, 145262306a36Sopenharmony_ci}; 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_cistatic const struct mt2701_soc_variants mt2701_soc_v2 = { 145562306a36Sopenharmony_ci .has_one_heart_mode = true, 145662306a36Sopenharmony_ci .i2s_num = 4, 145762306a36Sopenharmony_ci}; 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_cistatic const struct of_device_id mt2701_afe_pcm_dt_match[] = { 146062306a36Sopenharmony_ci { .compatible = "mediatek,mt2701-audio", .data = &mt2701_soc_v1 }, 146162306a36Sopenharmony_ci { .compatible = "mediatek,mt7622-audio", .data = &mt2701_soc_v2 }, 146262306a36Sopenharmony_ci {}, 146362306a36Sopenharmony_ci}; 146462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match); 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_cistatic const struct dev_pm_ops mt2701_afe_pm_ops = { 146762306a36Sopenharmony_ci SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend, 146862306a36Sopenharmony_ci mt2701_afe_runtime_resume, NULL) 146962306a36Sopenharmony_ci}; 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_cistatic struct platform_driver mt2701_afe_pcm_driver = { 147262306a36Sopenharmony_ci .driver = { 147362306a36Sopenharmony_ci .name = "mt2701-audio", 147462306a36Sopenharmony_ci .of_match_table = mt2701_afe_pcm_dt_match, 147562306a36Sopenharmony_ci .pm = &mt2701_afe_pm_ops, 147662306a36Sopenharmony_ci }, 147762306a36Sopenharmony_ci .probe = mt2701_afe_pcm_dev_probe, 147862306a36Sopenharmony_ci .remove_new = mt2701_afe_pcm_dev_remove, 147962306a36Sopenharmony_ci}; 148062306a36Sopenharmony_ci 148162306a36Sopenharmony_cimodule_platform_driver(mt2701_afe_pcm_driver); 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ciMODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701"); 148462306a36Sopenharmony_ciMODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); 148562306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 1486