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