Path: blob/master/sound/soc/mediatek/mt8189/mt8189-dai-i2s.c
38245 views
// SPDX-License-Identifier: GPL-2.01/*2* MediaTek ALSA SoC Audio DAI I2S Control3*4* Copyright (c) 2025 MediaTek Inc.5* Author: Darren Ye <[email protected]>6*/78#include <linux/bitops.h>9#include <linux/regmap.h>1011#include <sound/pcm_params.h>1213#include "mt8189-afe-clk.h"14#include "mt8189-afe-common.h"15#include "mt8189-interconnection.h"1617#include "../common/mtk-afe-fe-dai.h"1819#define I2SIN0_MCLK_EN_W_NAME "I2SIN0_MCLK_EN"20#define I2SIN1_MCLK_EN_W_NAME "I2SIN1_MCLK_EN"21#define I2SOUT0_MCLK_EN_W_NAME "I2SOUT0_MCLK_EN"22#define I2SOUT1_MCLK_EN_W_NAME "I2SOUT1_MCLK_EN"23#define I2SOUT4_MCLK_EN_W_NAME "I2SOUT4_MCLK_EN"2425enum {26SUPPLY_SEQ_APLL,27SUPPLY_SEQ_I2S_MCLK_EN,28SUPPLY_SEQ_I2S_CG_EN,29SUPPLY_SEQ_I2S_EN,30};3132/* this enum is merely for mtk_afe_i2s_priv declare */33enum {34DAI_I2SIN0,35DAI_I2SIN1,36DAI_I2SOUT0,37DAI_I2SOUT1,38DAI_I2SOUT4,39DAI_I2S_NUM,40};4142enum {43ETDM_CLK_SOURCE_H26M,44ETDM_CLK_SOURCE_APLL,45ETDM_CLK_SOURCE_SPDIF,46ETDM_CLK_SOURCE_HDMI,47ETDM_CLK_SOURCE_EARC,48ETDM_CLK_SOURCE_LINEIN,49};5051enum {52ETDM_RELATCH_SEL_H26M,53ETDM_RELATCH_SEL_APLL,54};5556enum {57ETDM_RATE_8K,58ETDM_RATE_12K,59ETDM_RATE_16K,60ETDM_RATE_24K,61ETDM_RATE_32K,62ETDM_RATE_48K,63ETDM_RATE_64K,64ETDM_RATE_96K,65ETDM_RATE_128K,66ETDM_RATE_192K,67ETDM_RATE_256K,68ETDM_RATE_384K,69ETDM_RATE_11025 = 16,70ETDM_RATE_22050,71ETDM_RATE_44100,72ETDM_RATE_88200,73ETDM_RATE_176400,74ETDM_RATE_352800,75};7677enum {78ETDM_CONN_8K,79ETDM_CONN_11K,80ETDM_CONN_12K,81ETDM_CONN_16K = 4,82ETDM_CONN_22K,83ETDM_CONN_24K,84ETDM_CONN_32K = 8,85ETDM_CONN_44K,86ETDM_CONN_48K,87ETDM_CONN_88K = 13,88ETDM_CONN_96K,89ETDM_CONN_176K = 17,90ETDM_CONN_192K,91ETDM_CONN_352K = 21,92ETDM_CONN_384K,93};9495enum {96ETDM_WLEN_8_BIT = 0x7,97ETDM_WLEN_16_BIT = 0xf,98ETDM_WLEN_32_BIT = 0x1f,99};100101enum {102ETDM_SLAVE_SEL_ETDMIN0_MASTER,103ETDM_SLAVE_SEL_ETDMIN0_SLAVE,104ETDM_SLAVE_SEL_ETDMIN1_MASTER,105ETDM_SLAVE_SEL_ETDMIN1_SLAVE,106ETDM_SLAVE_SEL_ETDMIN2_MASTER,107ETDM_SLAVE_SEL_ETDMIN2_SLAVE,108ETDM_SLAVE_SEL_ETDMIN3_MASTER,109ETDM_SLAVE_SEL_ETDMIN3_SLAVE,110ETDM_SLAVE_SEL_ETDMOUT0_MASTER,111ETDM_SLAVE_SEL_ETDMOUT0_SLAVE,112ETDM_SLAVE_SEL_ETDMOUT1_MASTER,113ETDM_SLAVE_SEL_ETDMOUT1_SLAVE,114ETDM_SLAVE_SEL_ETDMOUT2_MASTER,115ETDM_SLAVE_SEL_ETDMOUT2_SLAVE,116ETDM_SLAVE_SEL_ETDMOUT3_MASTER,117ETDM_SLAVE_SEL_ETDMOUT3_SLAVE,118};119120struct mtk_afe_i2s_priv {121int id;122int rate; /* for determine which apll to use */123int low_jitter_en;124unsigned int i2s_low_power_mask;125const char *share_property_name;126int share_i2s_id;127128int mclk_id;129int mclk_rate;130int mclk_apll;131132int ch_num;133int sync;134int ip_mode;135int slave_mode;136int lpbk_mode;137};138139static unsigned int get_etdm_wlen(snd_pcm_format_t format)140{141return snd_pcm_format_physical_width(format) <= 16 ?142ETDM_WLEN_16_BIT : ETDM_WLEN_32_BIT;143}144145static unsigned int get_etdm_lrck_width(snd_pcm_format_t format)146{147if (snd_pcm_format_physical_width(format) <= 1)148return 0;149150/* The valid data bit number should be larger than 7 due to hardware limitation. */151return snd_pcm_format_physical_width(format) - 1;152}153154static unsigned int get_etdm_rate(unsigned int rate)155{156switch (rate) {157case 8000:158return ETDM_RATE_8K;159case 12000:160return ETDM_RATE_12K;161case 16000:162return ETDM_RATE_16K;163case 24000:164return ETDM_RATE_24K;165case 32000:166return ETDM_RATE_32K;167case 48000:168return ETDM_RATE_48K;169case 64000:170return ETDM_RATE_64K;171case 96000:172return ETDM_RATE_96K;173case 128000:174return ETDM_RATE_128K;175case 192000:176return ETDM_RATE_192K;177case 256000:178return ETDM_RATE_256K;179case 384000:180return ETDM_RATE_384K;181case 11025:182return ETDM_RATE_11025;183case 22050:184return ETDM_RATE_22050;185case 44100:186return ETDM_RATE_44100;187case 88200:188return ETDM_RATE_88200;189case 176400:190return ETDM_RATE_176400;191case 352800:192return ETDM_RATE_352800;193default:194return 0;195}196}197198static unsigned int get_etdm_inconn_rate(unsigned int rate)199{200switch (rate) {201case 8000:202return ETDM_CONN_8K;203case 12000:204return ETDM_CONN_12K;205case 16000:206return ETDM_CONN_16K;207case 24000:208return ETDM_CONN_24K;209case 32000:210return ETDM_CONN_32K;211case 48000:212return ETDM_CONN_48K;213case 96000:214return ETDM_CONN_96K;215case 192000:216return ETDM_CONN_192K;217case 384000:218return ETDM_CONN_384K;219case 11025:220return ETDM_CONN_11K;221case 22050:222return ETDM_CONN_22K;223case 44100:224return ETDM_CONN_44K;225case 88200:226return ETDM_CONN_88K;227case 176400:228return ETDM_CONN_176K;229case 352800:230return ETDM_CONN_352K;231default:232return 0;233}234}235236static int get_i2s_id_by_name(struct mtk_base_afe *afe,237const char *name)238{239if (strncmp(name, "I2SIN0", 6) == 0)240return MT8189_DAI_I2S_IN0;241else if (strncmp(name, "I2SIN1", 6) == 0)242return MT8189_DAI_I2S_IN1;243else if (strncmp(name, "I2SOUT0", 7) == 0)244return MT8189_DAI_I2S_OUT0;245else if (strncmp(name, "I2SOUT1", 7) == 0)246return MT8189_DAI_I2S_OUT1;247else if (strncmp(name, "I2SOUT4", 7) == 0)248return MT8189_DAI_I2S_OUT4;249else250return -EINVAL;251}252253static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,254const char *name)255{256struct mt8189_afe_private *afe_priv = afe->platform_priv;257int dai_id = get_i2s_id_by_name(afe, name);258259if (dai_id < 0)260return NULL;261262return afe_priv->dai_priv[dai_id];263}264265static const char * const etdm_0_3_loopback_texts[] = {266"etdmin0", "etdmin1", "etdmout0", "etdmout1"267};268269static const u32 etdm_loopback_values[] = {2700, 2, 8, 10271};272273static SOC_VALUE_ENUM_SINGLE_DECL(i2sin0_loopback_enum,274ETDM_0_3_COWORK_CON1,275ETDM_IN0_SDATA0_SEL_SFT,276ETDM_IN0_SDATA0_SEL_MASK,277etdm_0_3_loopback_texts,278etdm_loopback_values);279280static SOC_VALUE_ENUM_SINGLE_DECL(i2sin1_loopback_enum,281ETDM_0_3_COWORK_CON1,282ETDM_IN1_SDATA0_SEL_SFT,283ETDM_IN1_SDATA0_SEL_MASK,284etdm_0_3_loopback_texts,285etdm_loopback_values);286287static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {288SOC_ENUM("I2SIN0 Loopback", i2sin0_loopback_enum),289SOC_ENUM("I2SIN1 Loopback", i2sin1_loopback_enum),290};291292/*293* I2S virtual mux to output widget294* If the I2S interface is required but not connected to an actual codec dai,295* a Dummy_Widget must be used to establish the connection.296*/297static const char *const i2s_mux_map[] = {298"Normal", "Dummy_Widget",299};300301static int i2s_mux_map_value[] = {3020, 1,303};304305static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum,306SND_SOC_NOPM,3070,3081,309i2s_mux_map,310i2s_mux_map_value);311312static const struct snd_kcontrol_new i2s_in0_mux_control =313SOC_DAPM_ENUM("I2S IN0 Select", i2s_mux_map_enum);314static const struct snd_kcontrol_new i2s_in1_mux_control =315SOC_DAPM_ENUM("I2S IN1 Select", i2s_mux_map_enum);316static const struct snd_kcontrol_new i2s_out0_mux_control =317SOC_DAPM_ENUM("I2S OUT0 Select", i2s_mux_map_enum);318static const struct snd_kcontrol_new i2s_out1_mux_control =319SOC_DAPM_ENUM("I2S OUT1 Select", i2s_mux_map_enum);320static const struct snd_kcontrol_new i2s_out4_mux_control =321SOC_DAPM_ENUM("I2S OUT4 Select", i2s_mux_map_enum);322323static const struct snd_kcontrol_new mtk_i2sout0_ch1_mix[] = {324SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN108_1, I_DL0_CH1, 1, 0),325SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN108_1, I_DL1_CH1, 1, 0),326SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN108_1, I_DL2_CH1, 1, 0),327SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN108_1, I_DL3_CH1, 1, 0),328SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN108_1, I_DL4_CH1, 1, 0),329SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN108_1, I_DL5_CH1, 1, 0),330SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN108_1, I_DL6_CH1, 1, 0),331SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN108_1, I_DL7_CH1, 1, 0),332SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN108_1, I_DL8_CH1, 1, 0),333SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN108_1, I_DL_24CH_CH1, 1, 0),334SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN108_0,335I_GAIN0_OUT_CH1, 1, 0),336SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN108_0,337I_ADDA_UL_CH1, 1, 0),338SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN108_4,339I_PCM_0_CAP_CH1, 1, 0),340};341342static const struct snd_kcontrol_new mtk_i2sout0_ch2_mix[] = {343SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN109_1, I_DL0_CH2, 1, 0),344SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN109_1, I_DL1_CH2, 1, 0),345SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN109_1, I_DL2_CH2, 1, 0),346SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN109_1, I_DL3_CH2, 1, 0),347SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN109_1, I_DL4_CH2, 1, 0),348SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN109_1, I_DL5_CH2, 1, 0),349SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN109_1, I_DL6_CH2, 1, 0),350SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN109_1, I_DL7_CH2, 1, 0),351SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN109_1, I_DL8_CH2, 1, 0),352SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN109_1, I_DL_24CH_CH2, 1, 0),353SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN109_0,354I_GAIN0_OUT_CH2, 1, 0),355SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN109_0,356I_ADDA_UL_CH2, 1, 0),357SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN109_4,358I_PCM_0_CAP_CH1, 1, 0),359SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN109_4,360I_PCM_0_CAP_CH2, 1, 0),361};362363static const struct snd_kcontrol_new mtk_i2sout1_ch1_mix[] = {364SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN110_1, I_DL0_CH1, 1, 0),365SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN110_1, I_DL1_CH1, 1, 0),366SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN110_1, I_DL2_CH1, 1, 0),367SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN110_1, I_DL3_CH1, 1, 0),368SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN110_1, I_DL4_CH1, 1, 0),369SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN110_1, I_DL5_CH1, 1, 0),370SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN110_1, I_DL6_CH1, 1, 0),371SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN110_1, I_DL7_CH1, 1, 0),372SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN110_1, I_DL8_CH1, 1, 0),373SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN110_1, I_DL_24CH_CH1, 1, 0),374SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN110_0,375I_GAIN0_OUT_CH1, 1, 0),376SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN110_0,377I_ADDA_UL_CH1, 1, 0),378SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN110_4,379I_PCM_0_CAP_CH1, 1, 0),380};381382static const struct snd_kcontrol_new mtk_i2sout1_ch2_mix[] = {383SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN111_1, I_DL0_CH2, 1, 0),384SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN111_1, I_DL1_CH2, 1, 0),385SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN111_1, I_DL2_CH2, 1, 0),386SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN111_1, I_DL3_CH2, 1, 0),387SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN111_1, I_DL4_CH2, 1, 0),388SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN111_1, I_DL5_CH2, 1, 0),389SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN111_1, I_DL6_CH2, 1, 0),390SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN111_1, I_DL7_CH2, 1, 0),391SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN111_1, I_DL8_CH2, 1, 0),392SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN111_1, I_DL_24CH_CH2, 1, 0),393SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN111_0,394I_GAIN0_OUT_CH2, 1, 0),395SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN111_0,396I_ADDA_UL_CH2, 1, 0),397SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN111_4,398I_PCM_0_CAP_CH1, 1, 0),399SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN111_4,400I_PCM_0_CAP_CH2, 1, 0),401};402403static const struct snd_kcontrol_new mtk_i2sout4_ch1_mix[] = {404SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH1", AFE_CONN116_1, I_DL0_CH1, 1, 0),405SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN116_1, I_DL1_CH1, 1, 0),406SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN116_1, I_DL2_CH1, 1, 0),407SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN116_1, I_DL3_CH1, 1, 0),408SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1", AFE_CONN116_1, I_DL4_CH1, 1, 0),409SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1", AFE_CONN116_1, I_DL5_CH1, 1, 0),410SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1", AFE_CONN116_1, I_DL6_CH1, 1, 0),411SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH1", AFE_CONN116_1, I_DL7_CH1, 1, 0),412SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1", AFE_CONN116_1, I_DL8_CH1, 1, 0),413SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH1", AFE_CONN116_1, I_DL_24CH_CH1, 1, 0),414SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH1", AFE_CONN116_2, I_DL24_CH1, 1, 0),415SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH1", AFE_CONN116_0,416I_GAIN0_OUT_CH1, 1, 0),417SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN116_0,418I_ADDA_UL_CH1, 1, 0),419SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN116_0,420I_ADDA_UL_CH2, 1, 0),421SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN116_4,422I_PCM_0_CAP_CH1, 1, 0),423SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH1", AFE_CONN116_6,424I_SRC_2_OUT_CH1, 1, 0),425};426427static const struct snd_kcontrol_new mtk_i2sout4_ch2_mix[] = {428SOC_DAPM_SINGLE_AUTODISABLE("DL0_CH2", AFE_CONN117_1, I_DL0_CH2, 1, 0),429SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN117_1, I_DL1_CH2, 1, 0),430SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN117_1, I_DL2_CH2, 1, 0),431SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN117_1, I_DL3_CH2, 1, 0),432SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2", AFE_CONN117_1, I_DL4_CH2, 1, 0),433SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2", AFE_CONN117_1, I_DL5_CH2, 1, 0),434SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2", AFE_CONN117_1, I_DL6_CH2, 1, 0),435SOC_DAPM_SINGLE_AUTODISABLE("DL7_CH2", AFE_CONN117_1, I_DL7_CH2, 1, 0),436SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2", AFE_CONN117_1, I_DL8_CH2, 1, 0),437SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH2", AFE_CONN117_1, I_DL_24CH_CH2, 1, 0),438SOC_DAPM_SINGLE_AUTODISABLE("DL24_CH2", AFE_CONN117_2, I_DL24_CH2, 1, 0),439SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN0_OUT_CH2", AFE_CONN117_0,440I_GAIN0_OUT_CH2, 1, 0),441SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN117_0,442I_ADDA_UL_CH1, 1, 0),443SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN117_0,444I_ADDA_UL_CH2, 1, 0),445SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN117_4,446I_PCM_0_CAP_CH1, 1, 0),447SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH2", AFE_CONN117_4,448I_PCM_0_CAP_CH2, 1, 0),449SOC_DAPM_SINGLE_AUTODISABLE("HW_SRC_2_OUT_CH2", AFE_CONN117_6,450I_SRC_2_OUT_CH2, 1, 0),451};452453static const struct snd_kcontrol_new mtk_i2sout4_ch3_mix[] = {454SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH3", AFE_CONN118_1, I_DL_24CH_CH3, 1, 0),455SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4,456I_PCM_0_CAP_CH1, 1, 0),457};458459static const struct snd_kcontrol_new mtk_i2sout4_ch4_mix[] = {460SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH4", AFE_CONN119_1, I_DL_24CH_CH4, 1, 0),461SOC_DAPM_SINGLE_AUTODISABLE("PCM_0_CAP_CH1", AFE_CONN118_4,462I_PCM_0_CAP_CH1, 1, 0),463};464465static const struct snd_kcontrol_new mtk_i2sout4_ch5_mix[] = {466SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH5", AFE_CONN120_1, I_DL_24CH_CH5, 1, 0),467};468469static const struct snd_kcontrol_new mtk_i2sout4_ch6_mix[] = {470SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH6", AFE_CONN121_1, I_DL_24CH_CH6, 1, 0),471};472473static const struct snd_kcontrol_new mtk_i2sout4_ch7_mix[] = {474SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH7", AFE_CONN122_1, I_DL_24CH_CH7, 1, 0),475};476477static const struct snd_kcontrol_new mtk_i2sout4_ch8_mix[] = {478SOC_DAPM_SINGLE_AUTODISABLE("DL_24CH_CH8", AFE_CONN123_1, I_DL_24CH_CH8, 1, 0),479};480481static int mtk_apll_event(struct snd_soc_dapm_widget *w,482struct snd_kcontrol *kcontrol,483int event)484{485struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);486struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);487488dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",489__func__, w->name, event);490491switch (event) {492case SND_SOC_DAPM_PRE_PMU:493if (strcmp(w->name, APLL1_W_NAME) == 0)494mt8189_apll1_enable(afe);495else496mt8189_apll2_enable(afe);497break;498case SND_SOC_DAPM_POST_PMD:499if (strcmp(w->name, APLL1_W_NAME) == 0)500mt8189_apll1_disable(afe);501else502mt8189_apll2_disable(afe);503break;504default:505break;506}507508return 0;509}510511static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,512struct snd_kcontrol *kcontrol,513int event)514{515struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);516struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);517struct mtk_afe_i2s_priv *i2s_priv;518519dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",520__func__, w->name, event);521522i2s_priv = get_i2s_priv_by_name(afe, w->name);523if (!i2s_priv)524return -EINVAL;525526switch (event) {527case SND_SOC_DAPM_PRE_PMU:528mt8189_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);529break;530case SND_SOC_DAPM_POST_PMD:531i2s_priv->mclk_rate = 0;532mt8189_mck_disable(afe, i2s_priv->mclk_id);533break;534default:535break;536}537538return 0;539}540541static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {542SND_SOC_DAPM_MIXER("I2SOUT0_CH1", SND_SOC_NOPM, 0, 0,543mtk_i2sout0_ch1_mix,544ARRAY_SIZE(mtk_i2sout0_ch1_mix)),545SND_SOC_DAPM_MIXER("I2SOUT0_CH2", SND_SOC_NOPM, 0, 0,546mtk_i2sout0_ch2_mix,547ARRAY_SIZE(mtk_i2sout0_ch2_mix)),548549SND_SOC_DAPM_MIXER("I2SOUT1_CH1", SND_SOC_NOPM, 0, 0,550mtk_i2sout1_ch1_mix,551ARRAY_SIZE(mtk_i2sout1_ch1_mix)),552SND_SOC_DAPM_MIXER("I2SOUT1_CH2", SND_SOC_NOPM, 0, 0,553mtk_i2sout1_ch2_mix,554ARRAY_SIZE(mtk_i2sout1_ch2_mix)),555556SND_SOC_DAPM_MIXER("I2SOUT4_CH1", SND_SOC_NOPM, 0, 0,557mtk_i2sout4_ch1_mix,558ARRAY_SIZE(mtk_i2sout4_ch1_mix)),559SND_SOC_DAPM_MIXER("I2SOUT4_CH2", SND_SOC_NOPM, 0, 0,560mtk_i2sout4_ch2_mix,561ARRAY_SIZE(mtk_i2sout4_ch2_mix)),562SND_SOC_DAPM_MIXER("I2SOUT4_CH3", SND_SOC_NOPM, 0, 0,563mtk_i2sout4_ch3_mix,564ARRAY_SIZE(mtk_i2sout4_ch3_mix)),565SND_SOC_DAPM_MIXER("I2SOUT4_CH4", SND_SOC_NOPM, 0, 0,566mtk_i2sout4_ch4_mix,567ARRAY_SIZE(mtk_i2sout4_ch4_mix)),568SND_SOC_DAPM_MIXER("I2SOUT4_CH5", SND_SOC_NOPM, 0, 0,569mtk_i2sout4_ch5_mix,570ARRAY_SIZE(mtk_i2sout4_ch5_mix)),571SND_SOC_DAPM_MIXER("I2SOUT4_CH6", SND_SOC_NOPM, 0, 0,572mtk_i2sout4_ch6_mix,573ARRAY_SIZE(mtk_i2sout4_ch6_mix)),574SND_SOC_DAPM_MIXER("I2SOUT4_CH7", SND_SOC_NOPM, 0, 0,575mtk_i2sout4_ch7_mix,576ARRAY_SIZE(mtk_i2sout4_ch7_mix)),577SND_SOC_DAPM_MIXER("I2SOUT4_CH8", SND_SOC_NOPM, 0, 0,578mtk_i2sout4_ch8_mix,579ARRAY_SIZE(mtk_i2sout4_ch8_mix)),580581/* i2s en*/582SND_SOC_DAPM_SUPPLY_S("I2SIN0_EN", SUPPLY_SEQ_I2S_EN,583ETDM_IN0_CON0, REG_ETDM_IN_EN_SFT, 0,584NULL, 0),585SND_SOC_DAPM_SUPPLY_S("I2SIN1_EN", SUPPLY_SEQ_I2S_EN,586ETDM_IN1_CON0, REG_ETDM_IN_EN_SFT, 0,587NULL, 0),588SND_SOC_DAPM_SUPPLY_S("I2SOUT0_EN", SUPPLY_SEQ_I2S_EN,589ETDM_OUT0_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0,590NULL, 0),591SND_SOC_DAPM_SUPPLY_S("I2SOUT1_EN", SUPPLY_SEQ_I2S_EN,592ETDM_OUT1_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0,593NULL, 0),594SND_SOC_DAPM_SUPPLY_S("I2SOUT4_EN", SUPPLY_SEQ_I2S_EN,595ETDM_OUT4_CON0, OUT_REG_ETDM_OUT_EN_SFT, 0,596NULL, 0),597598/* i2s mclk en */599SND_SOC_DAPM_SUPPLY_S(I2SIN0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,600SND_SOC_NOPM, 0, 0,601mtk_mclk_en_event,602SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),603SND_SOC_DAPM_SUPPLY_S(I2SIN1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,604SND_SOC_NOPM, 0, 0,605mtk_mclk_en_event,606SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),607SND_SOC_DAPM_SUPPLY_S(I2SOUT0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,608SND_SOC_NOPM, 0, 0,609mtk_mclk_en_event,610SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),611SND_SOC_DAPM_SUPPLY_S(I2SOUT1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,612SND_SOC_NOPM, 0, 0,613mtk_mclk_en_event,614SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),615SND_SOC_DAPM_SUPPLY_S(I2SOUT4_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,616SND_SOC_NOPM, 0, 0,617mtk_mclk_en_event,618SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),619620/* cg */621SND_SOC_DAPM_SUPPLY_S("I2SOUT0_CG", SUPPLY_SEQ_I2S_CG_EN,622AUDIO_TOP_CON2, PDN_ETDM_OUT0_SFT, 1,623NULL, 0),624SND_SOC_DAPM_SUPPLY_S("I2SOUT1_CG", SUPPLY_SEQ_I2S_CG_EN,625AUDIO_TOP_CON2, PDN_ETDM_OUT1_SFT, 1,626NULL, 0),627SND_SOC_DAPM_SUPPLY_S("I2SOUT4_CG", SUPPLY_SEQ_I2S_CG_EN,628AUDIO_TOP_CON2, PDN_ETDM_OUT4_SFT, 1,629NULL, 0),630SND_SOC_DAPM_SUPPLY_S("I2SIN0_CG", SUPPLY_SEQ_I2S_CG_EN,631AUDIO_TOP_CON2, PDN_ETDM_IN0_SFT, 1,632NULL, 0),633SND_SOC_DAPM_SUPPLY_S("I2SIN1_CG", SUPPLY_SEQ_I2S_CG_EN,634AUDIO_TOP_CON2, PDN_ETDM_IN1_SFT, 1,635NULL, 0),636637/* apll */638SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,639SND_SOC_NOPM, 0, 0,640mtk_apll_event,641SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),642SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,643SND_SOC_NOPM, 0, 0,644mtk_apll_event,645SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),646647/* allow i2s on without codec on */648SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"),649SND_SOC_DAPM_MUX("I2S_OUT0_Mux",650SND_SOC_NOPM, 0, 0, &i2s_out0_mux_control),651SND_SOC_DAPM_MUX("I2S_OUT1_Mux",652SND_SOC_NOPM, 0, 0, &i2s_out1_mux_control),653SND_SOC_DAPM_MUX("I2S_OUT4_Mux",654SND_SOC_NOPM, 0, 0, &i2s_out4_mux_control),655656SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"),657SND_SOC_DAPM_MUX("I2S_IN0_Mux",658SND_SOC_NOPM, 0, 0, &i2s_in0_mux_control),659SND_SOC_DAPM_MUX("I2S_IN1_Mux",660SND_SOC_NOPM, 0, 0, &i2s_in1_mux_control),661};662663static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,664struct snd_soc_dapm_widget *sink)665{666struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm);667struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);668struct mtk_afe_i2s_priv *i2s_priv;669670i2s_priv = get_i2s_priv_by_name(afe, sink->name);671if (!i2s_priv)672return 0;673674if (i2s_priv->share_i2s_id < 0)675return 0;676677return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);678}679680static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,681struct snd_soc_dapm_widget *sink)682{683struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm);684struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);685struct mtk_afe_i2s_priv *i2s_priv;686int cur_apll;687int needed_apll;688689i2s_priv = get_i2s_priv_by_name(afe, sink->name);690if (!i2s_priv)691return 0;692693/* which apll */694cur_apll = mt8189_get_apll_by_name(afe, source->name);695696/* choose APLL from i2s rate */697needed_apll = mt8189_get_apll_by_rate(afe, i2s_priv->rate);698699return needed_apll == cur_apll;700}701702static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,703struct snd_soc_dapm_widget *sink)704{705struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(sink->dapm);706struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);707struct mtk_afe_i2s_priv *i2s_priv;708int i2s_num;709710i2s_priv = get_i2s_priv_by_name(afe, sink->name);711if (!i2s_priv)712return 0;713714i2s_num = get_i2s_id_by_name(afe, source->name);715if (get_i2s_id_by_name(afe, sink->name) == i2s_num)716return i2s_priv->mclk_rate > 0;717718/* check if share i2s need mclk */719if (i2s_priv->share_i2s_id < 0)720return 0;721722if (i2s_priv->share_i2s_id == i2s_num)723return i2s_priv->mclk_rate > 0;724725return 0;726}727728static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,729struct snd_soc_dapm_widget *sink)730{731struct snd_soc_dapm_widget *w = sink;732struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);733struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);734struct mtk_afe_i2s_priv *i2s_priv;735int cur_apll;736737i2s_priv = get_i2s_priv_by_name(afe, w->name);738if (!i2s_priv)739return 0;740741/* which apll */742cur_apll = mt8189_get_apll_by_name(afe, source->name);743744return i2s_priv->mclk_apll == cur_apll;745}746747static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {748/* I2SIN0 */749{"I2SIN0", NULL, "I2SIN0_EN"},750{"I2SIN0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect},751{"I2SIN0", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect},752{"I2SIN0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect},753{"I2SIN0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect},754755{"I2SIN0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},756{"I2SIN0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},757{"I2SIN0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},758{"I2SIN0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},759{"I2SIN0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},760{I2SIN0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},761{I2SIN0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},762{"I2SIN0", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},763{"I2SIN0", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},764{"I2SIN0", NULL, "I2SOUT0_CG"},765{"I2SIN0", NULL, "I2SIN0_CG"},766767/* i2sin1 */768{"I2SIN1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect},769{"I2SIN1", NULL, "I2SIN1_EN"},770{"I2SIN1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect},771{"I2SIN1", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect},772{"I2SIN1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect},773774{"I2SIN1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},775{"I2SIN1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},776{"I2SIN1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},777{"I2SIN1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},778{"I2SIN1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},779{I2SIN1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},780{I2SIN1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},781{"I2SIN1", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},782{"I2SIN1", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},783{"I2SIN1", NULL, "I2SIN1_CG"},784{"I2SIN1", NULL, "I2SOUT1_CG"},785786/* i2sout0 */787{"I2SOUT0_CH1", "DL0_CH1", "DL0"},788{"I2SOUT0_CH2", "DL0_CH2", "DL0"},789{"I2SOUT0_CH1", "DL1_CH1", "DL1"},790{"I2SOUT0_CH2", "DL1_CH2", "DL1"},791{"I2SOUT0_CH1", "DL2_CH1", "DL2"},792{"I2SOUT0_CH2", "DL2_CH2", "DL2"},793{"I2SOUT0_CH1", "DL3_CH1", "DL3"},794{"I2SOUT0_CH2", "DL3_CH2", "DL3"},795{"I2SOUT0_CH1", "DL4_CH1", "DL4"},796{"I2SOUT0_CH2", "DL4_CH2", "DL4"},797{"I2SOUT0_CH1", "DL5_CH1", "DL5"},798{"I2SOUT0_CH2", "DL5_CH2", "DL5"},799{"I2SOUT0_CH1", "DL6_CH1", "DL6"},800{"I2SOUT0_CH2", "DL6_CH2", "DL6"},801{"I2SOUT0_CH1", "DL7_CH1", "DL7"},802{"I2SOUT0_CH2", "DL7_CH2", "DL7"},803{"I2SOUT0_CH1", "DL8_CH1", "DL8"},804{"I2SOUT0_CH2", "DL8_CH2", "DL8"},805{"I2SOUT0_CH1", "DL_24CH_CH1", "DL_24CH"},806{"I2SOUT0_CH2", "DL_24CH_CH2", "DL_24CH"},807808{"I2SOUT0", NULL, "I2SOUT0_CH1"},809{"I2SOUT0", NULL, "I2SOUT0_CH2"},810811{"I2SOUT0", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect},812{"I2SOUT0", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect},813{"I2SOUT0", NULL, "I2SOUT0_EN"},814{"I2SOUT0", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect},815{"I2SOUT0", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect},816817{"I2SOUT0", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},818{"I2SOUT0", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},819{"I2SOUT0", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},820{"I2SOUT0", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},821{"I2SOUT0", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},822{I2SOUT0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},823{I2SOUT0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},824{"I2SOUT0", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},825{"I2SOUT0", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},826{"I2SOUT0", NULL, "I2SOUT0_CG"},827{"I2SOUT0", NULL, "I2SIN0_CG"},828829/* i2sout1 */830{"I2SOUT1_CH1", "DL0_CH1", "DL0"},831{"I2SOUT1_CH2", "DL0_CH2", "DL0"},832{"I2SOUT1_CH1", "DL1_CH1", "DL1"},833{"I2SOUT1_CH2", "DL1_CH2", "DL1"},834{"I2SOUT1_CH1", "DL2_CH1", "DL2"},835{"I2SOUT1_CH2", "DL2_CH2", "DL2"},836{"I2SOUT1_CH1", "DL3_CH1", "DL3"},837{"I2SOUT1_CH2", "DL3_CH2", "DL3"},838{"I2SOUT1_CH1", "DL4_CH1", "DL4"},839{"I2SOUT1_CH2", "DL4_CH2", "DL4"},840{"I2SOUT1_CH1", "DL5_CH1", "DL5"},841{"I2SOUT1_CH2", "DL5_CH2", "DL5"},842{"I2SOUT1_CH1", "DL6_CH1", "DL6"},843{"I2SOUT1_CH2", "DL6_CH2", "DL6"},844{"I2SOUT1_CH1", "DL7_CH1", "DL7"},845{"I2SOUT1_CH2", "DL7_CH2", "DL7"},846{"I2SOUT1_CH1", "DL8_CH1", "DL8"},847{"I2SOUT1_CH2", "DL8_CH2", "DL8"},848{"I2SOUT1_CH1", "DL_24CH_CH1", "DL_24CH"},849{"I2SOUT1_CH2", "DL_24CH_CH2", "DL_24CH"},850851{"I2SOUT1", NULL, "I2SOUT1_CH1"},852{"I2SOUT1", NULL, "I2SOUT1_CH2"},853854{"I2SOUT1", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect},855{"I2SOUT1", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect},856{"I2SOUT1", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect},857{"I2SOUT1", NULL, "I2SOUT1_EN"},858{"I2SOUT1", NULL, "I2SOUT4_EN", mtk_afe_i2s_share_connect},859860{"I2SOUT1", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},861{"I2SOUT1", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},862{"I2SOUT1", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},863{"I2SOUT1", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},864{"I2SOUT1", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},865{I2SOUT1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},866{I2SOUT1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},867{"I2SOUT1", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},868{"I2SOUT1", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},869{"I2SOUT1", NULL, "I2SOUT1_CG"},870{"I2SOUT1", NULL, "I2SIN1_CG"},871872/* i2sout4 */873{"I2SOUT4_CH1", "DL0_CH1", "DL0"},874{"I2SOUT4_CH2", "DL0_CH2", "DL0"},875{"I2SOUT4_CH1", "DL1_CH1", "DL1"},876{"I2SOUT4_CH2", "DL1_CH2", "DL1"},877{"I2SOUT4_CH1", "DL2_CH1", "DL2"},878{"I2SOUT4_CH2", "DL2_CH2", "DL2"},879{"I2SOUT4_CH1", "DL3_CH1", "DL3"},880{"I2SOUT4_CH2", "DL3_CH2", "DL3"},881{"I2SOUT4_CH1", "DL4_CH1", "DL4"},882{"I2SOUT4_CH2", "DL4_CH2", "DL4"},883{"I2SOUT4_CH1", "DL5_CH1", "DL5"},884{"I2SOUT4_CH2", "DL5_CH2", "DL5"},885{"I2SOUT4_CH1", "DL6_CH1", "DL6"},886{"I2SOUT4_CH2", "DL6_CH2", "DL6"},887{"I2SOUT4_CH1", "DL7_CH1", "DL7"},888{"I2SOUT4_CH2", "DL7_CH2", "DL7"},889{"I2SOUT4_CH1", "DL8_CH1", "DL8"},890{"I2SOUT4_CH2", "DL8_CH2", "DL8"},891{"I2SOUT4_CH1", "DL_24CH_CH1", "DL_24CH"},892{"I2SOUT4_CH2", "DL_24CH_CH2", "DL_24CH"},893{"I2SOUT4_CH3", "DL_24CH_CH3", "DL_24CH"},894{"I2SOUT4_CH4", "DL_24CH_CH4", "DL_24CH"},895{"I2SOUT4_CH5", "DL_24CH_CH5", "DL_24CH"},896{"I2SOUT4_CH6", "DL_24CH_CH6", "DL_24CH"},897{"I2SOUT4_CH7", "DL_24CH_CH7", "DL_24CH"},898{"I2SOUT4_CH8", "DL_24CH_CH8", "DL_24CH"},899{"I2SOUT4_CH1", "DL24_CH1", "DL24"},900{"I2SOUT4_CH2", "DL24_CH2", "DL24"},901902{"I2SOUT4", NULL, "I2SOUT4_CH1"},903{"I2SOUT4", NULL, "I2SOUT4_CH2"},904{"I2SOUT4", NULL, "I2SOUT4_CH3"},905{"I2SOUT4", NULL, "I2SOUT4_CH4"},906{"I2SOUT4", NULL, "I2SOUT4_CH5"},907{"I2SOUT4", NULL, "I2SOUT4_CH6"},908{"I2SOUT4", NULL, "I2SOUT4_CH7"},909{"I2SOUT4", NULL, "I2SOUT4_CH8"},910911{"I2SOUT4", NULL, "I2SIN0_EN", mtk_afe_i2s_share_connect},912{"I2SOUT4", NULL, "I2SIN1_EN", mtk_afe_i2s_share_connect},913{"I2SOUT4", NULL, "I2SOUT0_EN", mtk_afe_i2s_share_connect},914{"I2SOUT4", NULL, "I2SOUT1_EN", mtk_afe_i2s_share_connect},915{"I2SOUT4", NULL, "I2SOUT4_EN"},916917{"I2SOUT4", NULL, I2SIN0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},918{"I2SOUT4", NULL, I2SIN1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},919{"I2SOUT4", NULL, I2SOUT0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},920{"I2SOUT4", NULL, I2SOUT1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},921{"I2SOUT4", NULL, I2SOUT4_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},922{I2SOUT4_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},923{I2SOUT4_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},924{"I2SOUT4", NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},925{"I2SOUT4", NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},926/* CG */927{"I2SOUT4", NULL, "I2SOUT4_CG"},928929/* allow i2s on without codec on */930{"I2SIN0", NULL, "I2S_IN0_Mux"},931{"I2S_IN0_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},932933{"I2SIN1", NULL, "I2S_IN1_Mux"},934{"I2S_IN1_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},935936{"I2S_OUT0_Mux", "Dummy_Widget", "I2SOUT0"},937{"I2S_DUMMY_OUT", NULL, "I2S_OUT0_Mux"},938939{"I2S_OUT1_Mux", "Dummy_Widget", "I2SOUT1"},940{"I2S_DUMMY_OUT", NULL, "I2S_OUT1_Mux"},941942{"I2S_OUT4_Mux", "Dummy_Widget", "I2SOUT4"},943{"I2S_DUMMY_OUT", NULL, "I2S_OUT4_Mux"},944};945946/* i2s dai ops*/947static int mtk_dai_i2s_config(struct mtk_base_afe *afe,948struct snd_pcm_hw_params *params,949int i2s_id)950{951struct mt8189_afe_private *afe_priv = afe->platform_priv;952struct mtk_afe_i2s_priv *i2s_priv;953unsigned int rate = params_rate(params);954snd_pcm_format_t format = params_format(params);955int ret;956957if (i2s_id >= MT8189_DAI_NUM || i2s_id < 0)958return -EINVAL;959960i2s_priv = afe_priv->dai_priv[i2s_id];961if (!i2s_priv)962return -EINVAL;963964i2s_priv->rate = rate;965966dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n",967__func__, i2s_id, rate, format);968969switch (i2s_id) {970case MT8189_DAI_I2S_IN0:971/* ---etdm in --- */972regmap_update_bits(afe->regmap, ETDM_IN0_CON1,973REG_INITIAL_COUNT_MASK_SFT,9740x5 << REG_INITIAL_COUNT_SFT);975/* 3: pad top 5: no pad top */976regmap_update_bits(afe->regmap, ETDM_IN0_CON1,977REG_INITIAL_POINT_MASK_SFT,9780x5 << REG_INITIAL_POINT_SFT);979regmap_update_bits(afe->regmap, ETDM_IN0_CON1,980REG_LRCK_RESET_MASK_SFT,9810x1 << REG_LRCK_RESET_SFT);982regmap_update_bits(afe->regmap, ETDM_IN0_CON2,983REG_CLOCK_SOURCE_SEL_MASK_SFT,984ETDM_CLK_SOURCE_APLL <<985REG_CLOCK_SOURCE_SEL_SFT);986/* 0: manual 1: auto */987regmap_update_bits(afe->regmap, ETDM_IN0_CON2,988REG_CK_EN_SEL_AUTO_MASK_SFT,9890x1 << REG_CK_EN_SEL_AUTO_SFT);990regmap_update_bits(afe->regmap, ETDM_IN0_CON3,991REG_FS_TIMING_SEL_MASK_SFT,992get_etdm_rate(rate) <<993REG_FS_TIMING_SEL_SFT);994regmap_update_bits(afe->regmap, ETDM_IN0_CON4,995REG_RELATCH_1X_EN_SEL_MASK_SFT,996get_etdm_inconn_rate(rate) <<997REG_RELATCH_1X_EN_SEL_SFT);998999regmap_update_bits(afe->regmap, ETDM_IN0_CON8,1000REG_ETDM_USE_AFIFO_MASK_SFT,10010x0 << REG_ETDM_USE_AFIFO_SFT);1002regmap_update_bits(afe->regmap, ETDM_IN0_CON8,1003REG_AFIFO_MODE_MASK_SFT,10040x0 << REG_AFIFO_MODE_SFT);1005regmap_update_bits(afe->regmap, ETDM_IN0_CON9,1006REG_ALMOST_END_CH_COUNT_MASK_SFT,10070x0 << REG_ALMOST_END_CH_COUNT_SFT);1008regmap_update_bits(afe->regmap, ETDM_IN0_CON9,1009REG_ALMOST_END_BIT_COUNT_MASK_SFT,10100x0 << REG_ALMOST_END_BIT_COUNT_SFT);1011regmap_update_bits(afe->regmap, ETDM_IN0_CON9,1012REG_OUT2LATCH_TIME_MASK_SFT,10130x6 << REG_OUT2LATCH_TIME_SFT);10141015/* 5: TDM Mode */1016regmap_update_bits(afe->regmap, ETDM_IN0_CON0,1017REG_FMT_MASK_SFT, 0x0 << REG_FMT_SFT);10181019/* APLL */1020regmap_update_bits(afe->regmap, ETDM_IN0_CON0,1021REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT,1022ETDM_RELATCH_SEL_APLL1023<< REG_RELATCH_1X_EN_DOMAIN_SEL_SFT);1024regmap_update_bits(afe->regmap, ETDM_IN0_CON0,1025REG_BIT_LENGTH_MASK_SFT,1026get_etdm_lrck_width(format) <<1027REG_BIT_LENGTH_SFT);1028regmap_update_bits(afe->regmap, ETDM_IN0_CON0,1029REG_WORD_LENGTH_MASK_SFT,1030get_etdm_wlen(format) <<1031REG_WORD_LENGTH_SFT);10321033/* ---etdm cowork --- */1034regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0,1035ETDM_IN0_SLAVE_SEL_MASK_SFT,1036ETDM_SLAVE_SEL_ETDMOUT0_MASTER1037<< ETDM_IN0_SLAVE_SEL_SFT);1038break;1039case MT8189_DAI_I2S_IN1:1040/* ---etdm in --- */1041regmap_update_bits(afe->regmap, ETDM_IN1_CON1,1042REG_INITIAL_COUNT_MASK_SFT,10430x5 << REG_INITIAL_COUNT_SFT);1044/* 3: pad top 5: no pad top */1045regmap_update_bits(afe->regmap, ETDM_IN1_CON1,1046REG_INITIAL_POINT_MASK_SFT,10470x5 << REG_INITIAL_POINT_SFT);1048regmap_update_bits(afe->regmap, ETDM_IN1_CON1,1049REG_LRCK_RESET_MASK_SFT,10500x1 << REG_LRCK_RESET_SFT);1051regmap_update_bits(afe->regmap, ETDM_IN1_CON2,1052REG_CLOCK_SOURCE_SEL_MASK_SFT,1053ETDM_CLK_SOURCE_APLL <<1054REG_CLOCK_SOURCE_SEL_SFT);1055/* 0: manual 1: auto */1056regmap_update_bits(afe->regmap, ETDM_IN1_CON2,1057REG_CK_EN_SEL_AUTO_MASK_SFT,10580x1 << REG_CK_EN_SEL_AUTO_SFT);1059regmap_update_bits(afe->regmap, ETDM_IN1_CON3,1060REG_FS_TIMING_SEL_MASK_SFT,1061get_etdm_rate(rate) <<1062REG_FS_TIMING_SEL_SFT);1063regmap_update_bits(afe->regmap, ETDM_IN1_CON4,1064REG_RELATCH_1X_EN_SEL_MASK_SFT,1065get_etdm_inconn_rate(rate) <<1066REG_RELATCH_1X_EN_SEL_SFT);10671068regmap_update_bits(afe->regmap, ETDM_IN1_CON8,1069REG_ETDM_USE_AFIFO_MASK_SFT,10700x0 << REG_ETDM_USE_AFIFO_SFT);1071regmap_update_bits(afe->regmap, ETDM_IN1_CON8,1072REG_AFIFO_MODE_MASK_SFT,10730x0 << REG_AFIFO_MODE_SFT);1074regmap_update_bits(afe->regmap, ETDM_IN1_CON9,1075REG_ALMOST_END_CH_COUNT_MASK_SFT,10760x0 << REG_ALMOST_END_CH_COUNT_SFT);1077regmap_update_bits(afe->regmap, ETDM_IN1_CON9,1078REG_ALMOST_END_BIT_COUNT_MASK_SFT,10790x0 << REG_ALMOST_END_BIT_COUNT_SFT);1080regmap_update_bits(afe->regmap, ETDM_IN1_CON9,1081REG_OUT2LATCH_TIME_MASK_SFT,10820x6 << REG_OUT2LATCH_TIME_SFT);10831084/* 5: TDM Mode */1085regmap_update_bits(afe->regmap, ETDM_IN1_CON0,1086REG_FMT_MASK_SFT, 0x0 << REG_FMT_SFT);10871088/* APLL */1089regmap_update_bits(afe->regmap, ETDM_IN1_CON0,1090REG_RELATCH_1X_EN_DOMAIN_SEL_MASK_SFT,1091ETDM_RELATCH_SEL_APLL1092<< REG_RELATCH_1X_EN_DOMAIN_SEL_SFT);1093regmap_update_bits(afe->regmap, ETDM_IN1_CON0,1094REG_BIT_LENGTH_MASK_SFT,1095get_etdm_lrck_width(format) <<1096REG_BIT_LENGTH_SFT);1097regmap_update_bits(afe->regmap, ETDM_IN1_CON0,1098REG_WORD_LENGTH_MASK_SFT,1099get_etdm_wlen(format) <<1100REG_WORD_LENGTH_SFT);11011102/* ---etdm cowork --- */1103regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON1,1104ETDM_IN1_SLAVE_SEL_MASK_SFT,1105ETDM_SLAVE_SEL_ETDMOUT1_MASTER1106<< ETDM_IN1_SLAVE_SEL_SFT);1107break;1108case MT8189_DAI_I2S_OUT0:1109/* ---etdm out --- */1110regmap_update_bits(afe->regmap, ETDM_OUT0_CON1,1111OUT_REG_INITIAL_COUNT_MASK_SFT,11120x5 << OUT_REG_INITIAL_COUNT_SFT);1113regmap_update_bits(afe->regmap, ETDM_OUT0_CON1,1114OUT_REG_INITIAL_POINT_MASK_SFT,11150x6 << OUT_REG_INITIAL_POINT_SFT);1116regmap_update_bits(afe->regmap, ETDM_OUT0_CON1,1117OUT_REG_LRCK_RESET_MASK_SFT,11180x1 << OUT_REG_LRCK_RESET_SFT);1119regmap_update_bits(afe->regmap, ETDM_OUT0_CON4,1120OUT_REG_FS_TIMING_SEL_MASK_SFT,1121get_etdm_rate(rate) <<1122OUT_REG_FS_TIMING_SEL_SFT);1123regmap_update_bits(afe->regmap, ETDM_OUT0_CON4,1124OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT,1125ETDM_CLK_SOURCE_APLL <<1126OUT_REG_CLOCK_SOURCE_SEL_SFT);1127regmap_update_bits(afe->regmap, ETDM_OUT0_CON4,1128OUT_REG_RELATCH_EN_SEL_MASK_SFT,1129get_etdm_inconn_rate(rate) <<1130OUT_REG_RELATCH_EN_SEL_SFT);1131/* 5: TDM Mode */1132regmap_update_bits(afe->regmap, ETDM_OUT0_CON0,1133OUT_REG_FMT_MASK_SFT,11340x0 << OUT_REG_FMT_SFT);11351136/* APLL */1137regmap_update_bits(afe->regmap, ETDM_OUT0_CON0,1138OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT,1139ETDM_RELATCH_SEL_APLL1140<< OUT_REG_RELATCH_DOMAIN_SEL_SFT);1141regmap_update_bits(afe->regmap, ETDM_OUT0_CON0,1142OUT_REG_BIT_LENGTH_MASK_SFT,1143get_etdm_lrck_width(format) <<1144OUT_REG_BIT_LENGTH_SFT);1145regmap_update_bits(afe->regmap, ETDM_OUT0_CON0,1146OUT_REG_WORD_LENGTH_MASK_SFT,1147get_etdm_wlen(format) <<1148OUT_REG_WORD_LENGTH_SFT);11491150/* ---etdm cowork --- */1151regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0,1152ETDM_OUT0_SLAVE_SEL_MASK_SFT,1153ETDM_SLAVE_SEL_ETDMIN0_MASTER1154<< ETDM_OUT0_SLAVE_SEL_SFT);1155break;1156case MT8189_DAI_I2S_OUT1:1157/* ---etdm out --- */1158regmap_update_bits(afe->regmap, ETDM_OUT1_CON1,1159OUT_REG_INITIAL_COUNT_MASK_SFT,11600x5 << OUT_REG_INITIAL_COUNT_SFT);1161regmap_update_bits(afe->regmap, ETDM_OUT1_CON1,1162OUT_REG_INITIAL_POINT_MASK_SFT,11630x6 << OUT_REG_INITIAL_POINT_SFT);1164regmap_update_bits(afe->regmap, ETDM_OUT1_CON1,1165OUT_REG_LRCK_RESET_MASK_SFT,11660x1 << OUT_REG_LRCK_RESET_SFT);1167regmap_update_bits(afe->regmap, ETDM_OUT1_CON4,1168OUT_REG_FS_TIMING_SEL_MASK_SFT,1169get_etdm_rate(rate) <<1170OUT_REG_FS_TIMING_SEL_SFT);1171regmap_update_bits(afe->regmap, ETDM_OUT1_CON4,1172OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT,1173ETDM_CLK_SOURCE_APLL <<1174OUT_REG_CLOCK_SOURCE_SEL_SFT);1175regmap_update_bits(afe->regmap, ETDM_OUT1_CON4,1176OUT_REG_RELATCH_EN_SEL_MASK_SFT,1177get_etdm_inconn_rate(rate) <<1178OUT_REG_RELATCH_EN_SEL_SFT);1179/* 5: TDM Mode */1180regmap_update_bits(afe->regmap, ETDM_OUT1_CON0,1181OUT_REG_FMT_MASK_SFT,11820x0 << OUT_REG_FMT_SFT);11831184/* APLL */1185regmap_update_bits(afe->regmap, ETDM_OUT1_CON0,1186OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT,1187ETDM_RELATCH_SEL_APLL1188<< OUT_REG_RELATCH_DOMAIN_SEL_SFT);1189regmap_update_bits(afe->regmap, ETDM_OUT1_CON0,1190OUT_REG_BIT_LENGTH_MASK_SFT,1191get_etdm_lrck_width(format) <<1192OUT_REG_BIT_LENGTH_SFT);1193regmap_update_bits(afe->regmap, ETDM_OUT1_CON0,1194OUT_REG_WORD_LENGTH_MASK_SFT,1195get_etdm_wlen(format) <<1196OUT_REG_WORD_LENGTH_SFT);11971198/* ---etdm cowork --- */1199regmap_update_bits(afe->regmap, ETDM_0_3_COWORK_CON0,1200ETDM_OUT1_SLAVE_SEL_MASK_SFT,1201ETDM_SLAVE_SEL_ETDMIN1_MASTER1202<< ETDM_OUT1_SLAVE_SEL_SFT);1203break;1204case MT8189_DAI_I2S_OUT4:1205/* ---etdm out --- */1206regmap_update_bits(afe->regmap, ETDM_OUT4_CON1,1207OUT_REG_INITIAL_COUNT_MASK_SFT,12080x5 << OUT_REG_INITIAL_COUNT_SFT);1209regmap_update_bits(afe->regmap, ETDM_OUT4_CON1,1210OUT_REG_INITIAL_POINT_MASK_SFT,12110x6 << OUT_REG_INITIAL_POINT_SFT);1212regmap_update_bits(afe->regmap, ETDM_OUT4_CON1,1213OUT_REG_LRCK_RESET_MASK_SFT,12140x1 << OUT_REG_LRCK_RESET_SFT);1215regmap_update_bits(afe->regmap, ETDM_OUT4_CON4,1216OUT_REG_FS_TIMING_SEL_MASK_SFT,1217get_etdm_rate(rate) <<1218OUT_REG_FS_TIMING_SEL_SFT);1219regmap_update_bits(afe->regmap, ETDM_OUT4_CON4,1220OUT_REG_CLOCK_SOURCE_SEL_MASK_SFT,1221ETDM_CLK_SOURCE_APLL <<1222OUT_REG_CLOCK_SOURCE_SEL_SFT);1223regmap_update_bits(afe->regmap, ETDM_OUT4_CON4,1224OUT_REG_RELATCH_EN_SEL_MASK_SFT,1225get_etdm_inconn_rate(rate) <<1226OUT_REG_RELATCH_EN_SEL_SFT);1227/* 5: TDM Mode */1228regmap_update_bits(afe->regmap, ETDM_OUT4_CON0,1229OUT_REG_FMT_MASK_SFT,12300x0 << OUT_REG_FMT_SFT);12311232/* APLL */1233regmap_update_bits(afe->regmap, ETDM_OUT4_CON0,1234OUT_REG_RELATCH_DOMAIN_SEL_MASK_SFT,1235ETDM_RELATCH_SEL_APLL1236<< OUT_REG_RELATCH_DOMAIN_SEL_SFT);1237regmap_update_bits(afe->regmap, ETDM_OUT4_CON0,1238OUT_REG_BIT_LENGTH_MASK_SFT,1239get_etdm_lrck_width(format) <<1240OUT_REG_BIT_LENGTH_SFT);1241regmap_update_bits(afe->regmap, ETDM_OUT4_CON0,1242OUT_REG_WORD_LENGTH_MASK_SFT,1243get_etdm_wlen(format) <<1244OUT_REG_WORD_LENGTH_SFT);1245break;1246default:1247dev_err(afe->dev, "%s(), id %d not support\n",1248__func__, i2s_id);1249return -EINVAL;1250}12511252/* set share i2s */1253if (i2s_priv->share_i2s_id >= 0) {1254ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);1255if (ret)1256return ret;1257}12581259return 0;1260}12611262static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,1263struct snd_pcm_hw_params *params,1264struct snd_soc_dai *dai)1265{1266struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);12671268return mtk_dai_i2s_config(afe, params, dai->id);1269}12701271static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,1272int clk_id, unsigned int freq, int dir)1273{1274struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);1275struct mt8189_afe_private *afe_priv = afe->platform_priv;1276struct mtk_afe_i2s_priv *i2s_priv;1277int apll;1278int apll_rate;12791280if (dai->id >= MT8189_DAI_NUM || dai->id < 0 ||1281dir != SND_SOC_CLOCK_OUT)1282return -EINVAL;12831284i2s_priv = afe_priv->dai_priv[dai->id];1285if (!i2s_priv)1286return -EINVAL;12871288dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq);12891290apll = mt8189_get_apll_by_rate(afe, freq);1291apll_rate = mt8189_get_apll_rate(afe, apll);12921293if (freq > apll_rate || apll_rate % freq) {1294dev_err(afe->dev, "%s(), freq %d, apll_rate %d\n",1295__func__, freq, apll_rate);1296return -EINVAL;1297}12981299i2s_priv->mclk_rate = freq;1300i2s_priv->mclk_apll = apll;13011302if (i2s_priv->share_i2s_id > 0) {1303struct mtk_afe_i2s_priv *share_i2s_priv;13041305share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];1306if (!share_i2s_priv)1307return -EINVAL;13081309share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;1310share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;1311}13121313return 0;1314}13151316static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {1317.hw_params = mtk_dai_i2s_hw_params,1318.set_sysclk = mtk_dai_i2s_set_sysclk,1319};13201321/* dai driver */1322#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_192000)1323#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S8 |\1324SNDRV_PCM_FMTBIT_S16_LE |\1325SNDRV_PCM_FMTBIT_S24_LE |\1326SNDRV_PCM_FMTBIT_S32_LE)13271328#define MT8189_I2S_DAI(_name, _id, max_ch, dir) \1329{ \1330.name = #_name, \1331.id = _id, \1332.dir = { \1333.stream_name = #_name, \1334.channels_min = 1, \1335.channels_max = max_ch, \1336.rates = MTK_ETDM_RATES, \1337.formats = MTK_ETDM_FORMATS, \1338}, \1339.ops = &mtk_dai_i2s_ops, \1340}13411342static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {1343/* capture */1344MT8189_I2S_DAI(I2SIN0, MT8189_DAI_I2S_IN0, 2, capture),1345MT8189_I2S_DAI(I2SIN1, MT8189_DAI_I2S_IN1, 2, capture),1346/* playback */1347MT8189_I2S_DAI(I2SOUT0, MT8189_DAI_I2S_OUT0, 2, playback),1348MT8189_I2S_DAI(I2SOUT1, MT8189_DAI_I2S_OUT1, 2, playback),1349MT8189_I2S_DAI(I2SOUT4, MT8189_DAI_I2S_OUT4, 8, playback),1350};13511352static const struct mtk_afe_i2s_priv mt8189_i2s_priv[DAI_I2S_NUM] = {1353[DAI_I2SIN0] = {1354.id = MT8189_DAI_I2S_IN0,1355.mclk_id = MT8189_I2SIN0_MCK,1356.share_property_name = "i2sin0-share",1357.share_i2s_id = MT8189_DAI_I2S_OUT0,1358},1359[DAI_I2SIN1] = {1360.id = MT8189_DAI_I2S_IN1,1361.mclk_id = MT8189_I2SIN1_MCK,1362.share_property_name = "i2sin1-share",1363.share_i2s_id = MT8189_DAI_I2S_OUT1,1364},1365[DAI_I2SOUT0] = {1366.id = MT8189_DAI_I2S_OUT0,1367.mclk_id = MT8189_I2SOUT0_MCK,1368.share_property_name = "i2sout0-share",1369.share_i2s_id = -1,1370},1371[DAI_I2SOUT1] = {1372.id = MT8189_DAI_I2S_OUT1,1373.mclk_id = MT8189_I2SOUT1_MCK,1374.share_property_name = "i2sout1-share",1375.share_i2s_id = -1,1376},1377[DAI_I2SOUT4] = {1378.id = MT8189_DAI_I2S_OUT4,1379.mclk_id = MT8189_I2SIN1_MCK,1380.share_property_name = "i2sout4-share",1381.share_i2s_id = -1,1382},1383};13841385static int mt8189_dai_i2s_get_share(struct mtk_base_afe *afe)1386{1387struct mt8189_afe_private *afe_priv = afe->platform_priv;1388const struct device_node *of_node = afe->dev->of_node;13891390for (int i = 0; i < DAI_I2S_NUM; i++) {1391const char *of_str;1392struct mtk_afe_i2s_priv *i2s_priv =1393afe_priv->dai_priv[mt8189_i2s_priv[i].id];1394const char *property_name =1395mt8189_i2s_priv[i].share_property_name;13961397if (of_property_read_string(of_node, property_name, &of_str))1398continue;13991400i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str);1401}14021403return 0;1404}14051406static int init_i2s_priv_data(struct mtk_base_afe *afe)1407{1408struct mt8189_afe_private *afe_priv = afe->platform_priv;1409struct mtk_afe_i2s_priv *i2s_priv;14101411for (int i = 0; i < DAI_I2S_NUM; i++) {1412int id = mt8189_i2s_priv[i].id;1413size_t size = sizeof(struct mtk_afe_i2s_priv);14141415if (id >= MT8189_DAI_NUM || id < 0)1416return -EINVAL;14171418i2s_priv = devm_kzalloc(afe->dev, size, GFP_KERNEL);1419if (!i2s_priv)1420return -ENOMEM;14211422memcpy(i2s_priv, &mt8189_i2s_priv[i], size);14231424afe_priv->dai_priv[id] = i2s_priv;1425}14261427return 0;1428}14291430int mt8189_dai_i2s_register(struct mtk_base_afe *afe)1431{1432struct mtk_base_afe_dai *dai;1433int ret;14341435dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);1436if (!dai)1437return -ENOMEM;14381439dai->dai_drivers = mtk_dai_i2s_driver;1440dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);14411442dai->controls = mtk_dai_i2s_controls;1443dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);1444dai->dapm_widgets = mtk_dai_i2s_widgets;1445dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);1446dai->dapm_routes = mtk_dai_i2s_routes;1447dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);14481449/* set all dai i2s private data */1450ret = init_i2s_priv_data(afe);1451if (ret)1452return ret;14531454/* parse share i2s */1455ret = mt8189_dai_i2s_get_share(afe);1456if (ret)1457return ret;14581459list_add(&dai->list, &afe->sub_dais);14601461return 0;1462}146314641465