root/sound/soc/mediatek/mt8183/mt8183-dai-i2s.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_i2s_wlen
  2. get_i2s_id_by_name
  3. get_i2s_priv_by_name
  4. mt8183_i2s_hd_get
  5. mt8183_i2s_hd_set
  6. mtk_apll_event
  7. mtk_mclk_en_event
  8. mtk_afe_i2s_share_connect
  9. mtk_afe_i2s_hd_connect
  10. mtk_afe_i2s_apll_connect
  11. mtk_afe_i2s_mclk_connect
  12. mtk_afe_mclk_apll_connect
  13. mtk_dai_i2s_config
  14. mtk_dai_i2s_hw_params
  15. mtk_dai_i2s_set_sysclk
  16. mt8183_dai_i2s_get_share
  17. mt8183_dai_i2s_set_priv
  18. mt8183_dai_i2s_register

   1 // SPDX-License-Identifier: GPL-2.0
   2 //
   3 // MediaTek ALSA SoC Audio DAI I2S Control
   4 //
   5 // Copyright (c) 2018 MediaTek Inc.
   6 // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
   7 
   8 #include <linux/bitops.h>
   9 #include <linux/regmap.h>
  10 #include <sound/pcm_params.h>
  11 #include "mt8183-afe-clk.h"
  12 #include "mt8183-afe-common.h"
  13 #include "mt8183-interconnection.h"
  14 #include "mt8183-reg.h"
  15 
  16 enum {
  17         I2S_FMT_EIAJ = 0,
  18         I2S_FMT_I2S = 1,
  19 };
  20 
  21 enum {
  22         I2S_WLEN_16_BIT = 0,
  23         I2S_WLEN_32_BIT = 1,
  24 };
  25 
  26 enum {
  27         I2S_HD_NORMAL = 0,
  28         I2S_HD_LOW_JITTER = 1,
  29 };
  30 
  31 enum {
  32         I2S1_SEL_O28_O29 = 0,
  33         I2S1_SEL_O03_O04 = 1,
  34 };
  35 
  36 enum {
  37         I2S_IN_PAD_CONNSYS = 0,
  38         I2S_IN_PAD_IO_MUX = 1,
  39 };
  40 
  41 struct mtk_afe_i2s_priv {
  42         int id;
  43         int rate; /* for determine which apll to use */
  44         int low_jitter_en;
  45 
  46         const char *share_property_name;
  47         int share_i2s_id;
  48 
  49         int mclk_id;
  50         int mclk_rate;
  51         int mclk_apll;
  52 };
  53 
  54 static unsigned int get_i2s_wlen(snd_pcm_format_t format)
  55 {
  56         return snd_pcm_format_physical_width(format) <= 16 ?
  57                I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
  58 }
  59 
  60 #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"
  65 
  66 #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"
  71 
  72 #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"
  77 
  78 static int get_i2s_id_by_name(struct mtk_base_afe *afe,
  79                               const char *name)
  80 {
  81         if (strncmp(name, "I2S0", 4) == 0)
  82                 return MT8183_DAI_I2S_0;
  83         else if (strncmp(name, "I2S1", 4) == 0)
  84                 return MT8183_DAI_I2S_1;
  85         else if (strncmp(name, "I2S2", 4) == 0)
  86                 return MT8183_DAI_I2S_2;
  87         else if (strncmp(name, "I2S3", 4) == 0)
  88                 return MT8183_DAI_I2S_3;
  89         else if (strncmp(name, "I2S5", 4) == 0)
  90                 return MT8183_DAI_I2S_5;
  91         else
  92                 return -EINVAL;
  93 }
  94 
  95 static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
  96                                                      const char *name)
  97 {
  98         struct mt8183_afe_private *afe_priv = afe->platform_priv;
  99         int dai_id = get_i2s_id_by_name(afe, name);
 100 
 101         if (dai_id < 0)
 102                 return NULL;
 103 
 104         return afe_priv->dai_priv[dai_id];
 105 }
 106 
 107 /* low jitter control */
 108 static const char * const mt8183_i2s_hd_str[] = {
 109         "Normal", "Low_Jitter"
 110 };
 111 
 112 static const struct soc_enum mt8183_i2s_enum[] = {
 113         SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_i2s_hd_str),
 114                             mt8183_i2s_hd_str),
 115 };
 116 
 117 static int mt8183_i2s_hd_get(struct snd_kcontrol *kcontrol,
 118                              struct snd_ctl_elem_value *ucontrol)
 119 {
 120         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
 121         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 122         struct mtk_afe_i2s_priv *i2s_priv;
 123 
 124         i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 125 
 126         if (!i2s_priv) {
 127                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 128                 return -EINVAL;
 129         }
 130 
 131         ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
 132 
 133         return 0;
 134 }
 135 
 136 static int mt8183_i2s_hd_set(struct snd_kcontrol *kcontrol,
 137                              struct snd_ctl_elem_value *ucontrol)
 138 {
 139         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
 140         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 141         struct mtk_afe_i2s_priv *i2s_priv;
 142         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 143         int hd_en;
 144 
 145         if (ucontrol->value.enumerated.item[0] >= e->items)
 146                 return -EINVAL;
 147 
 148         hd_en = ucontrol->value.integer.value[0];
 149 
 150         dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
 151                  __func__, kcontrol->id.name, hd_en);
 152 
 153         i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 154 
 155         if (!i2s_priv) {
 156                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 157                 return -EINVAL;
 158         }
 159 
 160         i2s_priv->low_jitter_en = hd_en;
 161 
 162         return 0;
 163 }
 164 
 165 static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
 166         SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8183_i2s_enum[0],
 167                      mt8183_i2s_hd_get, mt8183_i2s_hd_set),
 168         SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8183_i2s_enum[0],
 169                      mt8183_i2s_hd_get, mt8183_i2s_hd_set),
 170         SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8183_i2s_enum[0],
 171                      mt8183_i2s_hd_get, mt8183_i2s_hd_set),
 172         SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8183_i2s_enum[0],
 173                      mt8183_i2s_hd_get, mt8183_i2s_hd_set),
 174         SOC_ENUM_EXT(MTK_AFE_I2S5_KCONTROL_NAME, mt8183_i2s_enum[0],
 175                      mt8183_i2s_hd_get, mt8183_i2s_hd_set),
 176 };
 177 
 178 /* dai component */
 179 /* interconnection */
 180 static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
 181         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN0, I_DL1_CH1, 1, 0),
 182         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN0, I_DL2_CH1, 1, 0),
 183         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN0, I_DL3_CH1, 1, 0),
 184         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN0,
 185                                     I_ADDA_UL_CH1, 1, 0),
 186         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN0,
 187                                     I_PCM_1_CAP_CH1, 1, 0),
 188         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN0,
 189                                     I_PCM_2_CAP_CH1, 1, 0),
 190 };
 191 
 192 static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
 193         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN1, I_DL1_CH2, 1, 0),
 194         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN1, I_DL2_CH2, 1, 0),
 195         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN1, I_DL3_CH2, 1, 0),
 196         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN1,
 197                                     I_ADDA_UL_CH2, 1, 0),
 198         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN1,
 199                                     I_PCM_1_CAP_CH1, 1, 0),
 200         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN1,
 201                                     I_PCM_2_CAP_CH1, 1, 0),
 202         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN1,
 203                                     I_PCM_1_CAP_CH2, 1, 0),
 204         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN1,
 205                                     I_PCM_2_CAP_CH2, 1, 0),
 206 };
 207 
 208 static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
 209         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN28, I_DL1_CH1, 1, 0),
 210         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN28, I_DL2_CH1, 1, 0),
 211         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN28, I_DL3_CH1, 1, 0),
 212         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN28,
 213                                     I_ADDA_UL_CH1, 1, 0),
 214         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN28,
 215                                     I_PCM_1_CAP_CH1, 1, 0),
 216         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN28,
 217                                     I_PCM_2_CAP_CH1, 1, 0),
 218 };
 219 
 220 static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
 221         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN29, I_DL1_CH2, 1, 0),
 222         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN29, I_DL2_CH2, 1, 0),
 223         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN29, I_DL3_CH2, 1, 0),
 224         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN29,
 225                                     I_ADDA_UL_CH2, 1, 0),
 226         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN29,
 227                                     I_PCM_1_CAP_CH1, 1, 0),
 228         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN29,
 229                                     I_PCM_2_CAP_CH1, 1, 0),
 230         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN29,
 231                                     I_PCM_1_CAP_CH2, 1, 0),
 232         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN29,
 233                                     I_PCM_2_CAP_CH2, 1, 0),
 234 };
 235 
 236 static const struct snd_kcontrol_new mtk_i2s5_ch1_mix[] = {
 237         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN30, I_DL1_CH1, 1, 0),
 238         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN30, I_DL2_CH1, 1, 0),
 239         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN30, I_DL3_CH1, 1, 0),
 240         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN30,
 241                                     I_ADDA_UL_CH1, 1, 0),
 242         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN30,
 243                                     I_PCM_1_CAP_CH1, 1, 0),
 244         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN30,
 245                                     I_PCM_2_CAP_CH1, 1, 0),
 246 };
 247 
 248 static const struct snd_kcontrol_new mtk_i2s5_ch2_mix[] = {
 249         SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN31, I_DL1_CH2, 1, 0),
 250         SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN31, I_DL2_CH2, 1, 0),
 251         SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN31, I_DL3_CH2, 1, 0),
 252         SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN31,
 253                                     I_ADDA_UL_CH2, 1, 0),
 254         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN31,
 255                                     I_PCM_1_CAP_CH1, 1, 0),
 256         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN31,
 257                                     I_PCM_2_CAP_CH1, 1, 0),
 258         SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN31,
 259                                     I_PCM_1_CAP_CH2, 1, 0),
 260         SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN31,
 261                                     I_PCM_2_CAP_CH2, 1, 0),
 262 };
 263 
 264 enum {
 265         SUPPLY_SEQ_APLL,
 266         SUPPLY_SEQ_I2S_MCLK_EN,
 267         SUPPLY_SEQ_I2S_HD_EN,
 268         SUPPLY_SEQ_I2S_EN,
 269 };
 270 
 271 static int mtk_apll_event(struct snd_soc_dapm_widget *w,
 272                           struct snd_kcontrol *kcontrol,
 273                           int event)
 274 {
 275         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 276         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 277 
 278         dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 279                  __func__, w->name, event);
 280 
 281         switch (event) {
 282         case SND_SOC_DAPM_PRE_PMU:
 283                 if (strcmp(w->name, APLL1_W_NAME) == 0)
 284                         mt8183_apll1_enable(afe);
 285                 else
 286                         mt8183_apll2_enable(afe);
 287                 break;
 288         case SND_SOC_DAPM_POST_PMD:
 289                 if (strcmp(w->name, APLL1_W_NAME) == 0)
 290                         mt8183_apll1_disable(afe);
 291                 else
 292                         mt8183_apll2_disable(afe);
 293                 break;
 294         default:
 295                 break;
 296         }
 297 
 298         return 0;
 299 }
 300 
 301 static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
 302                              struct snd_kcontrol *kcontrol,
 303                              int event)
 304 {
 305         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 306         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 307         struct mtk_afe_i2s_priv *i2s_priv;
 308 
 309         dev_info(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 310                  __func__, w->name, event);
 311 
 312         i2s_priv = get_i2s_priv_by_name(afe, w->name);
 313 
 314         if (!i2s_priv) {
 315                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 316                 return -EINVAL;
 317         }
 318 
 319         switch (event) {
 320         case SND_SOC_DAPM_PRE_PMU:
 321                 mt8183_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
 322                 break;
 323         case SND_SOC_DAPM_POST_PMD:
 324                 i2s_priv->mclk_rate = 0;
 325                 mt8183_mck_disable(afe, i2s_priv->mclk_id);
 326                 break;
 327         default:
 328                 break;
 329         }
 330 
 331         return 0;
 332 }
 333 
 334 static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
 335         SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
 336                            mtk_i2s1_ch1_mix,
 337                            ARRAY_SIZE(mtk_i2s1_ch1_mix)),
 338         SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
 339                            mtk_i2s1_ch2_mix,
 340                            ARRAY_SIZE(mtk_i2s1_ch2_mix)),
 341 
 342         SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
 343                            mtk_i2s3_ch1_mix,
 344                            ARRAY_SIZE(mtk_i2s3_ch1_mix)),
 345         SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
 346                            mtk_i2s3_ch2_mix,
 347                            ARRAY_SIZE(mtk_i2s3_ch2_mix)),
 348 
 349         SND_SOC_DAPM_MIXER("I2S5_CH1", SND_SOC_NOPM, 0, 0,
 350                            mtk_i2s5_ch1_mix,
 351                            ARRAY_SIZE(mtk_i2s5_ch1_mix)),
 352         SND_SOC_DAPM_MIXER("I2S5_CH2", SND_SOC_NOPM, 0, 0,
 353                            mtk_i2s5_ch2_mix,
 354                            ARRAY_SIZE(mtk_i2s5_ch2_mix)),
 355 
 356         /* i2s en*/
 357         SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
 358                               AFE_I2S_CON, I2S_EN_SFT, 0,
 359                               NULL, 0),
 360         SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
 361                               AFE_I2S_CON1, I2S_EN_SFT, 0,
 362                               NULL, 0),
 363         SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
 364                               AFE_I2S_CON2, I2S_EN_SFT, 0,
 365                               NULL, 0),
 366         SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
 367                               AFE_I2S_CON3, I2S_EN_SFT, 0,
 368                               NULL, 0),
 369         SND_SOC_DAPM_SUPPLY_S("I2S5_EN", SUPPLY_SEQ_I2S_EN,
 370                               AFE_I2S_CON4, I2S5_EN_SFT, 0,
 371                               NULL, 0),
 372         /* i2s hd en */
 373         SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 374                               AFE_I2S_CON, I2S1_HD_EN_SFT, 0,
 375                               NULL, 0),
 376         SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 377                               AFE_I2S_CON1, I2S2_HD_EN_SFT, 0,
 378                               NULL, 0),
 379         SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 380                               AFE_I2S_CON2, I2S3_HD_EN_SFT, 0,
 381                               NULL, 0),
 382         SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 383                               AFE_I2S_CON3, I2S4_HD_EN_SFT, 0,
 384                               NULL, 0),
 385         SND_SOC_DAPM_SUPPLY_S(I2S5_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 386                               AFE_I2S_CON4, I2S5_HD_EN_SFT, 0,
 387                               NULL, 0),
 388 
 389         /* i2s mclk en */
 390         SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 391                               SND_SOC_NOPM, 0, 0,
 392                               mtk_mclk_en_event,
 393                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 394         SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 395                               SND_SOC_NOPM, 0, 0,
 396                               mtk_mclk_en_event,
 397                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 398         SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 399                               SND_SOC_NOPM, 0, 0,
 400                               mtk_mclk_en_event,
 401                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 402         SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 403                               SND_SOC_NOPM, 0, 0,
 404                               mtk_mclk_en_event,
 405                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 406         SND_SOC_DAPM_SUPPLY_S(I2S5_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 407                               SND_SOC_NOPM, 0, 0,
 408                               mtk_mclk_en_event,
 409                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 410 
 411         /* apll */
 412         SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
 413                               SND_SOC_NOPM, 0, 0,
 414                               mtk_apll_event,
 415                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 416         SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
 417                               SND_SOC_NOPM, 0, 0,
 418                               mtk_apll_event,
 419                               SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 420 };
 421 
 422 static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
 423                                      struct snd_soc_dapm_widget *sink)
 424 {
 425         struct snd_soc_dapm_widget *w = sink;
 426         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 427         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 428         struct mtk_afe_i2s_priv *i2s_priv;
 429 
 430         i2s_priv = get_i2s_priv_by_name(afe, sink->name);
 431 
 432         if (!i2s_priv) {
 433                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 434                 return 0;
 435         }
 436 
 437         if (i2s_priv->share_i2s_id < 0)
 438                 return 0;
 439 
 440         return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
 441 }
 442 
 443 static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
 444                                   struct snd_soc_dapm_widget *sink)
 445 {
 446         struct snd_soc_dapm_widget *w = sink;
 447         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 448         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 449         struct mtk_afe_i2s_priv *i2s_priv;
 450 
 451         i2s_priv = get_i2s_priv_by_name(afe, sink->name);
 452 
 453         if (!i2s_priv) {
 454                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 455                 return 0;
 456         }
 457 
 458         if (get_i2s_id_by_name(afe, sink->name) ==
 459             get_i2s_id_by_name(afe, source->name))
 460                 return i2s_priv->low_jitter_en;
 461 
 462         /* check if share i2s need hd en */
 463         if (i2s_priv->share_i2s_id < 0)
 464                 return 0;
 465 
 466         if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
 467                 return i2s_priv->low_jitter_en;
 468 
 469         return 0;
 470 }
 471 
 472 static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
 473                                     struct snd_soc_dapm_widget *sink)
 474 {
 475         struct snd_soc_dapm_widget *w = sink;
 476         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 477         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 478         struct mtk_afe_i2s_priv *i2s_priv;
 479         int cur_apll;
 480         int i2s_need_apll;
 481 
 482         i2s_priv = get_i2s_priv_by_name(afe, w->name);
 483 
 484         if (!i2s_priv) {
 485                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 486                 return 0;
 487         }
 488 
 489         /* which apll */
 490         cur_apll = mt8183_get_apll_by_name(afe, source->name);
 491 
 492         /* choose APLL from i2s rate */
 493         i2s_need_apll = mt8183_get_apll_by_rate(afe, i2s_priv->rate);
 494 
 495         return (i2s_need_apll == cur_apll) ? 1 : 0;
 496 }
 497 
 498 static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
 499                                     struct snd_soc_dapm_widget *sink)
 500 {
 501         struct snd_soc_dapm_widget *w = sink;
 502         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 503         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 504         struct mtk_afe_i2s_priv *i2s_priv;
 505 
 506         i2s_priv = get_i2s_priv_by_name(afe, sink->name);
 507 
 508         if (!i2s_priv) {
 509                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 510                 return 0;
 511         }
 512 
 513         if (get_i2s_id_by_name(afe, sink->name) ==
 514             get_i2s_id_by_name(afe, source->name))
 515                 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
 516 
 517         /* check if share i2s need mclk */
 518         if (i2s_priv->share_i2s_id < 0)
 519                 return 0;
 520 
 521         if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
 522                 return (i2s_priv->mclk_rate > 0) ? 1 : 0;
 523 
 524         return 0;
 525 }
 526 
 527 static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
 528                                      struct snd_soc_dapm_widget *sink)
 529 {
 530         struct snd_soc_dapm_widget *w = sink;
 531         struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 532         struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 533         struct mtk_afe_i2s_priv *i2s_priv;
 534         int cur_apll;
 535 
 536         i2s_priv = get_i2s_priv_by_name(afe, w->name);
 537 
 538         if (!i2s_priv) {
 539                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 540                 return 0;
 541         }
 542 
 543         /* which apll */
 544         cur_apll = mt8183_get_apll_by_name(afe, source->name);
 545 
 546         return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
 547 }
 548 
 549 static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
 550         /* i2s0 */
 551         {"I2S0", NULL, "I2S0_EN"},
 552         {"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 553         {"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 554         {"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 555         {"I2S0", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
 556 
 557         {"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 558         {"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 559         {"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 560         {"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 561         {"I2S0", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 562         {I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 563         {I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 564 
 565         {"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 566         {"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 567         {"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 568         {"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 569         {"I2S0", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 570         {I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 571         {I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 572 
 573         /* i2s1 */
 574         {"I2S1_CH1", "DL1_CH1", "DL1"},
 575         {"I2S1_CH2", "DL1_CH2", "DL1"},
 576 
 577         {"I2S1_CH1", "DL2_CH1", "DL2"},
 578         {"I2S1_CH2", "DL2_CH2", "DL2"},
 579 
 580         {"I2S1_CH1", "DL3_CH1", "DL3"},
 581         {"I2S1_CH2", "DL3_CH2", "DL3"},
 582 
 583         {"I2S1", NULL, "I2S1_CH1"},
 584         {"I2S1", NULL, "I2S1_CH2"},
 585 
 586         {"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 587         {"I2S1", NULL, "I2S1_EN"},
 588         {"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 589         {"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 590         {"I2S1", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
 591 
 592         {"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 593         {"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 594         {"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 595         {"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 596         {"I2S1", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 597         {I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 598         {I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 599 
 600         {"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 601         {"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 602         {"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 603         {"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 604         {"I2S1", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 605         {I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 606         {I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 607 
 608         /* i2s2 */
 609         {"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 610         {"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 611         {"I2S2", NULL, "I2S2_EN"},
 612         {"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 613         {"I2S2", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
 614 
 615         {"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 616         {"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 617         {"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 618         {"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 619         {"I2S2", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 620         {I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 621         {I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 622 
 623         {"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 624         {"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 625         {"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 626         {"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 627         {"I2S2", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 628         {I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 629         {I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 630 
 631         /* i2s3 */
 632         {"I2S3_CH1", "DL1_CH1", "DL1"},
 633         {"I2S3_CH2", "DL1_CH2", "DL1"},
 634 
 635         {"I2S3_CH1", "DL2_CH1", "DL2"},
 636         {"I2S3_CH2", "DL2_CH2", "DL2"},
 637 
 638         {"I2S3_CH1", "DL3_CH1", "DL3"},
 639         {"I2S3_CH2", "DL3_CH2", "DL3"},
 640 
 641         {"I2S3", NULL, "I2S3_CH1"},
 642         {"I2S3", NULL, "I2S3_CH2"},
 643 
 644         {"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 645         {"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 646         {"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 647         {"I2S3", NULL, "I2S3_EN"},
 648         {"I2S3", NULL, "I2S5_EN", mtk_afe_i2s_share_connect},
 649 
 650         {"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 651         {"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 652         {"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 653         {"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 654         {"I2S3", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 655         {I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 656         {I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 657 
 658         {"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 659         {"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 660         {"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 661         {"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 662         {"I2S3", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 663         {I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 664         {I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 665 
 666         /* i2s5 */
 667         {"I2S5_CH1", "DL1_CH1", "DL1"},
 668         {"I2S5_CH2", "DL1_CH2", "DL1"},
 669 
 670         {"I2S5_CH1", "DL2_CH1", "DL2"},
 671         {"I2S5_CH2", "DL2_CH2", "DL2"},
 672 
 673         {"I2S5_CH1", "DL3_CH1", "DL3"},
 674         {"I2S5_CH2", "DL3_CH2", "DL3"},
 675 
 676         {"I2S5", NULL, "I2S5_CH1"},
 677         {"I2S5", NULL, "I2S5_CH2"},
 678 
 679         {"I2S5", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 680         {"I2S5", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 681         {"I2S5", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 682         {"I2S5", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 683         {"I2S5", NULL, "I2S5_EN"},
 684 
 685         {"I2S5", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 686         {"I2S5", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 687         {"I2S5", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 688         {"I2S5", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 689         {"I2S5", NULL, I2S5_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 690         {I2S5_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 691         {I2S5_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 692 
 693         {"I2S5", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 694         {"I2S5", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 695         {"I2S5", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 696         {"I2S5", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 697         {"I2S5", NULL, I2S5_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 698         {I2S5_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 699         {I2S5_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 700 };
 701 
 702 /* dai ops */
 703 static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
 704                               struct snd_pcm_hw_params *params,
 705                               int i2s_id)
 706 {
 707         struct mt8183_afe_private *afe_priv = afe->platform_priv;
 708         struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
 709 
 710         unsigned int rate = params_rate(params);
 711         unsigned int rate_reg = mt8183_rate_transform(afe->dev,
 712                                                       rate, i2s_id);
 713         snd_pcm_format_t format = params_format(params);
 714         unsigned int i2s_con = 0;
 715         int ret = 0;
 716 
 717         dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
 718                  __func__,
 719                  i2s_id,
 720                  rate, format);
 721 
 722         if (i2s_priv)
 723                 i2s_priv->rate = rate;
 724         else
 725                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 726 
 727         switch (i2s_id) {
 728         case MT8183_DAI_I2S_0:
 729                 regmap_update_bits(afe->regmap, AFE_DAC_CON1,
 730                                    I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
 731                 i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
 732                 i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
 733                 i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
 734                 regmap_update_bits(afe->regmap, AFE_I2S_CON,
 735                                    0xffffeffe, i2s_con);
 736                 break;
 737         case MT8183_DAI_I2S_1:
 738                 i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
 739                 i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
 740                 i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
 741                 i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
 742                 regmap_update_bits(afe->regmap, AFE_I2S_CON1,
 743                                    0xffffeffe, i2s_con);
 744                 break;
 745         case MT8183_DAI_I2S_2:
 746                 i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
 747                 i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
 748                 i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
 749                 i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
 750                 regmap_update_bits(afe->regmap, AFE_I2S_CON2,
 751                                    0xffffeffe, i2s_con);
 752                 break;
 753         case MT8183_DAI_I2S_3:
 754                 i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
 755                 i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
 756                 i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
 757                 regmap_update_bits(afe->regmap, AFE_I2S_CON3,
 758                                    0xffffeffe, i2s_con);
 759                 break;
 760         case MT8183_DAI_I2S_5:
 761                 i2s_con = rate_reg << I2S5_OUT_MODE_SFT;
 762                 i2s_con |= I2S_FMT_I2S << I2S5_FMT_SFT;
 763                 i2s_con |= get_i2s_wlen(format) << I2S5_WLEN_SFT;
 764                 regmap_update_bits(afe->regmap, AFE_I2S_CON4,
 765                                    0xffffeffe, i2s_con);
 766                 break;
 767         default:
 768                 dev_warn(afe->dev, "%s(), id %d not support\n",
 769                          __func__, i2s_id);
 770                 return -EINVAL;
 771         }
 772 
 773         /* set share i2s */
 774         if (i2s_priv && i2s_priv->share_i2s_id >= 0)
 775                 ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
 776 
 777         return ret;
 778 }
 779 
 780 static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
 781                                  struct snd_pcm_hw_params *params,
 782                                  struct snd_soc_dai *dai)
 783 {
 784         struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 785 
 786         return mtk_dai_i2s_config(afe, params, dai->id);
 787 }
 788 
 789 static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
 790                                   int clk_id, unsigned int freq, int dir)
 791 {
 792         struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
 793         struct mt8183_afe_private *afe_priv = afe->platform_priv;
 794         struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
 795         int apll;
 796         int apll_rate;
 797 
 798         if (!i2s_priv) {
 799                 dev_warn(afe->dev, "%s(), i2s_priv == NULL", __func__);
 800                 return -EINVAL;
 801         }
 802 
 803         if (dir != SND_SOC_CLOCK_OUT) {
 804                 dev_warn(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
 805                 return -EINVAL;
 806         }
 807 
 808         dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
 809 
 810         apll = mt8183_get_apll_by_rate(afe, freq);
 811         apll_rate = mt8183_get_apll_rate(afe, apll);
 812 
 813         if (freq > apll_rate) {
 814                 dev_warn(afe->dev, "%s(), freq > apll rate", __func__);
 815                 return -EINVAL;
 816         }
 817 
 818         if (apll_rate % freq != 0) {
 819                 dev_warn(afe->dev, "%s(), APLL cannot generate freq Hz",
 820                          __func__);
 821                 return -EINVAL;
 822         }
 823 
 824         i2s_priv->mclk_rate = freq;
 825         i2s_priv->mclk_apll = apll;
 826 
 827         if (i2s_priv->share_i2s_id > 0) {
 828                 struct mtk_afe_i2s_priv *share_i2s_priv;
 829 
 830                 share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
 831                 if (!share_i2s_priv) {
 832                         dev_warn(afe->dev, "%s(), share_i2s_priv == NULL",
 833                                  __func__);
 834                         return -EINVAL;
 835                 }
 836 
 837                 share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
 838                 share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
 839         }
 840 
 841         return 0;
 842 }
 843 
 844 static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
 845         .hw_params = mtk_dai_i2s_hw_params,
 846         .set_sysclk = mtk_dai_i2s_set_sysclk,
 847 };
 848 
 849 /* dai driver */
 850 #define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
 851                        SNDRV_PCM_RATE_88200 |\
 852                        SNDRV_PCM_RATE_96000 |\
 853                        SNDRV_PCM_RATE_176400 |\
 854                        SNDRV_PCM_RATE_192000)
 855 
 856 #define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
 857                          SNDRV_PCM_FMTBIT_S24_LE |\
 858                          SNDRV_PCM_FMTBIT_S32_LE)
 859 
 860 static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
 861         {
 862                 .name = "I2S0",
 863                 .id = MT8183_DAI_I2S_0,
 864                 .capture = {
 865                         .stream_name = "I2S0",
 866                         .channels_min = 1,
 867                         .channels_max = 2,
 868                         .rates = MTK_I2S_RATES,
 869                         .formats = MTK_I2S_FORMATS,
 870                 },
 871                 .ops = &mtk_dai_i2s_ops,
 872         },
 873         {
 874                 .name = "I2S1",
 875                 .id = MT8183_DAI_I2S_1,
 876                 .playback = {
 877                         .stream_name = "I2S1",
 878                         .channels_min = 1,
 879                         .channels_max = 2,
 880                         .rates = MTK_I2S_RATES,
 881                         .formats = MTK_I2S_FORMATS,
 882                 },
 883                 .ops = &mtk_dai_i2s_ops,
 884         },
 885         {
 886                 .name = "I2S2",
 887                 .id = MT8183_DAI_I2S_2,
 888                 .capture = {
 889                         .stream_name = "I2S2",
 890                         .channels_min = 1,
 891                         .channels_max = 2,
 892                         .rates = MTK_I2S_RATES,
 893                         .formats = MTK_I2S_FORMATS,
 894                 },
 895                 .ops = &mtk_dai_i2s_ops,
 896         },
 897         {
 898                 .name = "I2S3",
 899                 .id = MT8183_DAI_I2S_3,
 900                 .playback = {
 901                         .stream_name = "I2S3",
 902                         .channels_min = 1,
 903                         .channels_max = 2,
 904                         .rates = MTK_I2S_RATES,
 905                         .formats = MTK_I2S_FORMATS,
 906                 },
 907                 .ops = &mtk_dai_i2s_ops,
 908         },
 909         {
 910                 .name = "I2S5",
 911                 .id = MT8183_DAI_I2S_5,
 912                 .playback = {
 913                         .stream_name = "I2S5",
 914                         .channels_min = 1,
 915                         .channels_max = 2,
 916                         .rates = MTK_I2S_RATES,
 917                         .formats = MTK_I2S_FORMATS,
 918                 },
 919                 .ops = &mtk_dai_i2s_ops,
 920         },
 921 };
 922 
 923 /* this enum is merely for mtk_afe_i2s_priv declare */
 924 enum {
 925         DAI_I2S0 = 0,
 926         DAI_I2S1,
 927         DAI_I2S2,
 928         DAI_I2S3,
 929         DAI_I2S5,
 930         DAI_I2S_NUM,
 931 };
 932 
 933 static const struct mtk_afe_i2s_priv mt8183_i2s_priv[DAI_I2S_NUM] = {
 934         [DAI_I2S0] = {
 935                 .id = MT8183_DAI_I2S_0,
 936                 .mclk_id = MT8183_I2S0_MCK,
 937                 .share_property_name = "i2s0-share",
 938                 .share_i2s_id = -1,
 939         },
 940         [DAI_I2S1] = {
 941                 .id = MT8183_DAI_I2S_1,
 942                 .mclk_id = MT8183_I2S1_MCK,
 943                 .share_property_name = "i2s1-share",
 944                 .share_i2s_id = -1,
 945         },
 946         [DAI_I2S2] = {
 947                 .id = MT8183_DAI_I2S_2,
 948                 .mclk_id = MT8183_I2S2_MCK,
 949                 .share_property_name = "i2s2-share",
 950                 .share_i2s_id = -1,
 951         },
 952         [DAI_I2S3] = {
 953                 .id = MT8183_DAI_I2S_3,
 954                 .mclk_id = MT8183_I2S3_MCK,
 955                 .share_property_name = "i2s3-share",
 956                 .share_i2s_id = -1,
 957         },
 958         [DAI_I2S5] = {
 959                 .id = MT8183_DAI_I2S_5,
 960                 .mclk_id = MT8183_I2S5_MCK,
 961                 .share_property_name = "i2s5-share",
 962                 .share_i2s_id = -1,
 963         },
 964 };
 965 
 966 static int mt8183_dai_i2s_get_share(struct mtk_base_afe *afe)
 967 {
 968         struct mt8183_afe_private *afe_priv = afe->platform_priv;
 969         const struct device_node *of_node = afe->dev->of_node;
 970         const char *of_str;
 971         const char *property_name;
 972         struct mtk_afe_i2s_priv *i2s_priv;
 973         int i;
 974 
 975         for (i = 0; i < DAI_I2S_NUM; i++) {
 976                 i2s_priv = afe_priv->dai_priv[mt8183_i2s_priv[i].id];
 977                 property_name = mt8183_i2s_priv[i].share_property_name;
 978                 if (of_property_read_string(of_node, property_name, &of_str))
 979                         continue;
 980                 i2s_priv->share_i2s_id = get_i2s_id_by_name(afe, of_str);
 981         }
 982 
 983         return 0;
 984 }
 985 
 986 static int mt8183_dai_i2s_set_priv(struct mtk_base_afe *afe)
 987 {
 988         struct mt8183_afe_private *afe_priv = afe->platform_priv;
 989         struct mtk_afe_i2s_priv *i2s_priv;
 990         int i;
 991 
 992         for (i = 0; i < DAI_I2S_NUM; i++) {
 993                 i2s_priv = devm_kzalloc(afe->dev,
 994                                         sizeof(struct mtk_afe_i2s_priv),
 995                                         GFP_KERNEL);
 996                 if (!i2s_priv)
 997                         return -ENOMEM;
 998 
 999                 memcpy(i2s_priv, &mt8183_i2s_priv[i],
1000                        sizeof(struct mtk_afe_i2s_priv));
1001 
1002                 afe_priv->dai_priv[mt8183_i2s_priv[i].id] = i2s_priv;
1003         }
1004 
1005         return 0;
1006 }
1007 
1008 int mt8183_dai_i2s_register(struct mtk_base_afe *afe)
1009 {
1010         struct mtk_base_afe_dai *dai;
1011         int ret;
1012 
1013         dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1014         if (!dai)
1015                 return -ENOMEM;
1016 
1017         list_add(&dai->list, &afe->sub_dais);
1018 
1019         dai->dai_drivers = mtk_dai_i2s_driver;
1020         dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
1021 
1022         dai->controls = mtk_dai_i2s_controls;
1023         dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
1024         dai->dapm_widgets = mtk_dai_i2s_widgets;
1025         dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
1026         dai->dapm_routes = mtk_dai_i2s_routes;
1027         dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
1028 
1029         /* set all dai i2s private data */
1030         ret = mt8183_dai_i2s_set_priv(afe);
1031         if (ret)
1032                 return ret;
1033 
1034         /* parse share i2s */
1035         ret = mt8183_dai_i2s_get_share(afe);
1036         if (ret)
1037                 return ret;
1038 
1039         return 0;
1040 }

/* [<][>][^][v][top][bottom][index][help] */