162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * MediaTek ALSA SoC Audio DAI eTDM Control 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2023 MediaTek Inc. 662306a36Sopenharmony_ci * Authors: Vic Wu <vic.wu@mediatek.com> 762306a36Sopenharmony_ci * Maso Huang <maso.huang@mediatek.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/bitfield.h> 1162306a36Sopenharmony_ci#include <linux/bitops.h> 1262306a36Sopenharmony_ci#include <linux/regmap.h> 1362306a36Sopenharmony_ci#include <sound/pcm_params.h> 1462306a36Sopenharmony_ci#include "mt7986-afe-common.h" 1562306a36Sopenharmony_ci#include "mt7986-reg.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define HOPPING_CLK 0 1862306a36Sopenharmony_ci#define APLL_CLK 1 1962306a36Sopenharmony_ci#define MTK_DAI_ETDM_FORMAT_I2S 0 2062306a36Sopenharmony_ci#define MTK_DAI_ETDM_FORMAT_DSPA 4 2162306a36Sopenharmony_ci#define MTK_DAI_ETDM_FORMAT_DSPB 5 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cienum { 2462306a36Sopenharmony_ci MTK_ETDM_RATE_8K = 0, 2562306a36Sopenharmony_ci MTK_ETDM_RATE_12K = 1, 2662306a36Sopenharmony_ci MTK_ETDM_RATE_16K = 2, 2762306a36Sopenharmony_ci MTK_ETDM_RATE_24K = 3, 2862306a36Sopenharmony_ci MTK_ETDM_RATE_32K = 4, 2962306a36Sopenharmony_ci MTK_ETDM_RATE_48K = 5, 3062306a36Sopenharmony_ci MTK_ETDM_RATE_96K = 7, 3162306a36Sopenharmony_ci MTK_ETDM_RATE_192K = 9, 3262306a36Sopenharmony_ci MTK_ETDM_RATE_11K = 16, 3362306a36Sopenharmony_ci MTK_ETDM_RATE_22K = 17, 3462306a36Sopenharmony_ci MTK_ETDM_RATE_44K = 18, 3562306a36Sopenharmony_ci MTK_ETDM_RATE_88K = 19, 3662306a36Sopenharmony_ci MTK_ETDM_RATE_176K = 20, 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistruct mtk_dai_etdm_priv { 4062306a36Sopenharmony_ci bool bck_inv; 4162306a36Sopenharmony_ci bool lrck_inv; 4262306a36Sopenharmony_ci bool slave_mode; 4362306a36Sopenharmony_ci unsigned int format; 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic unsigned int mt7986_etdm_rate_transform(struct device *dev, unsigned int rate) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci switch (rate) { 4962306a36Sopenharmony_ci case 8000: 5062306a36Sopenharmony_ci return MTK_ETDM_RATE_8K; 5162306a36Sopenharmony_ci case 11025: 5262306a36Sopenharmony_ci return MTK_ETDM_RATE_11K; 5362306a36Sopenharmony_ci case 12000: 5462306a36Sopenharmony_ci return MTK_ETDM_RATE_12K; 5562306a36Sopenharmony_ci case 16000: 5662306a36Sopenharmony_ci return MTK_ETDM_RATE_16K; 5762306a36Sopenharmony_ci case 22050: 5862306a36Sopenharmony_ci return MTK_ETDM_RATE_22K; 5962306a36Sopenharmony_ci case 24000: 6062306a36Sopenharmony_ci return MTK_ETDM_RATE_24K; 6162306a36Sopenharmony_ci case 32000: 6262306a36Sopenharmony_ci return MTK_ETDM_RATE_32K; 6362306a36Sopenharmony_ci case 44100: 6462306a36Sopenharmony_ci return MTK_ETDM_RATE_44K; 6562306a36Sopenharmony_ci case 48000: 6662306a36Sopenharmony_ci return MTK_ETDM_RATE_48K; 6762306a36Sopenharmony_ci case 88200: 6862306a36Sopenharmony_ci return MTK_ETDM_RATE_88K; 6962306a36Sopenharmony_ci case 96000: 7062306a36Sopenharmony_ci return MTK_ETDM_RATE_96K; 7162306a36Sopenharmony_ci case 176400: 7262306a36Sopenharmony_ci return MTK_ETDM_RATE_176K; 7362306a36Sopenharmony_ci case 192000: 7462306a36Sopenharmony_ci return MTK_ETDM_RATE_192K; 7562306a36Sopenharmony_ci default: 7662306a36Sopenharmony_ci dev_warn(dev, "%s(), rate %u invalid, using %d!!!\n", 7762306a36Sopenharmony_ci __func__, rate, MTK_ETDM_RATE_48K); 7862306a36Sopenharmony_ci return MTK_ETDM_RATE_48K; 7962306a36Sopenharmony_ci } 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic int get_etdm_wlen(unsigned int bitwidth) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci return bitwidth <= 16 ? 16 : 32; 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* dai component */ 8862306a36Sopenharmony_ci/* interconnection */ 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic const struct snd_kcontrol_new o124_mix[] = { 9162306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I032_Switch", AFE_CONN124_1, 0, 1, 0), 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic const struct snd_kcontrol_new o125_mix[] = { 9562306a36Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("I033_Switch", AFE_CONN125_1, 1, 1, 0), 9662306a36Sopenharmony_ci}; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* DL */ 10162306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0), 10262306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0), 10362306a36Sopenharmony_ci /* UL */ 10462306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, o124_mix, ARRAY_SIZE(o124_mix)), 10562306a36Sopenharmony_ci SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, o125_mix, ARRAY_SIZE(o125_mix)), 10662306a36Sopenharmony_ci}; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { 10962306a36Sopenharmony_ci {"I150", NULL, "ETDM Capture"}, 11062306a36Sopenharmony_ci {"I151", NULL, "ETDM Capture"}, 11162306a36Sopenharmony_ci {"ETDM Playback", NULL, "O124"}, 11262306a36Sopenharmony_ci {"ETDM Playback", NULL, "O125"}, 11362306a36Sopenharmony_ci {"O124", "I032_Switch", "I032"}, 11462306a36Sopenharmony_ci {"O125", "I033_Switch", "I033"}, 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci/* dai ops */ 11862306a36Sopenharmony_cistatic int mtk_dai_etdm_startup(struct snd_pcm_substream *substream, 11962306a36Sopenharmony_ci struct snd_soc_dai *dai) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 12262306a36Sopenharmony_ci struct mt7986_afe_private *afe_priv = afe->platform_priv; 12362306a36Sopenharmony_ci int ret; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci ret = clk_bulk_prepare_enable(afe_priv->num_clks, afe_priv->clks); 12662306a36Sopenharmony_ci if (ret) 12762306a36Sopenharmony_ci return dev_err_probe(afe->dev, ret, "Failed to enable clocks\n"); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK, 0); 13062306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK, 0); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci return 0; 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream, 13662306a36Sopenharmony_ci struct snd_soc_dai *dai) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 13962306a36Sopenharmony_ci struct mt7986_afe_private *afe_priv = afe->platform_priv; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK, 14262306a36Sopenharmony_ci CLK_OUT5_PDN); 14362306a36Sopenharmony_ci regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK, 14462306a36Sopenharmony_ci CLK_IN5_PDN); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci clk_bulk_disable_unprepare(afe_priv->num_clks, afe_priv->clks); 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic unsigned int get_etdm_ch_fixup(unsigned int channels) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci if (channels > 16) 15262306a36Sopenharmony_ci return 24; 15362306a36Sopenharmony_ci else if (channels > 8) 15462306a36Sopenharmony_ci return 16; 15562306a36Sopenharmony_ci else if (channels > 4) 15662306a36Sopenharmony_ci return 8; 15762306a36Sopenharmony_ci else if (channels > 2) 15862306a36Sopenharmony_ci return 4; 15962306a36Sopenharmony_ci else 16062306a36Sopenharmony_ci return 2; 16162306a36Sopenharmony_ci} 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_cistatic int mtk_dai_etdm_config(struct mtk_base_afe *afe, 16462306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 16562306a36Sopenharmony_ci struct snd_soc_dai *dai, 16662306a36Sopenharmony_ci int stream) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct mt7986_afe_private *afe_priv = afe->platform_priv; 16962306a36Sopenharmony_ci struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id]; 17062306a36Sopenharmony_ci unsigned int rate = params_rate(params); 17162306a36Sopenharmony_ci unsigned int etdm_rate = mt7986_etdm_rate_transform(afe->dev, rate); 17262306a36Sopenharmony_ci unsigned int afe_rate = mt7986_afe_rate_transform(afe->dev, rate); 17362306a36Sopenharmony_ci unsigned int channels = params_channels(params); 17462306a36Sopenharmony_ci unsigned int bit_width = params_width(params); 17562306a36Sopenharmony_ci unsigned int wlen = get_etdm_wlen(bit_width); 17662306a36Sopenharmony_ci unsigned int val = 0; 17762306a36Sopenharmony_ci unsigned int mask = 0; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n", 18062306a36Sopenharmony_ci __func__, stream, rate, bit_width); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci /* CON0 */ 18362306a36Sopenharmony_ci mask |= ETDM_BIT_LEN_MASK; 18462306a36Sopenharmony_ci val |= FIELD_PREP(ETDM_BIT_LEN_MASK, bit_width - 1); 18562306a36Sopenharmony_ci mask |= ETDM_WRD_LEN_MASK; 18662306a36Sopenharmony_ci val |= FIELD_PREP(ETDM_WRD_LEN_MASK, wlen - 1); 18762306a36Sopenharmony_ci mask |= ETDM_FMT_MASK; 18862306a36Sopenharmony_ci val |= FIELD_PREP(ETDM_FMT_MASK, etdm_data->format); 18962306a36Sopenharmony_ci mask |= ETDM_CH_NUM_MASK; 19062306a36Sopenharmony_ci val |= FIELD_PREP(ETDM_CH_NUM_MASK, get_etdm_ch_fixup(channels) - 1); 19162306a36Sopenharmony_ci mask |= RELATCH_SRC_MASK; 19262306a36Sopenharmony_ci val |= FIELD_PREP(RELATCH_SRC_MASK, APLL_CLK); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci switch (stream) { 19562306a36Sopenharmony_ci case SNDRV_PCM_STREAM_PLAYBACK: 19662306a36Sopenharmony_ci /* set ETDM_OUT5_CON0 */ 19762306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, mask, val); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci /* set ETDM_OUT5_CON4 */ 20062306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON4, 20162306a36Sopenharmony_ci OUT_RELATCH_MASK, OUT_RELATCH(afe_rate)); 20262306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON4, 20362306a36Sopenharmony_ci OUT_CLK_SRC_MASK, OUT_CLK_SRC(APLL_CLK)); 20462306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON4, 20562306a36Sopenharmony_ci OUT_SEL_FS_MASK, OUT_SEL_FS(etdm_rate)); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci /* set ETDM_OUT5_CON5 */ 20862306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON5, 20962306a36Sopenharmony_ci ETDM_CLK_DIV_MASK, ETDM_CLK_DIV); 21062306a36Sopenharmony_ci break; 21162306a36Sopenharmony_ci case SNDRV_PCM_STREAM_CAPTURE: 21262306a36Sopenharmony_ci /* set ETDM_IN5_CON0 */ 21362306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON0, mask, val); 21462306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON0, 21562306a36Sopenharmony_ci ETDM_SYNC_MASK, ETDM_SYNC); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* set ETDM_IN5_CON2 */ 21862306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON2, 21962306a36Sopenharmony_ci IN_CLK_SRC_MASK, IN_CLK_SRC(APLL_CLK)); 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci /* set ETDM_IN5_CON3 */ 22262306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON3, 22362306a36Sopenharmony_ci IN_SEL_FS_MASK, IN_SEL_FS(etdm_rate)); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* set ETDM_IN5_CON4 */ 22662306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON4, 22762306a36Sopenharmony_ci IN_RELATCH_MASK, IN_RELATCH(afe_rate)); 22862306a36Sopenharmony_ci break; 22962306a36Sopenharmony_ci default: 23062306a36Sopenharmony_ci break; 23162306a36Sopenharmony_ci } 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci return 0; 23462306a36Sopenharmony_ci} 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_cistatic int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, 23762306a36Sopenharmony_ci struct snd_pcm_hw_params *params, 23862306a36Sopenharmony_ci struct snd_soc_dai *dai) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK); 24362306a36Sopenharmony_ci mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci return 0; 24662306a36Sopenharmony_ci} 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_cistatic int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd, 24962306a36Sopenharmony_ci struct snd_soc_dai *dai) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id); 25462306a36Sopenharmony_ci switch (cmd) { 25562306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_START: 25662306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_RESUME: 25762306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK, 25862306a36Sopenharmony_ci ETDM_EN); 25962306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK, 26062306a36Sopenharmony_ci ETDM_EN); 26162306a36Sopenharmony_ci break; 26262306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_STOP: 26362306a36Sopenharmony_ci case SNDRV_PCM_TRIGGER_SUSPEND: 26462306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK, 26562306a36Sopenharmony_ci 0); 26662306a36Sopenharmony_ci regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK, 26762306a36Sopenharmony_ci 0); 26862306a36Sopenharmony_ci break; 26962306a36Sopenharmony_ci default: 27062306a36Sopenharmony_ci break; 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci return 0; 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistatic int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 27962306a36Sopenharmony_ci struct mt7986_afe_private *afe_priv = afe->platform_priv; 28062306a36Sopenharmony_ci struct mtk_dai_etdm_priv *etdm_data; 28162306a36Sopenharmony_ci void *priv_data; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci switch (dai->id) { 28462306a36Sopenharmony_ci case MT7986_DAI_ETDM: 28562306a36Sopenharmony_ci break; 28662306a36Sopenharmony_ci default: 28762306a36Sopenharmony_ci dev_warn(afe->dev, "%s(), id %d not support\n", 28862306a36Sopenharmony_ci __func__, dai->id); 28962306a36Sopenharmony_ci return -EINVAL; 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci priv_data = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv), 29362306a36Sopenharmony_ci GFP_KERNEL); 29462306a36Sopenharmony_ci if (!priv_data) 29562306a36Sopenharmony_ci return -ENOMEM; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci afe_priv->dai_priv[dai->id] = priv_data; 29862306a36Sopenharmony_ci etdm_data = afe_priv->dai_priv[dai->id]; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 30162306a36Sopenharmony_ci case SND_SOC_DAIFMT_I2S: 30262306a36Sopenharmony_ci etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S; 30362306a36Sopenharmony_ci break; 30462306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_A: 30562306a36Sopenharmony_ci etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA; 30662306a36Sopenharmony_ci break; 30762306a36Sopenharmony_ci case SND_SOC_DAIFMT_DSP_B: 30862306a36Sopenharmony_ci etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB; 30962306a36Sopenharmony_ci break; 31062306a36Sopenharmony_ci default: 31162306a36Sopenharmony_ci return -EINVAL; 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 31562306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_NF: 31662306a36Sopenharmony_ci etdm_data->bck_inv = false; 31762306a36Sopenharmony_ci etdm_data->lrck_inv = false; 31862306a36Sopenharmony_ci break; 31962306a36Sopenharmony_ci case SND_SOC_DAIFMT_NB_IF: 32062306a36Sopenharmony_ci etdm_data->bck_inv = false; 32162306a36Sopenharmony_ci etdm_data->lrck_inv = true; 32262306a36Sopenharmony_ci break; 32362306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_NF: 32462306a36Sopenharmony_ci etdm_data->bck_inv = true; 32562306a36Sopenharmony_ci etdm_data->lrck_inv = false; 32662306a36Sopenharmony_ci break; 32762306a36Sopenharmony_ci case SND_SOC_DAIFMT_IB_IF: 32862306a36Sopenharmony_ci etdm_data->bck_inv = true; 32962306a36Sopenharmony_ci etdm_data->lrck_inv = true; 33062306a36Sopenharmony_ci break; 33162306a36Sopenharmony_ci default: 33262306a36Sopenharmony_ci return -EINVAL; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 33662306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBM_CFM: 33762306a36Sopenharmony_ci etdm_data->slave_mode = true; 33862306a36Sopenharmony_ci break; 33962306a36Sopenharmony_ci case SND_SOC_DAIFMT_CBS_CFS: 34062306a36Sopenharmony_ci etdm_data->slave_mode = false; 34162306a36Sopenharmony_ci break; 34262306a36Sopenharmony_ci default: 34362306a36Sopenharmony_ci return -EINVAL; 34462306a36Sopenharmony_ci } 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci return 0; 34762306a36Sopenharmony_ci} 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_cistatic const struct snd_soc_dai_ops mtk_dai_etdm_ops = { 35062306a36Sopenharmony_ci .startup = mtk_dai_etdm_startup, 35162306a36Sopenharmony_ci .shutdown = mtk_dai_etdm_shutdown, 35262306a36Sopenharmony_ci .hw_params = mtk_dai_etdm_hw_params, 35362306a36Sopenharmony_ci .trigger = mtk_dai_etdm_trigger, 35462306a36Sopenharmony_ci .set_fmt = mtk_dai_etdm_set_fmt, 35562306a36Sopenharmony_ci}; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci/* dai driver */ 35862306a36Sopenharmony_ci#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_48000 |\ 35962306a36Sopenharmony_ci SNDRV_PCM_RATE_88200 |\ 36062306a36Sopenharmony_ci SNDRV_PCM_RATE_96000 |\ 36162306a36Sopenharmony_ci SNDRV_PCM_RATE_176400 |\ 36262306a36Sopenharmony_ci SNDRV_PCM_RATE_192000) 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 36562306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE |\ 36662306a36Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE) 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_cistatic struct snd_soc_dai_driver mtk_dai_etdm_driver[] = { 36962306a36Sopenharmony_ci { 37062306a36Sopenharmony_ci .name = "ETDM", 37162306a36Sopenharmony_ci .id = MT7986_DAI_ETDM, 37262306a36Sopenharmony_ci .capture = { 37362306a36Sopenharmony_ci .stream_name = "ETDM Capture", 37462306a36Sopenharmony_ci .channels_min = 1, 37562306a36Sopenharmony_ci .channels_max = 2, 37662306a36Sopenharmony_ci .rates = MTK_ETDM_RATES, 37762306a36Sopenharmony_ci .formats = MTK_ETDM_FORMATS, 37862306a36Sopenharmony_ci }, 37962306a36Sopenharmony_ci .playback = { 38062306a36Sopenharmony_ci .stream_name = "ETDM Playback", 38162306a36Sopenharmony_ci .channels_min = 1, 38262306a36Sopenharmony_ci .channels_max = 2, 38362306a36Sopenharmony_ci .rates = MTK_ETDM_RATES, 38462306a36Sopenharmony_ci .formats = MTK_ETDM_FORMATS, 38562306a36Sopenharmony_ci }, 38662306a36Sopenharmony_ci .ops = &mtk_dai_etdm_ops, 38762306a36Sopenharmony_ci .symmetric_rate = 1, 38862306a36Sopenharmony_ci .symmetric_sample_bits = 1, 38962306a36Sopenharmony_ci }, 39062306a36Sopenharmony_ci}; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ciint mt7986_dai_etdm_register(struct mtk_base_afe *afe) 39362306a36Sopenharmony_ci{ 39462306a36Sopenharmony_ci struct mtk_base_afe_dai *dai; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 39762306a36Sopenharmony_ci if (!dai) 39862306a36Sopenharmony_ci return -ENOMEM; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci list_add(&dai->list, &afe->sub_dais); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci dai->dai_drivers = mtk_dai_etdm_driver; 40362306a36Sopenharmony_ci dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci dai->dapm_widgets = mtk_dai_etdm_widgets; 40662306a36Sopenharmony_ci dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets); 40762306a36Sopenharmony_ci dai->dapm_routes = mtk_dai_etdm_routes; 40862306a36Sopenharmony_ci dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci return 0; 41162306a36Sopenharmony_ci} 412