Path: blob/master/sound/soc/mediatek/mt8183/mt8183-dai-i2s.c
26488 views
// SPDX-License-Identifier: GPL-2.01//2// MediaTek ALSA SoC Audio DAI I2S Control3//4// Copyright (c) 2018 MediaTek Inc.5// Author: KaiChieh Chuang <[email protected]>67#include <linux/bitops.h>8#include <linux/regmap.h>9#include <sound/pcm_params.h>10#include "mt8183-afe-clk.h"11#include "mt8183-afe-common.h"12#include "mt8183-interconnection.h"13#include "mt8183-reg.h"1415enum {16I2S_FMT_EIAJ = 0,17I2S_FMT_I2S = 1,18};1920enum {21I2S_WLEN_16_BIT = 0,22I2S_WLEN_32_BIT = 1,23};2425enum {26I2S_HD_NORMAL = 0,27I2S_HD_LOW_JITTER = 1,28};2930enum {31I2S1_SEL_O28_O29 = 0,32I2S1_SEL_O03_O04 = 1,33};3435enum {36I2S_IN_PAD_CONNSYS = 0,37I2S_IN_PAD_IO_MUX = 1,38};3940struct mtk_afe_i2s_priv {41int id;42int rate; /* for determine which apll to use */43int low_jitter_en;4445int share_i2s_id;4647int mclk_id;48int mclk_rate;49int mclk_apll;5051int use_eiaj;52};5354static unsigned int get_i2s_wlen(snd_pcm_format_t format)55{56return snd_pcm_format_physical_width(format) <= 16 ?57I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;58}5960#define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"61#define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"62#define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"63#define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"64#define MTK_AFE_I2S5_KCONTROL_NAME "I2S5_HD_Mux"6566#define I2S0_HD_EN_W_NAME "I2S0_HD_EN"67#define I2S1_HD_EN_W_NAME "I2S1_HD_EN"68#define I2S2_HD_EN_W_NAME "I2S2_HD_EN"69#define I2S3_HD_EN_W_NAME "I2S3_HD_EN"70#define I2S5_HD_EN_W_NAME "I2S5_HD_EN"7172#define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"73#define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"74#define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"75#define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"76#define I2S5_MCLK_EN_W_NAME "I2S5_MCLK_EN"7778static int get_i2s_id_by_name(struct mtk_base_afe *afe,79const char *name)80{81if (strncmp(name, "I2S0", 4) == 0)82return MT8183_DAI_I2S_0;83else if (strncmp(name, "I2S1", 4) == 0)84return MT8183_DAI_I2S_1;85else if (strncmp(name, "I2S2", 4) == 0)86return MT8183_DAI_I2S_2;87else if (strncmp(name, "I2S3", 4) == 0)88return MT8183_DAI_I2S_3;89else if (strncmp(name, "I2S5", 4) == 0)90return MT8183_DAI_I2S_5;91else92return -EINVAL;93}9495static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,96const char *name)97{98struct mt8183_afe_private *afe_priv = afe->platform_priv;99int dai_id = get_i2s_id_by_name(afe, name);100101if (dai_id < 0)102return NULL;103104return afe_priv->dai_priv[dai_id];105}106107/* low jitter control */108static const char * const mt8183_i2s_hd_str[] = {109"Normal", "Low_Jitter"110};111112static const struct soc_enum mt8183_i2s_enum[] = {113SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str),114mt8183_i2s_hd_str),115};116117static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol,118struct snd_ctl_elem_value *ucontrol)119{120struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);121struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);122struct mtk_afe_i2s_priv *i2s_priv;123124i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);125126if (!i2s_priv) {127dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);128return -EINVAL;129}130131ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;132133return 0;134}135136static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,137struct snd_ctl_elem_value *ucontrol)138{139struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);140struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);141struct mtk_afe_i2s_priv *i2s_priv;142struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;143int hd_en, change;144145if (ucontrol->value.enumerated.item[0] >= e->items)146return -EINVAL;147148hd_en = ucontrol->value.integer.value[0];149150i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);151152if (!i2s_priv) {153dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);154return -EINVAL;155}156157change = i2s_priv->low_jitter_en != hd_en;158i2s_priv->low_jitter_en = hd_en;159160return change;161}162163static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {164SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8183_i2s_enum[0],165mt8183_i2s_hd_get, mt8183_i2s_hd_set),166SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8183_i2s_enum[0],167mt8183_i2s_hd_get, mt8183_i2s_hd_set),168SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8183_i2s_enum[0],169mt8183_i2s_hd_get, mt8183_i2s_hd_set),170SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8183_i2s_enum[0],171mt8183_i2s_hd_get, mt8183_i2s_hd_set),172SOC_ENUM_EXT(MTK_AFE_I2S5_KCONTROL_NAME, mt8183_i2s_enum[0],173mt8183_i2s_hd_get, mt8183_i2s_hd_set),174};175176/* dai component */177/* interconnection */178static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {179SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN0, I_DL1_CH1, 1, 0),180SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN0, I_DL2_CH1, 1, 0),181SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN0, I_DL3_CH1, 1, 0),182SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN0,183I_ADDA_UL_CH1, 1, 0),184SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN0,185I_PCM_1_CAP_CH1, 1, 0),186SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN0,187I_PCM_2_CAP_CH1, 1, 0),188};189190static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {191SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN1, I_DL1_CH2, 1, 0),192SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN1, I_DL2_CH2, 1, 0),193SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN1, I_DL3_CH2, 1, 0),194SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN1,195I_ADDA_UL_CH2, 1, 0),196SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN1,197I_PCM_1_CAP_CH1, 1, 0),198SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN1,199I_PCM_2_CAP_CH1, 1, 0),200SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN1,201I_PCM_1_CAP_CH2, 1, 0),202SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN1,203I_PCM_2_CAP_CH2, 1, 0),204};205206static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {207SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN28, I_DL1_CH1, 1, 0),208SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN28, I_DL2_CH1, 1, 0),209SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN28, I_DL3_CH1, 1, 0),210SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN28,211I_ADDA_UL_CH1, 1, 0),212SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN28,213I_PCM_1_CAP_CH1, 1, 0),214SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN28,215I_PCM_2_CAP_CH1, 1, 0),216};217218static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {219SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN29, I_DL1_CH2, 1, 0),220SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN29, I_DL2_CH2, 1, 0),221SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN29, I_DL3_CH2, 1, 0),222SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN29,223I_ADDA_UL_CH2, 1, 0),224SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN29,225I_PCM_1_CAP_CH1, 1, 0),226SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN29,227I_PCM_2_CAP_CH1, 1, 0),228SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN29,229I_PCM_1_CAP_CH2, 1, 0),230SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN29,231I_PCM_2_CAP_CH2, 1, 0),232};233234static const struct snd_kcontrol_new mtk_i2s5_ch1_mix[] = {235SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN30, I_DL1_CH1, 1, 0),236SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN30, I_DL2_CH1, 1, 0),237SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN30, I_DL3_CH1, 1, 0),238SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN30,239I_ADDA_UL_CH1, 1, 0),240SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN30,241I_PCM_1_CAP_CH1, 1, 0),242SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN30,243I_PCM_2_CAP_CH1, 1, 0),244};245246static const struct snd_kcontrol_new mtk_i2s5_ch2_mix[] = {247SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN31, I_DL1_CH2, 1, 0),248SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN31, I_DL2_CH2, 1, 0),249SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN31, I_DL3_CH2, 1, 0),250SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN31,251I_ADDA_UL_CH2, 1, 0),252SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN31,253I_PCM_1_CAP_CH1, 1, 0),254SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN31,255I_PCM_2_CAP_CH1, 1, 0),256SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN31,257I_PCM_1_CAP_CH2, 1, 0),258SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN31,259I_PCM_2_CAP_CH2, 1, 0),260};261262enum {263SUPPLY_SEQ_APLL,264SUPPLY_SEQ_I2S_MCLK_EN,265SUPPLY_SEQ_I2S_HD_EN,266SUPPLY_SEQ_I2S_EN,267};268269static int mtk_apll_event(struct snd_soc_dapm_widget *w,270struct snd_kcontrol *kcontrol,271int event)272{273struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);274struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);275276switch (event) {277case SND_SOC_DAPM_PRE_PMU:278if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)279mt8183_apll1_enable(afe);280else281mt8183_apll2_enable(afe);282break;283case SND_SOC_DAPM_POST_PMD:284if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)285mt8183_apll1_disable(afe);286else287mt8183_apll2_disable(afe);288break;289default:290break;291}292293return 0;294}295296static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,297struct snd_kcontrol *kcontrol,298int event)299{300struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);301struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);302struct mtk_afe_i2s_priv *i2s_priv;303304i2s_priv = get_i2s_priv_by_name(afe, w->name);305306if (!i2s_priv) {307dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);308return -EINVAL;309}310311switch (event) {312case SND_SOC_DAPM_PRE_PMU:313mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);314break;315case SND_SOC_DAPM_POST_PMD:316i2s_priv->mclk_rate = 0;317mt8183_mck_disable(afe, i2s_priv->mclk_id);318break;319default:320break;321}322323return 0;324}325326static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {327SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,328mtk_i2s1_ch1_mix,329ARRAY_SIZE(mtk_i2s1_ch1_mix)),330SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,331mtk_i2s1_ch2_mix,332ARRAY_SIZE(mtk_i2s1_ch2_mix)),333334SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,335mtk_i2s3_ch1_mix,336ARRAY_SIZE(mtk_i2s3_ch1_mix)),337SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,338mtk_i2s3_ch2_mix,339ARRAY_SIZE(mtk_i2s3_ch2_mix)),340341SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0,342mtk_i2s5_ch1_mix,343ARRAY_SIZE(mtk_i2s5_ch1_mix)),344SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0,345mtk_i2s5_ch2_mix,346ARRAY_SIZE(mtk_i2s5_ch2_mix)),347348/* i2s en*/349SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,350AFE_I2S_CON, I2S_EN_SFT, 0,351NULL, 0),352SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,353AFE_I2S_CON1, I2S_EN_SFT, 0,354NULL, 0),355SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,356AFE_I2S_CON2, I2S_EN_SFT, 0,357NULL, 0),358SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,359AFE_I2S_CON3, I2S_EN_SFT, 0,360NULL, 0),361SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN,362AFE_I2S_CON4, I2S5_EN_SFT, 0,363NULL, 0),364/* i2s hd en */365SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,366AFE_I2S_CON, I2S1_HD_EN_SFT, 0,367NULL, 0),368SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,369AFE_I2S_CON1, I2S2_HD_EN_SFT, 0,370NULL, 0),371SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,372AFE_I2S_CON2, I2S3_HD_EN_SFT, 0,373NULL, 0),374SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,375AFE_I2S_CON3, I2S4_HD_EN_SFT, 0,376NULL, 0),377SND_SOC_DAPM_SUPPLY_S(I2S5_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,378AFE_I2S_CON4, I2S5_HD_EN_SFT, 0,379NULL, 0),380381/* i2s mclk en */382SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,383SND_SOC_NOPM, 0, 0,384mtk_mclk_en_event,385SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),386SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,387SND_SOC_NOPM, 0, 0,388mtk_mclk_en_event,389SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),390SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,391SND_SOC_NOPM, 0, 0,392mtk_mclk_en_event,393SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),394SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,395SND_SOC_NOPM, 0, 0,396mtk_mclk_en_event,397SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),398SND_SOC_DAPM_SUPPLY_S(I2S5_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,399SND_SOC_NOPM, 0, 0,400mtk_mclk_en_event,401SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),402403/* apll */404SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,405SND_SOC_NOPM, 0, 0,406mtk_apll_event,407SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),408SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,409SND_SOC_NOPM, 0, 0,410mtk_apll_event,411SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),412};413414static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,415struct snd_soc_dapm_widget *sink)416{417struct snd_soc_dapm_widget *w = sink;418struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);419struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);420struct mtk_afe_i2s_priv *i2s_priv;421422i2s_priv = get_i2s_priv_by_name(afe, sink->name);423424if (!i2s_priv) {425dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);426return 0;427}428429if (i2s_priv->share_i2s_id < 0)430return 0;431432return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);433}434435static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,436struct snd_soc_dapm_widget *sink)437{438struct snd_soc_dapm_widget *w = sink;439struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);440struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);441struct mtk_afe_i2s_priv *i2s_priv;442443i2s_priv = get_i2s_priv_by_name(afe, sink->name);444445if (!i2s_priv) {446dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);447return 0;448}449450if (get_i2s_id_by_name(afe, sink->name) ==451get_i2s_id_by_name(afe, source->name))452return i2s_priv->low_jitter_en;453454/* check if share i2s need hd en */455if (i2s_priv->share_i2s_id < 0)456return 0;457458if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))459return i2s_priv->low_jitter_en;460461return 0;462}463464static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,465struct snd_soc_dapm_widget *sink)466{467struct snd_soc_dapm_widget *w = sink;468struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);469struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);470struct mtk_afe_i2s_priv *i2s_priv;471int cur_apll;472int i2s_need_apll;473474i2s_priv = get_i2s_priv_by_name(afe, w->name);475476if (!i2s_priv) {477dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);478return 0;479}480481/* which apll */482cur_apll = mt8183_get_apll_by_name(afe, source->name);483484/* choose APLL from i2s rate */485i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate);486487return (i2s_need_apll == cur_apll) ? 1 : 0;488}489490static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,491struct snd_soc_dapm_widget *sink)492{493struct snd_soc_dapm_widget *w = sink;494struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);495struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);496struct mtk_afe_i2s_priv *i2s_priv;497498i2s_priv = get_i2s_priv_by_name(afe, sink->name);499500if (!i2s_priv) {501dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);502return 0;503}504505if (get_i2s_id_by_name(afe, sink->name) ==506get_i2s_id_by_name(afe, source->name))507return (i2s_priv->mclk_rate > 0) ? 1 : 0;508509/* check if share i2s need mclk */510if (i2s_priv->share_i2s_id < 0)511return 0;512513if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))514return (i2s_priv->mclk_rate > 0) ? 1 : 0;515516return 0;517}518519static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,520struct snd_soc_dapm_widget *sink)521{522struct snd_soc_dapm_widget *w = sink;523struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);524struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);525struct mtk_afe_i2s_priv *i2s_priv;526int cur_apll;527528i2s_priv = get_i2s_priv_by_name(afe, w->name);529530if (!i2s_priv) {531dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);532return 0;533}534535/* which apll */536cur_apll = mt8183_get_apll_by_name(afe, source->name);537538return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;539}540541static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {542/* i2s0 */543{"I2S0", NULL, "I2S0_EN"},544{"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},545{"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},546{"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},547{"I2S0", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},548549{"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},550{"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},551{"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},552{"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},553{"I2S0", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},554{I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},555{I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},556557{"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},558{"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},559{"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},560{"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},561{"I2S0", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},562{I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},563{I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},564565/* i2s1 */566{"I2S1_CH1", "DL1_CH1", "DL1"},567{"I2S1_CH2", "DL1_CH2", "DL1"},568569{"I2S1_CH1", "DL2_CH1", "DL2"},570{"I2S1_CH2", "DL2_CH2", "DL2"},571572{"I2S1_CH1", "DL3_CH1", "DL3"},573{"I2S1_CH2", "DL3_CH2", "DL3"},574575{"I2S1", NULL, "I2S1_CH1"},576{"I2S1", NULL, "I2S1_CH2"},577578{"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},579{"I2S1", NULL, "I2S1_EN"},580{"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},581{"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},582{"I2S1", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},583584{"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},585{"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},586{"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},587{"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},588{"I2S1", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},589{I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},590{I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},591592{"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},593{"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},594{"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},595{"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},596{"I2S1", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},597{I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},598{I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},599600/* i2s2 */601{"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},602{"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},603{"I2S2", NULL, "I2S2_EN"},604{"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},605{"I2S2", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},606607{"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},608{"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},609{"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},610{"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},611{"I2S2", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},612{I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},613{I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},614615{"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},616{"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},617{"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},618{"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},619{"I2S2", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},620{I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},621{I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},622623/* i2s3 */624{"I2S3_CH1", "DL1_CH1", "DL1"},625{"I2S3_CH2", "DL1_CH2", "DL1"},626627{"I2S3_CH1", "DL2_CH1", "DL2"},628{"I2S3_CH2", "DL2_CH2", "DL2"},629630{"I2S3_CH1", "DL3_CH1", "DL3"},631{"I2S3_CH2", "DL3_CH2", "DL3"},632633{"I2S3", NULL, "I2S3_CH1"},634{"I2S3", NULL, "I2S3_CH2"},635636{"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},637{"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},638{"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},639{"I2S3", NULL, "I2S3_EN"},640{"I2S3", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},641642{"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},643{"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},644{"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},645{"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},646{"I2S3", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},647{I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},648{I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},649650{"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},651{"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},652{"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},653{"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},654{"I2S3", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},655{I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},656{I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},657658/* i2s5 */659{"I2S5_CH1", "DL1_CH1", "DL1"},660{"I2S5_CH2", "DL1_CH2", "DL1"},661662{"I2S5_CH1", "DL2_CH1", "DL2"},663{"I2S5_CH2", "DL2_CH2", "DL2"},664665{"I2S5_CH1", "DL3_CH1", "DL3"},666{"I2S5_CH2", "DL3_CH2", "DL3"},667668{"I2S5", NULL, "I2S5_CH1"},669{"I2S5", NULL, "I2S5_CH2"},670671{"I2S5", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},672{"I2S5", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},673{"I2S5", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},674{"I2S5", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},675{"I2S5", NULL, "I2S5_EN"},676677{"I2S5", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},678{"I2S5", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},679{"I2S5", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},680{"I2S5", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},681{"I2S5", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},682{I2S5_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},683{I2S5_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},684685{"I2S5", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},686{"I2S5", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},687{"I2S5", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},688{"I2S5", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},689{"I2S5", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},690{I2S5_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},691{I2S5_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},692};693694/* dai ops */695static int mtk_dai_i2s_config(struct mtk_base_afe *afe,696struct snd_pcm_hw_params *params,697int i2s_id)698{699struct mt8183_afe_private *afe_priv = afe->platform_priv;700struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];701702unsigned int rate = params_rate(params);703unsigned int rate_reg = mt8183_rate_transform(afe->dev,704rate, i2s_id);705snd_pcm_format_t format = params_format(params);706unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT;707int ret = 0;708709if (i2s_priv) {710i2s_priv->rate = rate;711712if (i2s_priv->use_eiaj)713fmt_con = I2S_FMT_EIAJ << I2S_FMT_SFT;714} else {715dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);716}717718switch (i2s_id) {719case MT8183_DAI_I2S_0:720regmap_update_bits(afe->regmap, AFE_DAC_CON1,721I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);722i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;723i2s_con |= fmt_con;724i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;725regmap_update_bits(afe->regmap, AFE_I2S_CON,7260xffffeffe, i2s_con);727break;728case MT8183_DAI_I2S_1:729i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;730i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;731i2s_con |= fmt_con;732i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;733regmap_update_bits(afe->regmap, AFE_I2S_CON1,7340xffffeffe, i2s_con);735break;736case MT8183_DAI_I2S_2:737i2s_con = 8 << I2S3_UPDATE_WORD_SFT;738i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;739i2s_con |= fmt_con;740i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;741regmap_update_bits(afe->regmap, AFE_I2S_CON2,7420xffffeffe, i2s_con);743break;744case MT8183_DAI_I2S_3:745i2s_con = rate_reg << I2S4_OUT_MODE_SFT;746i2s_con |= fmt_con;747i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;748regmap_update_bits(afe->regmap, AFE_I2S_CON3,7490xffffeffe, i2s_con);750break;751case MT8183_DAI_I2S_5:752i2s_con = rate_reg << I2S5_OUT_MODE_SFT;753i2s_con |= fmt_con;754i2s_con |= get_i2s_wlen(format) << I2S5_WLEN_SFT;755regmap_update_bits(afe->regmap, AFE_I2S_CON4,7560xffffeffe, i2s_con);757break;758default:759dev_warn(afe->dev, "%s(), id %d not support\n",760__func__, i2s_id);761return -EINVAL;762}763764/* set share i2s */765if (i2s_priv && i2s_priv->share_i2s_id >= 0)766ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);767768return ret;769}770771static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,772struct snd_pcm_hw_params *params,773struct snd_soc_dai *dai)774{775struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);776777return mtk_dai_i2s_config(afe, params, dai->id);778}779780static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,781int clk_id, unsigned int freq, int dir)782{783struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);784struct mt8183_afe_private *afe_priv = afe->platform_priv;785struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];786int apll;787int apll_rate;788789if (!i2s_priv) {790dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);791return -EINVAL;792}793794if (dir != SND_SOC_CLOCK_OUT) {795dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);796return -EINVAL;797}798799apll = mt8183_get_apll_by_rate(afe, freq);800apll_rate = mt8183_get_apll_rate(afe, apll);801802if (freq > apll_rate) {803dev_warn(afe->dev, "%s(), freq > apll rate", __func__);804return -EINVAL;805}806807if (apll_rate % freq != 0) {808dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz",809__func__);810return -EINVAL;811}812813i2s_priv->mclk_rate = freq;814i2s_priv->mclk_apll = apll;815816if (i2s_priv->share_i2s_id > 0) {817struct mtk_afe_i2s_priv *share_i2s_priv;818819share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];820if (!share_i2s_priv) {821dev_warn(afe->dev, "%s(), share_i2s_priv == NULL",822__func__);823return -EINVAL;824}825826share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;827share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;828}829830return 0;831}832833static int mtk_dai_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)834{835struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);836struct mt8183_afe_private *afe_priv = afe->platform_priv;837struct mtk_afe_i2s_priv *i2s_priv;838839switch (dai->id) {840case MT8183_DAI_I2S_0:841case MT8183_DAI_I2S_1:842case MT8183_DAI_I2S_2:843case MT8183_DAI_I2S_3:844case MT8183_DAI_I2S_5:845break;846default:847dev_warn(afe->dev, "%s(), id %d not support\n",848__func__, dai->id);849return -EINVAL;850}851i2s_priv = afe_priv->dai_priv[dai->id];852853switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {854case SND_SOC_DAIFMT_LEFT_J:855i2s_priv->use_eiaj = 1;856break;857case SND_SOC_DAIFMT_I2S:858i2s_priv->use_eiaj = 0;859break;860default:861dev_warn(afe->dev, "%s(), DAI format %d not support\n",862__func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);863return -EINVAL;864}865866return 0;867}868869static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {870.hw_params = mtk_dai_i2s_hw_params,871.set_sysclk = mtk_dai_i2s_set_sysclk,872.set_fmt = mtk_dai_i2s_set_fmt,873};874875/* dai driver */876#define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\877SNDRV_PCM_RATE_88200 |\878SNDRV_PCM_RATE_96000 |\879SNDRV_PCM_RATE_176400 |\880SNDRV_PCM_RATE_192000)881882#define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\883SNDRV_PCM_FMTBIT_S24_LE |\884SNDRV_PCM_FMTBIT_S32_LE)885886static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {887{888.name = "I2S0",889.id = MT8183_DAI_I2S_0,890.capture = {891.stream_name = "I2S0",892.channels_min = 1,893.channels_max = 2,894.rates = MTK_I2S_RATES,895.formats = MTK_I2S_FORMATS,896},897.ops = &mtk_dai_i2s_ops,898},899{900.name = "I2S1",901.id = MT8183_DAI_I2S_1,902.playback = {903.stream_name = "I2S1",904.channels_min = 1,905.channels_max = 2,906.rates = MTK_I2S_RATES,907.formats = MTK_I2S_FORMATS,908},909.ops = &mtk_dai_i2s_ops,910},911{912.name = "I2S2",913.id = MT8183_DAI_I2S_2,914.capture = {915.stream_name = "I2S2",916.channels_min = 1,917.channels_max = 2,918.rates = MTK_I2S_RATES,919.formats = MTK_I2S_FORMATS,920},921.ops = &mtk_dai_i2s_ops,922},923{924.name = "I2S3",925.id = MT8183_DAI_I2S_3,926.playback = {927.stream_name = "I2S3",928.channels_min = 1,929.channels_max = 2,930.rates = MTK_I2S_RATES,931.formats = MTK_I2S_FORMATS,932},933.ops = &mtk_dai_i2s_ops,934},935{936.name = "I2S5",937.id = MT8183_DAI_I2S_5,938.playback = {939.stream_name = "I2S5",940.channels_min = 1,941.channels_max = 2,942.rates = MTK_I2S_RATES,943.formats = MTK_I2S_FORMATS,944},945.ops = &mtk_dai_i2s_ops,946},947};948949/* this enum is merely for mtk_afe_i2s_priv declare */950enum {951DAI_I2S0 = 0,952DAI_I2S1,953DAI_I2S2,954DAI_I2S3,955DAI_I2S5,956DAI_I2S_NUM,957};958959static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = {960[DAI_I2S0] = {961.id = MT8183_DAI_I2S_0,962.mclk_id = MT8183_I2S0_MCK,963.share_i2s_id = -1,964},965[DAI_I2S1] = {966.id = MT8183_DAI_I2S_1,967.mclk_id = MT8183_I2S1_MCK,968.share_i2s_id = -1,969},970[DAI_I2S2] = {971.id = MT8183_DAI_I2S_2,972.mclk_id = MT8183_I2S2_MCK,973.share_i2s_id = -1,974},975[DAI_I2S3] = {976.id = MT8183_DAI_I2S_3,977.mclk_id = MT8183_I2S3_MCK,978.share_i2s_id = -1,979},980[DAI_I2S5] = {981.id = MT8183_DAI_I2S_5,982.mclk_id = MT8183_I2S5_MCK,983.share_i2s_id = -1,984},985};986987/**988* mt8183_dai_i2s_set_share() - Set up I2S ports to share a single clock.989* @afe: Pointer to &struct mtk_base_afe990* @main_i2s_name: The name of the I2S port that will provide the clock991* @secondary_i2s_name: The name of the I2S port that will use this clock992*/993int mt8183_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,994const char *secondary_i2s_name)995{996struct mtk_afe_i2s_priv *secondary_i2s_priv;997int main_i2s_id;998999secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);1000if (!secondary_i2s_priv)1001return -EINVAL;10021003main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);1004if (main_i2s_id < 0)1005return main_i2s_id;10061007secondary_i2s_priv->share_i2s_id = main_i2s_id;10081009return 0;1010}1011EXPORT_SYMBOL_GPL(mt8183_dai_i2s_set_share);10121013static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe)1014{1015struct mt8183_afe_private *afe_priv = afe->platform_priv;1016struct mtk_afe_i2s_priv *i2s_priv;1017int i;10181019for (i = 0; i < DAI_I2S_NUM; i++) {1020i2s_priv = devm_kzalloc(afe->dev,1021sizeof(struct mtk_afe_i2s_priv),1022GFP_KERNEL);1023if (!i2s_priv)1024return -ENOMEM;10251026memcpy(i2s_priv, &mt8183_i2s_priv[i],1027sizeof(struct mtk_afe_i2s_priv));10281029afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv;1030}10311032return 0;1033}10341035int mt8183_dai_i2s_register(struct mtk_base_afe *afe)1036{1037struct mtk_base_afe_dai *dai;10381039dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);1040if (!dai)1041return -ENOMEM;10421043list_add(&dai->list, &afe->sub_dais);10441045dai->dai_drivers = mtk_dai_i2s_driver;1046dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);10471048dai->controls = mtk_dai_i2s_controls;1049dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);1050dai->dapm_widgets = mtk_dai_i2s_widgets;1051dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);1052dai->dapm_routes = mtk_dai_i2s_routes;1053dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);10541055/* set all dai i2s private data */1056return mt8183_dai_i2s_set_priv(afe);1057}105810591060