0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitops.h>
0009 #include <linux/regmap.h>
0010 #include <sound/pcm_params.h>
0011 #include "mt8183-afe-clk.h"
0012 #include "mt8183-afe-common.h"
0013 #include "mt8183-interconnection.h"
0014 #include "mt8183-reg.h"
0015
0016 enum {
0017 I2S_FMT_EIAJ = 0,
0018 I2S_FMT_I2S = 1,
0019 };
0020
0021 enum {
0022 I2S_WLEN_16_BIT = 0,
0023 I2S_WLEN_32_BIT = 1,
0024 };
0025
0026 enum {
0027 I2S_HD_NORMAL = 0,
0028 I2S_HD_LOW_JITTER = 1,
0029 };
0030
0031 enum {
0032 I2S1_SEL_O28_O29 = 0,
0033 I2S1_SEL_O03_O04 = 1,
0034 };
0035
0036 enum {
0037 I2S_IN_PAD_CONNSYS = 0,
0038 I2S_IN_PAD_IO_MUX = 1,
0039 };
0040
0041 struct mtk_afe_i2s_priv {
0042 int id;
0043 int rate;
0044 int low_jitter_en;
0045
0046 const char *share_property_name;
0047 int share_i2s_id;
0048
0049 int mclk_id;
0050 int mclk_rate;
0051 int mclk_apll;
0052
0053 int use_eiaj;
0054 };
0055
0056 static unsigned int get_i2s_wlen(snd_pcm_format_t format)
0057 {
0058 return snd_pcm_format_physical_width(format) <= 16 ?
0059 I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
0060 }
0061
0062 #define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
0063 #define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
0064 #define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
0065 #define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
0066 #define MTK_AFE_I2S5_KCONTROL_NAME "I2S5_HD_Mux"
0067
0068 #define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
0069 #define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
0070 #define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
0071 #define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
0072 #define I2S5_HD_EN_W_NAME "I2S5_HD_EN"
0073
0074 #define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
0075 #define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
0076 #define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
0077 #define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
0078 #define I2S5_MCLK_EN_W_NAME "I2S5_MCLK_EN"
0079
0080 static int get_i2s_id_by_name(struct mtk_base_afe *afe,
0081 const char *name)
0082 {
0083 if (strncmp(name, "I2S0", 4) == 0)
0084 return MT8183_DAI_I2S_0;
0085 else if (strncmp(name, "I2S1", 4) == 0)
0086 return MT8183_DAI_I2S_1;
0087 else if (strncmp(name, "I2S2", 4) == 0)
0088 return MT8183_DAI_I2S_2;
0089 else if (strncmp(name, "I2S3", 4) == 0)
0090 return MT8183_DAI_I2S_3;
0091 else if (strncmp(name, "I2S5", 4) == 0)
0092 return MT8183_DAI_I2S_5;
0093 else
0094 return -EINVAL;
0095 }
0096
0097 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
0098 const char *name)
0099 {
0100 struct mt8183_afe_private *afe_priv = afe->platform_priv;
0101 int dai_id = get_i2s_id_by_name(afe, name);
0102
0103 if (dai_id < 0)
0104 return NULL;
0105
0106 return afe_priv->dai_priv[dai_id];
0107 }
0108
0109
0110 static const char * const mt8183_i2s_hd_str[] = {
0111 "Normal", "Low_Jitter"
0112 };
0113
0114 static const struct soc_enum mt8183_i2s_enum[] = {
0115 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str),
0116 mt8183_i2s_hd_str),
0117 };
0118
0119 static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol,
0120 struct snd_ctl_elem_value *ucontrol)
0121 {
0122 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0123 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0124 struct mtk_afe_i2s_priv *i2s_priv;
0125
0126 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
0127
0128 if (!i2s_priv) {
0129 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0130 return -EINVAL;
0131 }
0132
0133 ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
0134
0135 return 0;
0136 }
0137
0138 static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
0139 struct snd_ctl_elem_value *ucontrol)
0140 {
0141 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
0142 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0143 struct mtk_afe_i2s_priv *i2s_priv;
0144 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
0145 int hd_en;
0146
0147 if (ucontrol->value.enumerated.item[0] >= e->items)
0148 return -EINVAL;
0149
0150 hd_en = ucontrol->value.integer.value[0];
0151
0152 dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
0153 __func__, kcontrol->id.name, hd_en);
0154
0155 i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
0156
0157 if (!i2s_priv) {
0158 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0159 return -EINVAL;
0160 }
0161
0162 i2s_priv->low_jitter_en = hd_en;
0163
0164 return 0;
0165 }
0166
0167 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
0168 SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8183_i2s_enum[0],
0169 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
0170 SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8183_i2s_enum[0],
0171 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
0172 SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8183_i2s_enum[0],
0173 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
0174 SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8183_i2s_enum[0],
0175 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
0176 SOC_ENUM_EXT(MTK_AFE_I2S5_KCONTROL_NAME, mt8183_i2s_enum[0],
0177 mt8183_i2s_hd_get, mt8183_i2s_hd_set),
0178 };
0179
0180
0181
0182 static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
0183 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN0, I_DL1_CH1, 1, 0),
0184 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN0, I_DL2_CH1, 1, 0),
0185 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN0, I_DL3_CH1, 1, 0),
0186 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN0,
0187 I_ADDA_UL_CH1, 1, 0),
0188 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN0,
0189 I_PCM_1_CAP_CH1, 1, 0),
0190 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN0,
0191 I_PCM_2_CAP_CH1, 1, 0),
0192 };
0193
0194 static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
0195 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN1, I_DL1_CH2, 1, 0),
0196 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN1, I_DL2_CH2, 1, 0),
0197 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN1, I_DL3_CH2, 1, 0),
0198 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN1,
0199 I_ADDA_UL_CH2, 1, 0),
0200 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN1,
0201 I_PCM_1_CAP_CH1, 1, 0),
0202 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN1,
0203 I_PCM_2_CAP_CH1, 1, 0),
0204 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN1,
0205 I_PCM_1_CAP_CH2, 1, 0),
0206 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN1,
0207 I_PCM_2_CAP_CH2, 1, 0),
0208 };
0209
0210 static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
0211 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN28, I_DL1_CH1, 1, 0),
0212 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN28, I_DL2_CH1, 1, 0),
0213 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN28, I_DL3_CH1, 1, 0),
0214 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN28,
0215 I_ADDA_UL_CH1, 1, 0),
0216 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN28,
0217 I_PCM_1_CAP_CH1, 1, 0),
0218 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN28,
0219 I_PCM_2_CAP_CH1, 1, 0),
0220 };
0221
0222 static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
0223 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN29, I_DL1_CH2, 1, 0),
0224 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN29, I_DL2_CH2, 1, 0),
0225 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN29, I_DL3_CH2, 1, 0),
0226 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN29,
0227 I_ADDA_UL_CH2, 1, 0),
0228 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN29,
0229 I_PCM_1_CAP_CH1, 1, 0),
0230 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN29,
0231 I_PCM_2_CAP_CH1, 1, 0),
0232 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN29,
0233 I_PCM_1_CAP_CH2, 1, 0),
0234 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN29,
0235 I_PCM_2_CAP_CH2, 1, 0),
0236 };
0237
0238 static const struct snd_kcontrol_new mtk_i2s5_ch1_mix[] = {
0239 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN30, I_DL1_CH1, 1, 0),
0240 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN30, I_DL2_CH1, 1, 0),
0241 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN30, I_DL3_CH1, 1, 0),
0242 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN30,
0243 I_ADDA_UL_CH1, 1, 0),
0244 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN30,
0245 I_PCM_1_CAP_CH1, 1, 0),
0246 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN30,
0247 I_PCM_2_CAP_CH1, 1, 0),
0248 };
0249
0250 static const struct snd_kcontrol_new mtk_i2s5_ch2_mix[] = {
0251 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN31, I_DL1_CH2, 1, 0),
0252 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN31, I_DL2_CH2, 1, 0),
0253 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN31, I_DL3_CH2, 1, 0),
0254 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN31,
0255 I_ADDA_UL_CH2, 1, 0),
0256 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN31,
0257 I_PCM_1_CAP_CH1, 1, 0),
0258 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN31,
0259 I_PCM_2_CAP_CH1, 1, 0),
0260 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN31,
0261 I_PCM_1_CAP_CH2, 1, 0),
0262 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN31,
0263 I_PCM_2_CAP_CH2, 1, 0),
0264 };
0265
0266 enum {
0267 SUPPLY_SEQ_APLL,
0268 SUPPLY_SEQ_I2S_MCLK_EN,
0269 SUPPLY_SEQ_I2S_HD_EN,
0270 SUPPLY_SEQ_I2S_EN,
0271 };
0272
0273 static int mtk_apll_event(struct snd_soc_dapm_widget *w,
0274 struct snd_kcontrol *kcontrol,
0275 int event)
0276 {
0277 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0278 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0279
0280 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
0281 __func__, w->name, event);
0282
0283 switch (event) {
0284 case SND_SOC_DAPM_PRE_PMU:
0285 if (strcmp(w->name, APLL1_W_NAME) == 0)
0286 mt8183_apll1_enable(afe);
0287 else
0288 mt8183_apll2_enable(afe);
0289 break;
0290 case SND_SOC_DAPM_POST_PMD:
0291 if (strcmp(w->name, APLL1_W_NAME) == 0)
0292 mt8183_apll1_disable(afe);
0293 else
0294 mt8183_apll2_disable(afe);
0295 break;
0296 default:
0297 break;
0298 }
0299
0300 return 0;
0301 }
0302
0303 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
0304 struct snd_kcontrol *kcontrol,
0305 int event)
0306 {
0307 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0308 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0309 struct mtk_afe_i2s_priv *i2s_priv;
0310
0311 dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
0312 __func__, w->name, event);
0313
0314 i2s_priv = get_i2s_priv_by_name(afe, w->name);
0315
0316 if (!i2s_priv) {
0317 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0318 return -EINVAL;
0319 }
0320
0321 switch (event) {
0322 case SND_SOC_DAPM_PRE_PMU:
0323 mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
0324 break;
0325 case SND_SOC_DAPM_POST_PMD:
0326 i2s_priv->mclk_rate = 0;
0327 mt8183_mck_disable(afe, i2s_priv->mclk_id);
0328 break;
0329 default:
0330 break;
0331 }
0332
0333 return 0;
0334 }
0335
0336 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
0337 SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
0338 mtk_i2s1_ch1_mix,
0339 ARRAY_SIZE(mtk_i2s1_ch1_mix)),
0340 SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
0341 mtk_i2s1_ch2_mix,
0342 ARRAY_SIZE(mtk_i2s1_ch2_mix)),
0343
0344 SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
0345 mtk_i2s3_ch1_mix,
0346 ARRAY_SIZE(mtk_i2s3_ch1_mix)),
0347 SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
0348 mtk_i2s3_ch2_mix,
0349 ARRAY_SIZE(mtk_i2s3_ch2_mix)),
0350
0351 SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0,
0352 mtk_i2s5_ch1_mix,
0353 ARRAY_SIZE(mtk_i2s5_ch1_mix)),
0354 SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0,
0355 mtk_i2s5_ch2_mix,
0356 ARRAY_SIZE(mtk_i2s5_ch2_mix)),
0357
0358
0359 SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
0360 AFE_I2S_CON, I2S_EN_SFT, 0,
0361 NULL, 0),
0362 SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
0363 AFE_I2S_CON1, I2S_EN_SFT, 0,
0364 NULL, 0),
0365 SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
0366 AFE_I2S_CON2, I2S_EN_SFT, 0,
0367 NULL, 0),
0368 SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
0369 AFE_I2S_CON3, I2S_EN_SFT, 0,
0370 NULL, 0),
0371 SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN,
0372 AFE_I2S_CON4, I2S5_EN_SFT, 0,
0373 NULL, 0),
0374
0375 SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
0376 AFE_I2S_CON, I2S1_HD_EN_SFT, 0,
0377 NULL, 0),
0378 SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
0379 AFE_I2S_CON1, I2S2_HD_EN_SFT, 0,
0380 NULL, 0),
0381 SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
0382 AFE_I2S_CON2, I2S3_HD_EN_SFT, 0,
0383 NULL, 0),
0384 SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
0385 AFE_I2S_CON3, I2S4_HD_EN_SFT, 0,
0386 NULL, 0),
0387 SND_SOC_DAPM_SUPPLY_S(I2S5_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
0388 AFE_I2S_CON4, I2S5_HD_EN_SFT, 0,
0389 NULL, 0),
0390
0391
0392 SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
0393 SND_SOC_NOPM, 0, 0,
0394 mtk_mclk_en_event,
0395 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0396 SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
0397 SND_SOC_NOPM, 0, 0,
0398 mtk_mclk_en_event,
0399 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0400 SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
0401 SND_SOC_NOPM, 0, 0,
0402 mtk_mclk_en_event,
0403 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0404 SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
0405 SND_SOC_NOPM, 0, 0,
0406 mtk_mclk_en_event,
0407 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0408 SND_SOC_DAPM_SUPPLY_S(I2S5_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
0409 SND_SOC_NOPM, 0, 0,
0410 mtk_mclk_en_event,
0411 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0412
0413
0414 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
0415 SND_SOC_NOPM, 0, 0,
0416 mtk_apll_event,
0417 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0418 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
0419 SND_SOC_NOPM, 0, 0,
0420 mtk_apll_event,
0421 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
0422 };
0423
0424 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
0425 struct snd_soc_dapm_widget *sink)
0426 {
0427 struct snd_soc_dapm_widget *w = sink;
0428 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0429 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0430 struct mtk_afe_i2s_priv *i2s_priv;
0431
0432 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
0433
0434 if (!i2s_priv) {
0435 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0436 return 0;
0437 }
0438
0439 if (i2s_priv->share_i2s_id < 0)
0440 return 0;
0441
0442 return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
0443 }
0444
0445 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
0446 struct snd_soc_dapm_widget *sink)
0447 {
0448 struct snd_soc_dapm_widget *w = sink;
0449 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0450 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0451 struct mtk_afe_i2s_priv *i2s_priv;
0452
0453 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
0454
0455 if (!i2s_priv) {
0456 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0457 return 0;
0458 }
0459
0460 if (get_i2s_id_by_name(afe, sink->name) ==
0461 get_i2s_id_by_name(afe, source->name))
0462 return i2s_priv->low_jitter_en;
0463
0464
0465 if (i2s_priv->share_i2s_id < 0)
0466 return 0;
0467
0468 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
0469 return i2s_priv->low_jitter_en;
0470
0471 return 0;
0472 }
0473
0474 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
0475 struct snd_soc_dapm_widget *sink)
0476 {
0477 struct snd_soc_dapm_widget *w = sink;
0478 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0479 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0480 struct mtk_afe_i2s_priv *i2s_priv;
0481 int cur_apll;
0482 int i2s_need_apll;
0483
0484 i2s_priv = get_i2s_priv_by_name(afe, w->name);
0485
0486 if (!i2s_priv) {
0487 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0488 return 0;
0489 }
0490
0491
0492 cur_apll = mt8183_get_apll_by_name(afe, source->name);
0493
0494
0495 i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate);
0496
0497 return (i2s_need_apll == cur_apll) ? 1 : 0;
0498 }
0499
0500 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
0501 struct snd_soc_dapm_widget *sink)
0502 {
0503 struct snd_soc_dapm_widget *w = sink;
0504 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0505 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0506 struct mtk_afe_i2s_priv *i2s_priv;
0507
0508 i2s_priv = get_i2s_priv_by_name(afe, sink->name);
0509
0510 if (!i2s_priv) {
0511 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0512 return 0;
0513 }
0514
0515 if (get_i2s_id_by_name(afe, sink->name) ==
0516 get_i2s_id_by_name(afe, source->name))
0517 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
0518
0519
0520 if (i2s_priv->share_i2s_id < 0)
0521 return 0;
0522
0523 if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
0524 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
0525
0526 return 0;
0527 }
0528
0529 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
0530 struct snd_soc_dapm_widget *sink)
0531 {
0532 struct snd_soc_dapm_widget *w = sink;
0533 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0534 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0535 struct mtk_afe_i2s_priv *i2s_priv;
0536 int cur_apll;
0537
0538 i2s_priv = get_i2s_priv_by_name(afe, w->name);
0539
0540 if (!i2s_priv) {
0541 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0542 return 0;
0543 }
0544
0545
0546 cur_apll = mt8183_get_apll_by_name(afe, source->name);
0547
0548 return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
0549 }
0550
0551 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
0552
0553 {"I2S0", NULL, "I2S0_EN"},
0554 {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
0555 {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
0556 {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
0557 {"I2S0", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
0558
0559 {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0560 {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0561 {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0562 {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0563 {"I2S0", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0564 {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
0565 {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
0566
0567 {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0568 {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0569 {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0570 {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0571 {"I2S0", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0572 {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
0573 {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
0574
0575
0576 {"I2S1_CH1", "DL1_CH1", "DL1"},
0577 {"I2S1_CH2", "DL1_CH2", "DL1"},
0578
0579 {"I2S1_CH1", "DL2_CH1", "DL2"},
0580 {"I2S1_CH2", "DL2_CH2", "DL2"},
0581
0582 {"I2S1_CH1", "DL3_CH1", "DL3"},
0583 {"I2S1_CH2", "DL3_CH2", "DL3"},
0584
0585 {"I2S1", NULL, "I2S1_CH1"},
0586 {"I2S1", NULL, "I2S1_CH2"},
0587
0588 {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
0589 {"I2S1", NULL, "I2S1_EN"},
0590 {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
0591 {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
0592 {"I2S1", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
0593
0594 {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0595 {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0596 {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0597 {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0598 {"I2S1", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0599 {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
0600 {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
0601
0602 {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0603 {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0604 {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0605 {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0606 {"I2S1", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0607 {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
0608 {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
0609
0610
0611 {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
0612 {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
0613 {"I2S2", NULL, "I2S2_EN"},
0614 {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
0615 {"I2S2", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
0616
0617 {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0618 {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0619 {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0620 {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0621 {"I2S2", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0622 {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
0623 {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
0624
0625 {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0626 {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0627 {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0628 {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0629 {"I2S2", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0630 {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
0631 {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
0632
0633
0634 {"I2S3_CH1", "DL1_CH1", "DL1"},
0635 {"I2S3_CH2", "DL1_CH2", "DL1"},
0636
0637 {"I2S3_CH1", "DL2_CH1", "DL2"},
0638 {"I2S3_CH2", "DL2_CH2", "DL2"},
0639
0640 {"I2S3_CH1", "DL3_CH1", "DL3"},
0641 {"I2S3_CH2", "DL3_CH2", "DL3"},
0642
0643 {"I2S3", NULL, "I2S3_CH1"},
0644 {"I2S3", NULL, "I2S3_CH2"},
0645
0646 {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
0647 {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
0648 {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
0649 {"I2S3", NULL, "I2S3_EN"},
0650 {"I2S3", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
0651
0652 {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0653 {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0654 {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0655 {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0656 {"I2S3", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0657 {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
0658 {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
0659
0660 {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0661 {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0662 {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0663 {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0664 {"I2S3", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0665 {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
0666 {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
0667
0668
0669 {"I2S5_CH1", "DL1_CH1", "DL1"},
0670 {"I2S5_CH2", "DL1_CH2", "DL1"},
0671
0672 {"I2S5_CH1", "DL2_CH1", "DL2"},
0673 {"I2S5_CH2", "DL2_CH2", "DL2"},
0674
0675 {"I2S5_CH1", "DL3_CH1", "DL3"},
0676 {"I2S5_CH2", "DL3_CH2", "DL3"},
0677
0678 {"I2S5", NULL, "I2S5_CH1"},
0679 {"I2S5", NULL, "I2S5_CH2"},
0680
0681 {"I2S5", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
0682 {"I2S5", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
0683 {"I2S5", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
0684 {"I2S5", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
0685 {"I2S5", NULL, "I2S5_EN"},
0686
0687 {"I2S5", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0688 {"I2S5", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0689 {"I2S5", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0690 {"I2S5", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0691 {"I2S5", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
0692 {I2S5_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
0693 {I2S5_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
0694
0695 {"I2S5", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0696 {"I2S5", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0697 {"I2S5", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0698 {"I2S5", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0699 {"I2S5", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
0700 {I2S5_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
0701 {I2S5_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
0702 };
0703
0704
0705 static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
0706 struct snd_pcm_hw_params *params,
0707 int i2s_id)
0708 {
0709 struct mt8183_afe_private *afe_priv = afe->platform_priv;
0710 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
0711
0712 unsigned int rate = params_rate(params);
0713 unsigned int rate_reg = mt8183_rate_transform(afe->dev,
0714 rate, i2s_id);
0715 snd_pcm_format_t format = params_format(params);
0716 unsigned int i2s_con = 0, fmt_con = I2S_FMT_I2S << I2S_FMT_SFT;
0717 int ret = 0;
0718
0719 dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
0720 __func__,
0721 i2s_id,
0722 rate, format);
0723
0724 if (i2s_priv) {
0725 i2s_priv->rate = rate;
0726
0727 if (i2s_priv->use_eiaj)
0728 fmt_con = I2S_FMT_EIAJ << I2S_FMT_SFT;
0729 } else {
0730 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0731 }
0732
0733 switch (i2s_id) {
0734 case MT8183_DAI_I2S_0:
0735 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
0736 I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
0737 i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
0738 i2s_con |= fmt_con;
0739 i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
0740 regmap_update_bits(afe->regmap, AFE_I2S_CON,
0741 0xffffeffe, i2s_con);
0742 break;
0743 case MT8183_DAI_I2S_1:
0744 i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
0745 i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
0746 i2s_con |= fmt_con;
0747 i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
0748 regmap_update_bits(afe->regmap, AFE_I2S_CON1,
0749 0xffffeffe, i2s_con);
0750 break;
0751 case MT8183_DAI_I2S_2:
0752 i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
0753 i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
0754 i2s_con |= fmt_con;
0755 i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
0756 regmap_update_bits(afe->regmap, AFE_I2S_CON2,
0757 0xffffeffe, i2s_con);
0758 break;
0759 case MT8183_DAI_I2S_3:
0760 i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
0761 i2s_con |= fmt_con;
0762 i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
0763 regmap_update_bits(afe->regmap, AFE_I2S_CON3,
0764 0xffffeffe, i2s_con);
0765 break;
0766 case MT8183_DAI_I2S_5:
0767 i2s_con = rate_reg << I2S5_OUT_MODE_SFT;
0768 i2s_con |= fmt_con;
0769 i2s_con |= get_i2s_wlen(format) << I2S5_WLEN_SFT;
0770 regmap_update_bits(afe->regmap, AFE_I2S_CON4,
0771 0xffffeffe, i2s_con);
0772 break;
0773 default:
0774 dev_warn(afe->dev, "%s(), id %d not support\n",
0775 __func__, i2s_id);
0776 return -EINVAL;
0777 }
0778
0779
0780 if (i2s_priv && i2s_priv->share_i2s_id >= 0)
0781 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
0782
0783 return ret;
0784 }
0785
0786 static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
0787 struct snd_pcm_hw_params *params,
0788 struct snd_soc_dai *dai)
0789 {
0790 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0791
0792 return mtk_dai_i2s_config(afe, params, dai->id);
0793 }
0794
0795 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
0796 int clk_id, unsigned int freq, int dir)
0797 {
0798 struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
0799 struct mt8183_afe_private *afe_priv = afe->platform_priv;
0800 struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
0801 int apll;
0802 int apll_rate;
0803
0804 if (!i2s_priv) {
0805 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
0806 return -EINVAL;
0807 }
0808
0809 if (dir != SND_SOC_CLOCK_OUT) {
0810 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
0811 return -EINVAL;
0812 }
0813
0814 dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
0815
0816 apll = mt8183_get_apll_by_rate(afe, freq);
0817 apll_rate = mt8183_get_apll_rate(afe, apll);
0818
0819 if (freq > apll_rate) {
0820 dev_warn(afe->dev, "%s(), freq > apll rate", __func__);
0821 return -EINVAL;
0822 }
0823
0824 if (apll_rate % freq != 0) {
0825 dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz",
0826 __func__);
0827 return -EINVAL;
0828 }
0829
0830 i2s_priv->mclk_rate = freq;
0831 i2s_priv->mclk_apll = apll;
0832
0833 if (i2s_priv->share_i2s_id > 0) {
0834 struct mtk_afe_i2s_priv *share_i2s_priv;
0835
0836 share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
0837 if (!share_i2s_priv) {
0838 dev_warn(afe->dev, "%s(), share_i2s_priv == NULL",
0839 __func__);
0840 return -EINVAL;
0841 }
0842
0843 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
0844 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
0845 }
0846
0847 return 0;
0848 }
0849
0850 static int mtk_dai_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0851 {
0852 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0853 struct mt8183_afe_private *afe_priv = afe->platform_priv;
0854 struct mtk_afe_i2s_priv *i2s_priv;
0855
0856 switch (dai->id) {
0857 case MT8183_DAI_I2S_0:
0858 case MT8183_DAI_I2S_1:
0859 case MT8183_DAI_I2S_2:
0860 case MT8183_DAI_I2S_3:
0861 case MT8183_DAI_I2S_5:
0862 break;
0863 default:
0864 dev_warn(afe->dev, "%s(), id %d not support\n",
0865 __func__, dai->id);
0866 return -EINVAL;
0867 }
0868 i2s_priv = afe_priv->dai_priv[dai->id];
0869
0870 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0871 case SND_SOC_DAIFMT_LEFT_J:
0872 i2s_priv->use_eiaj = 1;
0873 break;
0874 case SND_SOC_DAIFMT_I2S:
0875 i2s_priv->use_eiaj = 0;
0876 break;
0877 default:
0878 dev_warn(afe->dev, "%s(), DAI format %d not support\n",
0879 __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
0880 return -EINVAL;
0881 }
0882
0883 return 0;
0884 }
0885
0886 static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
0887 .hw_params = mtk_dai_i2s_hw_params,
0888 .set_sysclk = mtk_dai_i2s_set_sysclk,
0889 .set_fmt = mtk_dai_i2s_set_fmt,
0890 };
0891
0892
0893 #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
0894 SNDRV_PCM_RATE_88200 |\
0895 SNDRV_PCM_RATE_96000 |\
0896 SNDRV_PCM_RATE_176400 |\
0897 SNDRV_PCM_RATE_192000)
0898
0899 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
0900 SNDRV_PCM_FMTBIT_S24_LE |\
0901 SNDRV_PCM_FMTBIT_S32_LE)
0902
0903 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
0904 {
0905 .name = "I2S0",
0906 .id = MT8183_DAI_I2S_0,
0907 .capture = {
0908 .stream_name = "I2S0",
0909 .channels_min = 1,
0910 .channels_max = 2,
0911 .rates = MTK_I2S_RATES,
0912 .formats = MTK_I2S_FORMATS,
0913 },
0914 .ops = &mtk_dai_i2s_ops,
0915 },
0916 {
0917 .name = "I2S1",
0918 .id = MT8183_DAI_I2S_1,
0919 .playback = {
0920 .stream_name = "I2S1",
0921 .channels_min = 1,
0922 .channels_max = 2,
0923 .rates = MTK_I2S_RATES,
0924 .formats = MTK_I2S_FORMATS,
0925 },
0926 .ops = &mtk_dai_i2s_ops,
0927 },
0928 {
0929 .name = "I2S2",
0930 .id = MT8183_DAI_I2S_2,
0931 .capture = {
0932 .stream_name = "I2S2",
0933 .channels_min = 1,
0934 .channels_max = 2,
0935 .rates = MTK_I2S_RATES,
0936 .formats = MTK_I2S_FORMATS,
0937 },
0938 .ops = &mtk_dai_i2s_ops,
0939 },
0940 {
0941 .name = "I2S3",
0942 .id = MT8183_DAI_I2S_3,
0943 .playback = {
0944 .stream_name = "I2S3",
0945 .channels_min = 1,
0946 .channels_max = 2,
0947 .rates = MTK_I2S_RATES,
0948 .formats = MTK_I2S_FORMATS,
0949 },
0950 .ops = &mtk_dai_i2s_ops,
0951 },
0952 {
0953 .name = "I2S5",
0954 .id = MT8183_DAI_I2S_5,
0955 .playback = {
0956 .stream_name = "I2S5",
0957 .channels_min = 1,
0958 .channels_max = 2,
0959 .rates = MTK_I2S_RATES,
0960 .formats = MTK_I2S_FORMATS,
0961 },
0962 .ops = &mtk_dai_i2s_ops,
0963 },
0964 };
0965
0966
0967 enum {
0968 DAI_I2S0 = 0,
0969 DAI_I2S1,
0970 DAI_I2S2,
0971 DAI_I2S3,
0972 DAI_I2S5,
0973 DAI_I2S_NUM,
0974 };
0975
0976 static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = {
0977 [DAI_I2S0] = {
0978 .id = MT8183_DAI_I2S_0,
0979 .mclk_id = MT8183_I2S0_MCK,
0980 .share_property_name = "i2s0-share",
0981 .share_i2s_id = -1,
0982 },
0983 [DAI_I2S1] = {
0984 .id = MT8183_DAI_I2S_1,
0985 .mclk_id = MT8183_I2S1_MCK,
0986 .share_property_name = "i2s1-share",
0987 .share_i2s_id = -1,
0988 },
0989 [DAI_I2S2] = {
0990 .id = MT8183_DAI_I2S_2,
0991 .mclk_id = MT8183_I2S2_MCK,
0992 .share_property_name = "i2s2-share",
0993 .share_i2s_id = -1,
0994 },
0995 [DAI_I2S3] = {
0996 .id = MT8183_DAI_I2S_3,
0997 .mclk_id = MT8183_I2S3_MCK,
0998 .share_property_name = "i2s3-share",
0999 .share_i2s_id = -1,
1000 },
1001 [DAI_I2S5] = {
1002 .id = MT8183_DAI_I2S_5,
1003 .mclk_id = MT8183_I2S5_MCK,
1004 .share_property_name = "i2s5-share",
1005 .share_i2s_id = -1,
1006 },
1007 };
1008
1009 static int mt8183_dai_i2s_get_share(struct mtk_base_afe *afe)
1010 {
1011 struct mt8183_afe_private *afe_priv = afe->platform_priv;
1012 const struct device_node *of_node = afe->dev->of_node;
1013 const char *of_str;
1014 const char *property_name;
1015 struct mtk_afe_i2s_priv *i2s_priv;
1016 int i;
1017
1018 for (i = 0; i < DAI_I2S_NUM; i++) {
1019 i2s_priv = afe_priv->dai_priv[mt8183_i2s_priv[i].id];
1020 property_name = mt8183_i2s_priv[i].share_property_name;
1021 if (of_property_read_string(of_node, property_name, &of_str))
1022 continue;
1023 i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str);
1024 }
1025
1026 return 0;
1027 }
1028
1029 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe)
1030 {
1031 struct mt8183_afe_private *afe_priv = afe->platform_priv;
1032 struct mtk_afe_i2s_priv *i2s_priv;
1033 int i;
1034
1035 for (i = 0; i < DAI_I2S_NUM; i++) {
1036 i2s_priv = devm_kzalloc(afe->dev,
1037 sizeof(struct mtk_afe_i2s_priv),
1038 GFP_KERNEL);
1039 if (!i2s_priv)
1040 return -ENOMEM;
1041
1042 memcpy(i2s_priv, &mt8183_i2s_priv[i],
1043 sizeof(struct mtk_afe_i2s_priv));
1044
1045 afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv;
1046 }
1047
1048 return 0;
1049 }
1050
1051 int mt8183_dai_i2s_register(struct mtk_base_afe *afe)
1052 {
1053 struct mtk_base_afe_dai *dai;
1054 int ret;
1055
1056 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1057 if (!dai)
1058 return -ENOMEM;
1059
1060 list_add(&dai->list, &afe->sub_dais);
1061
1062 dai->dai_drivers = mtk_dai_i2s_driver;
1063 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
1064
1065 dai->controls = mtk_dai_i2s_controls;
1066 dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
1067 dai->dapm_widgets = mtk_dai_i2s_widgets;
1068 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
1069 dai->dapm_routes = mtk_dai_i2s_routes;
1070 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
1071
1072
1073 ret = mt8183_dai_i2s_set_priv(afe);
1074 if (ret)
1075 return ret;
1076
1077
1078 ret = mt8183_dai_i2s_get_share(afe);
1079 if (ret)
1080 return ret;
1081
1082 return 0;
1083 }