Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 //  MediaTek ALSA SoC Audio DAI SRC Control
0004 //
0005 // Copyright (c) 2022 MediaTek Inc.
0006 // Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
0007 
0008 #include <linux/regmap.h>
0009 #include "mt8186-afe-common.h"
0010 #include "mt8186-interconnection.h"
0011 
0012 struct mtk_afe_src_priv {
0013     int dl_rate;
0014     int ul_rate;
0015 };
0016 
0017 static const unsigned int src_iir_coeff_32_to_16[] = {
0018     0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002,
0019     0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002,
0020     0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002,
0021     0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002,
0022     0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002,
0023     0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002,
0024     0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002,
0025     0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x000001
0026 };
0027 
0028 static const unsigned int src_iir_coeff_44_to_16[] = {
0029     0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002,
0030     0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002,
0031     0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002,
0032     0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002,
0033     0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002,
0034     0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002,
0035     0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x000001
0036 };
0037 
0038 static const unsigned int src_iir_coeff_44_to_32[] = {
0039     0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003,
0040     0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002,
0041     0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002,
0042     0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002,
0043     0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002,
0044     0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002,
0045     0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x000001
0046 };
0047 
0048 static const unsigned int src_iir_coeff_48_to_16[] = {
0049     0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002,
0050     0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002,
0051     0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002,
0052     0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002,
0053     0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002,
0054     0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002,
0055     0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001,
0056     0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x000004
0057 };
0058 
0059 static const unsigned int src_iir_coeff_48_to_32[] = {
0060     0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002,
0061     0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002,
0062     0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002,
0063     0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002,
0064     0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002,
0065     0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002,
0066     0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x000001
0067 };
0068 
0069 static const unsigned int src_iir_coeff_48_to_44[] = {
0070     0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003,
0071     0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003,
0072     0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003,
0073     0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003,
0074     0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x000001
0075 };
0076 
0077 static const unsigned int src_iir_coeff_96_to_16[] = {
0078     0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002,
0079     0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003,
0080     0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003,
0081     0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003,
0082     0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002,
0083     0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002,
0084     0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002,
0085     0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001,
0086 };
0087 
0088 static const unsigned int src_iir_coeff_96_to_44[] = {
0089     0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002,
0090     0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002,
0091     0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002,
0092     0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002,
0093     0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002,
0094     0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002,
0095     0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001,
0096     0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001,
0097 };
0098 
0099 static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate)
0100 {
0101     switch (rate) {
0102     case 8000:
0103         return 0x50000;
0104     case 11025:
0105         return 0x6e400;
0106     case 12000:
0107         return 0x78000;
0108     case 16000:
0109         return 0xa0000;
0110     case 22050:
0111         return 0xdc800;
0112     case 24000:
0113         return 0xf0000;
0114     case 32000:
0115         return 0x140000;
0116     case 44100:
0117         return 0x1b9000;
0118     case 48000:
0119         return 0x1e0000;
0120     case 88200:
0121         return 0x372000;
0122     case 96000:
0123         return 0x3c0000;
0124     case 176400:
0125         return 0x6e4000;
0126     case 192000:
0127         return 0x780000;
0128     default:
0129         dev_err(afe->dev, "%s(), rate %d invalid!!!\n",
0130             __func__, rate);
0131         return 0;
0132     }
0133 }
0134 
0135 static const unsigned int *get_iir_coeff(unsigned int rate_in,
0136                      unsigned int rate_out,
0137                      unsigned int *param_num)
0138 {
0139     if (rate_in == 32000 && rate_out == 16000) {
0140         *param_num = ARRAY_SIZE(src_iir_coeff_32_to_16);
0141         return src_iir_coeff_32_to_16;
0142     } else if (rate_in == 44100 && rate_out == 16000) {
0143         *param_num = ARRAY_SIZE(src_iir_coeff_44_to_16);
0144         return src_iir_coeff_44_to_16;
0145     } else if (rate_in == 44100 && rate_out == 32000) {
0146         *param_num = ARRAY_SIZE(src_iir_coeff_44_to_32);
0147         return src_iir_coeff_44_to_32;
0148     } else if ((rate_in == 48000 && rate_out == 16000) ||
0149            (rate_in == 96000 && rate_out == 32000)) {
0150         *param_num = ARRAY_SIZE(src_iir_coeff_48_to_16);
0151         return src_iir_coeff_48_to_16;
0152     } else if (rate_in == 48000 && rate_out == 32000) {
0153         *param_num = ARRAY_SIZE(src_iir_coeff_48_to_32);
0154         return src_iir_coeff_48_to_32;
0155     } else if (rate_in == 48000 && rate_out == 44100) {
0156         *param_num = ARRAY_SIZE(src_iir_coeff_48_to_44);
0157         return src_iir_coeff_48_to_44;
0158     } else if (rate_in == 96000 && rate_out == 16000) {
0159         *param_num = ARRAY_SIZE(src_iir_coeff_96_to_16);
0160         return src_iir_coeff_96_to_16;
0161     } else if ((rate_in == 96000 && rate_out == 44100) ||
0162            (rate_in == 48000 && rate_out == 22050)) {
0163         *param_num = ARRAY_SIZE(src_iir_coeff_96_to_44);
0164         return src_iir_coeff_96_to_44;
0165     }
0166 
0167     *param_num = 0;
0168     return NULL;
0169 }
0170 
0171 static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id)
0172 {
0173     struct mt8186_afe_private *afe_priv = afe->platform_priv;
0174     struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
0175     unsigned int iir_coeff_num;
0176     unsigned int iir_stage;
0177     int rate_in = src_priv->dl_rate;
0178     int rate_out = src_priv->ul_rate;
0179     unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);
0180     unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);
0181 
0182     /* set out freq mode */
0183     regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3,
0184                G_SRC_ASM_FREQ_4_MASK_SFT,
0185                out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
0186 
0187     /* set in freq mode */
0188     regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4,
0189                G_SRC_ASM_FREQ_5_MASK_SFT,
0190                in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
0191 
0192     regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5986);
0193     regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5987);
0194     regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, 0x1fbd);
0195     regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 0);
0196 
0197     /* set iir if in_rate > out_rate */
0198     if (rate_in > rate_out) {
0199         int i;
0200         const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
0201                                   &iir_coeff_num);
0202 
0203         if (iir_coeff_num == 0 || !iir_coeff) {
0204             dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
0205                 __func__, iir_coeff_num, iir_coeff);
0206             return -EINVAL;
0207         }
0208 
0209         /* COEFF_SRAM_CTRL */
0210         regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
0211                    G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
0212                    BIT(G_SRC_COEFF_SRAM_CTRL_SFT));
0213         /* Clear coeff history to r/w coeff from the first position */
0214         regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13,
0215                    G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);
0216         /* Write SRC coeff, should not read the reg during write */
0217         for (i = 0; i < iir_coeff_num; i++)
0218             regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12,
0219                      iir_coeff[i]);
0220         /* disable sram access */
0221         regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
0222                    G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);
0223         /* CHSET_IIR_STAGE */
0224         iir_stage = (iir_coeff_num / 6) - 1;
0225         regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
0226                    G_SRC_CHSET_IIR_STAGE_MASK_SFT,
0227                    iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
0228         /* CHSET_IIR_EN */
0229         regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
0230                    G_SRC_CHSET_IIR_EN_MASK_SFT,
0231                    BIT(G_SRC_CHSET_IIR_EN_SFT));
0232     } else {
0233         /* CHSET_IIR_EN off */
0234         regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
0235                    G_SRC_CHSET_IIR_EN_MASK_SFT, 0);
0236     }
0237 
0238     return 0;
0239 }
0240 
0241 static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id)
0242 {
0243     struct mt8186_afe_private *afe_priv = afe->platform_priv;
0244     struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
0245     unsigned int iir_coeff_num;
0246     unsigned int iir_stage;
0247     int rate_in = src_priv->dl_rate;
0248     int rate_out = src_priv->ul_rate;
0249     unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);
0250     unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);
0251 
0252     /* set out freq mode */
0253     regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3,
0254                G_SRC_ASM_FREQ_4_MASK_SFT,
0255                out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
0256 
0257     /* set in freq mode */
0258     regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4,
0259                G_SRC_ASM_FREQ_5_MASK_SFT,
0260                in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
0261 
0262     regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5986);
0263     regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5987);
0264     regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, 0x1fbd);
0265     regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 0);
0266 
0267     /* set iir if in_rate > out_rate */
0268     if (rate_in > rate_out) {
0269         int i;
0270         const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
0271                                   &iir_coeff_num);
0272 
0273         if (iir_coeff_num == 0 || !iir_coeff) {
0274             dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
0275                  __func__, iir_coeff_num, iir_coeff);
0276             return -EINVAL;
0277         }
0278 
0279         /* COEFF_SRAM_CTRL */
0280         regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
0281                    G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
0282                    BIT(G_SRC_COEFF_SRAM_CTRL_SFT));
0283         /* Clear coeff history to r/w coeff from the first position */
0284         regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13,
0285                    G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);
0286         /* Write SRC coeff, should not read the reg during write */
0287         for (i = 0; i < iir_coeff_num; i++)
0288             regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12,
0289                      iir_coeff[i]);
0290         /* disable sram access */
0291         regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
0292                    G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);
0293         /* CHSET_IIR_STAGE */
0294         iir_stage = (iir_coeff_num / 6) - 1;
0295         regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
0296                    G_SRC_CHSET_IIR_STAGE_MASK_SFT,
0297                    iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
0298         /* CHSET_IIR_EN */
0299         regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
0300                    G_SRC_CHSET_IIR_EN_MASK_SFT,
0301                    BIT(G_SRC_CHSET_IIR_EN_SFT));
0302     } else {
0303         /* CHSET_IIR_EN off */
0304         regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
0305                    G_SRC_CHSET_IIR_EN_MASK_SFT, 0);
0306     }
0307 
0308     return 0;
0309 }
0310 
0311 #define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable"
0312 #define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable"
0313 
0314 static int mtk_hw_src_event(struct snd_soc_dapm_widget *w,
0315                 struct snd_kcontrol *kcontrol,
0316                 int event)
0317 {
0318     struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0319     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0320     struct mt8186_afe_private *afe_priv = afe->platform_priv;
0321     int id;
0322     struct mtk_afe_src_priv *src_priv;
0323     unsigned int reg;
0324 
0325     if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0)
0326         id = MT8186_DAI_SRC_1;
0327     else
0328         id = MT8186_DAI_SRC_2;
0329 
0330     src_priv = afe_priv->dai_priv[id];
0331 
0332     dev_dbg(afe->dev,
0333         "%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n",
0334         __func__, w->name, event, id, src_priv,
0335         src_priv->dl_rate, src_priv->ul_rate);
0336 
0337     switch (event) {
0338     case SND_SOC_DAPM_PRE_PMU:
0339         if (id == MT8186_DAI_SRC_1)
0340             mtk_set_src_1_param(afe, id);
0341         else
0342             mtk_set_src_2_param(afe, id);
0343         break;
0344     case SND_SOC_DAPM_POST_PMU:
0345         reg = (id == MT8186_DAI_SRC_1) ?
0346               AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
0347         /* ASM_ON */
0348         regmap_update_bits(afe->regmap, reg,
0349                    G_SRC_ASM_ON_MASK_SFT,
0350                    BIT(G_SRC_ASM_ON_SFT));
0351         /* CHSET_ON */
0352         regmap_update_bits(afe->regmap, reg,
0353                    G_SRC_CHSET_ON_MASK_SFT,
0354                    BIT(G_SRC_CHSET_ON_SFT));
0355         /* CHSET_STR_CLR */
0356         regmap_update_bits(afe->regmap, reg,
0357                    G_SRC_CHSET_STR_CLR_MASK_SFT,
0358                    BIT(G_SRC_CHSET_STR_CLR_SFT));
0359         break;
0360     case SND_SOC_DAPM_PRE_PMD:
0361         reg = (id == MT8186_DAI_SRC_1) ?
0362               AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
0363         /* ASM_OFF */
0364         regmap_update_bits(afe->regmap, reg, G_SRC_ASM_ON_MASK_SFT, 0);
0365         /* CHSET_OFF */
0366         regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_ON_MASK_SFT, 0);
0367         /* CHSET_STR_CLR */
0368         regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_STR_CLR_MASK_SFT, 0);
0369         break;
0370     default:
0371         break;
0372     }
0373 
0374     return 0;
0375 }
0376 
0377 /* dai component */
0378 static const struct snd_kcontrol_new mtk_hw_src_1_in_ch1_mix[] = {
0379     SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN40,
0380                     I_DL1_CH1, 1, 0),
0381     SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN40,
0382                     I_DL2_CH1, 1, 0),
0383     SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN40,
0384                     I_DL3_CH1, 1, 0),
0385     SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN40_1,
0386                     I_DL4_CH1, 1, 0),
0387     SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN40_1,
0388                     I_DL6_CH1, 1, 0),
0389     SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH1 Switch", AFE_CONN40,
0390                     I_I2S0_CH1, 1, 0),
0391     SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN40_1,
0392                     I_DL5_CH1, 1, 0),
0393 };
0394 
0395 static const struct snd_kcontrol_new mtk_hw_src_1_in_ch2_mix[] = {
0396     SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN41,
0397                     I_DL1_CH2, 1, 0),
0398     SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN41,
0399                     I_DL2_CH2, 1, 0),
0400     SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN41,
0401                     I_DL3_CH2, 1, 0),
0402     SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN41_1,
0403                     I_DL4_CH2, 1, 0),
0404     SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN41_1,
0405                     I_DL6_CH2, 1, 0),
0406     SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH2 Switch", AFE_CONN41,
0407                     I_I2S0_CH2, 1, 0),
0408     SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN41_1,
0409                     I_DL5_CH2, 1, 0),
0410 };
0411 
0412 static const struct snd_kcontrol_new mtk_hw_src_2_in_ch1_mix[] = {
0413     SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN42,
0414                     I_DL1_CH1, 1, 0),
0415     SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN42,
0416                     I_DL2_CH1, 1, 0),
0417     SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN42,
0418                     I_DL3_CH1, 1, 0),
0419     SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN42,
0420                     I_DL4_CH1, 1, 0),
0421     SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN42_1,
0422                     I_DL5_CH1, 1, 0),
0423     SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN42_1,
0424                     I_DL6_CH1, 1, 0),
0425     SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH1 Switch", AFE_CONN42,
0426                     I_GAIN2_OUT_CH1, 1, 0),
0427 };
0428 
0429 static const struct snd_kcontrol_new mtk_hw_src_2_in_ch2_mix[] = {
0430     SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN43,
0431                     I_DL1_CH2, 1, 0),
0432     SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN43,
0433                     I_DL2_CH2, 1, 0),
0434     SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN43,
0435                     I_DL3_CH2, 1, 0),
0436     SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN43,
0437                     I_DL4_CH2, 1, 0),
0438     SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN43_1,
0439                     I_DL5_CH2, 1, 0),
0440     SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN43_1,
0441                     I_DL6_CH2, 1, 0),
0442     SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH2 Switch", AFE_CONN43,
0443                     I_GAIN2_OUT_CH2, 1, 0),
0444 };
0445 
0446 static const struct snd_soc_dapm_widget mtk_dai_src_widgets[] = {
0447     /* inter-connections */
0448     SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH1", SND_SOC_NOPM, 0, 0,
0449                mtk_hw_src_1_in_ch1_mix,
0450                ARRAY_SIZE(mtk_hw_src_1_in_ch1_mix)),
0451     SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH2", SND_SOC_NOPM, 0, 0,
0452                mtk_hw_src_1_in_ch2_mix,
0453                ARRAY_SIZE(mtk_hw_src_1_in_ch2_mix)),
0454     SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH1", SND_SOC_NOPM, 0, 0,
0455                mtk_hw_src_2_in_ch1_mix,
0456                ARRAY_SIZE(mtk_hw_src_2_in_ch1_mix)),
0457     SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH2", SND_SOC_NOPM, 0, 0,
0458                mtk_hw_src_2_in_ch2_mix,
0459                ARRAY_SIZE(mtk_hw_src_2_in_ch2_mix)),
0460 
0461     SND_SOC_DAPM_SUPPLY(HW_SRC_1_EN_W_NAME,
0462                 GENERAL_ASRC_EN_ON, GENERAL1_ASRC_EN_ON_SFT, 0,
0463                 mtk_hw_src_event,
0464                 SND_SOC_DAPM_PRE_PMU |
0465                 SND_SOC_DAPM_POST_PMU |
0466                 SND_SOC_DAPM_PRE_PMD),
0467 
0468     SND_SOC_DAPM_SUPPLY(HW_SRC_2_EN_W_NAME,
0469                 GENERAL_ASRC_EN_ON, GENERAL2_ASRC_EN_ON_SFT, 0,
0470                 mtk_hw_src_event,
0471                 SND_SOC_DAPM_PRE_PMU |
0472                 SND_SOC_DAPM_POST_PMU |
0473                 SND_SOC_DAPM_PRE_PMD),
0474 
0475     SND_SOC_DAPM_INPUT("HW SRC 1 Out Endpoint"),
0476     SND_SOC_DAPM_INPUT("HW SRC 2 Out Endpoint"),
0477     SND_SOC_DAPM_OUTPUT("HW SRC 1 In Endpoint"),
0478     SND_SOC_DAPM_OUTPUT("HW SRC 2 In Endpoint"),
0479 };
0480 
0481 static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source,
0482                   struct snd_soc_dapm_widget *sink)
0483 {
0484     struct snd_soc_dapm_widget *w = source;
0485     struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
0486     struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
0487     struct mt8186_afe_private *afe_priv = afe->platform_priv;
0488     struct mtk_afe_src_priv *src_priv;
0489 
0490     if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0)
0491         src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1];
0492     else
0493         src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2];
0494 
0495     dev_dbg(afe->dev,
0496         "%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n",
0497         __func__, source->name, sink->name,
0498         src_priv->dl_rate, src_priv->ul_rate);
0499 
0500     return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0;
0501 }
0502 
0503 static const struct snd_soc_dapm_route mtk_dai_src_routes[] = {
0504     {"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"},
0505     {"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"},
0506     {"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"},
0507     {"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"},
0508     {"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"},
0509     {"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"},
0510     {"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"},
0511     {"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"},
0512     {"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"},
0513     {"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"},
0514     {"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"},
0515     {"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"},
0516     {"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"},
0517     {"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"},
0518     {"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"},
0519     {"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"},
0520     {"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"},
0521     {"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"},
0522     {"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"},
0523     {"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"},
0524     {"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"},
0525     {"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"},
0526     {"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"},
0527     {"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"},
0528 
0529     {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"},
0530     {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"},
0531 
0532     {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"},
0533     {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"},
0534 
0535     {"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
0536     {"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
0537     {"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
0538     {"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
0539 
0540     {"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"},
0541     {"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"},
0542     {"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"},
0543     {"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"},
0544 };
0545 
0546 /* dai ops */
0547 static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream,
0548                  struct snd_pcm_hw_params *params,
0549                  struct snd_soc_dai *dai)
0550 {
0551     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0552     struct mt8186_afe_private *afe_priv = afe->platform_priv;
0553     int id = dai->id;
0554     struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
0555     unsigned int sft, mask;
0556     unsigned int rate = params_rate(params);
0557     unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id);
0558 
0559     dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
0560         __func__, id, substream->stream, rate);
0561 
0562     /* rate */
0563     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0564         src_priv->dl_rate = rate;
0565         if (id == MT8186_DAI_SRC_1) {
0566             sft = GENERAL1_ASRCIN_MODE_SFT;
0567             mask = GENERAL1_ASRCIN_MODE_MASK;
0568         } else {
0569             sft = GENERAL2_ASRCIN_MODE_SFT;
0570             mask = GENERAL2_ASRCIN_MODE_MASK;
0571         }
0572     } else {
0573         src_priv->ul_rate = rate;
0574         if (id == MT8186_DAI_SRC_1) {
0575             sft = GENERAL1_ASRCOUT_MODE_SFT;
0576             mask = GENERAL1_ASRCOUT_MODE_MASK;
0577         } else {
0578             sft = GENERAL2_ASRCOUT_MODE_SFT;
0579             mask = GENERAL2_ASRCOUT_MODE_MASK;
0580         }
0581     }
0582 
0583     regmap_update_bits(afe->regmap, GENERAL_ASRC_MODE, mask << sft, rate_reg << sft);
0584 
0585     return 0;
0586 }
0587 
0588 static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream,
0589                    struct snd_soc_dai *dai)
0590 {
0591     struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
0592     struct mt8186_afe_private *afe_priv = afe->platform_priv;
0593     int id = dai->id;
0594     struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
0595 
0596     dev_dbg(afe->dev, "%s(), id %d, stream %d\n",
0597         __func__, id, substream->stream);
0598 
0599     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0600         src_priv->dl_rate = 0;
0601     else
0602         src_priv->ul_rate = 0;
0603 
0604     return 0;
0605 }
0606 
0607 static const struct snd_soc_dai_ops mtk_dai_src_ops = {
0608     .hw_params = mtk_dai_src_hw_params,
0609     .hw_free = mtk_dai_src_hw_free,
0610 };
0611 
0612 /* dai driver */
0613 #define MTK_SRC_RATES (SNDRV_PCM_RATE_8000_48000 |\
0614                SNDRV_PCM_RATE_88200 |\
0615                SNDRV_PCM_RATE_96000 |\
0616                SNDRV_PCM_RATE_176400 |\
0617                SNDRV_PCM_RATE_192000)
0618 
0619 #define MTK_SRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
0620              SNDRV_PCM_FMTBIT_S24_LE |\
0621              SNDRV_PCM_FMTBIT_S32_LE)
0622 
0623 static struct snd_soc_dai_driver mtk_dai_src_driver[] = {
0624     {
0625         .name = "HW_SRC_1",
0626         .id = MT8186_DAI_SRC_1,
0627         .playback = {
0628             .stream_name = "HW_SRC_1_In",
0629             .channels_min = 1,
0630             .channels_max = 2,
0631             .rates = MTK_SRC_RATES,
0632             .formats = MTK_SRC_FORMATS,
0633         },
0634         .capture = {
0635             .stream_name = "HW_SRC_1_Out",
0636             .channels_min = 1,
0637             .channels_max = 2,
0638             .rates = MTK_SRC_RATES,
0639             .formats = MTK_SRC_FORMATS,
0640         },
0641         .ops = &mtk_dai_src_ops,
0642     },
0643     {
0644         .name = "HW_SRC_2",
0645         .id = MT8186_DAI_SRC_2,
0646         .playback = {
0647             .stream_name = "HW_SRC_2_In",
0648             .channels_min = 1,
0649             .channels_max = 2,
0650             .rates = MTK_SRC_RATES,
0651             .formats = MTK_SRC_FORMATS,
0652         },
0653         .capture = {
0654             .stream_name = "HW_SRC_2_Out",
0655             .channels_min = 1,
0656             .channels_max = 2,
0657             .rates = MTK_SRC_RATES,
0658             .formats = MTK_SRC_FORMATS,
0659         },
0660         .ops = &mtk_dai_src_ops,
0661     },
0662 };
0663 
0664 int mt8186_dai_src_register(struct mtk_base_afe *afe)
0665 {
0666     struct mtk_base_afe_dai *dai;
0667     int ret;
0668 
0669     dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
0670     if (!dai)
0671         return -ENOMEM;
0672 
0673     list_add(&dai->list, &afe->sub_dais);
0674 
0675     dai->dai_drivers = mtk_dai_src_driver;
0676     dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_src_driver);
0677 
0678     dai->dapm_widgets = mtk_dai_src_widgets;
0679     dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_src_widgets);
0680     dai->dapm_routes = mtk_dai_src_routes;
0681     dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_src_routes);
0682 
0683     /* set dai priv */
0684     ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_1,
0685                   sizeof(struct mtk_afe_src_priv), NULL);
0686     if (ret)
0687         return ret;
0688 
0689     ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_2,
0690                   sizeof(struct mtk_afe_src_priv), NULL);
0691     if (ret)
0692         return ret;
0693 
0694     return 0;
0695 }