696 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// MediaTek ALSA SoC Audio DAI SRC Control4//5// Copyright (c) 2022 MediaTek Inc.6// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>7 8#include <linux/regmap.h>9#include "mt8186-afe-common.h"10#include "mt8186-interconnection.h"11 12struct mtk_afe_src_priv {13 int dl_rate;14 int ul_rate;15};16 17static const unsigned int src_iir_coeff_32_to_16[] = {18 0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002,19 0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002,20 0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002,21 0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002,22 0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002,23 0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002,24 0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002,25 0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x00000126};27 28static const unsigned int src_iir_coeff_44_to_16[] = {29 0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002,30 0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002,31 0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002,32 0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002,33 0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002,34 0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002,35 0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x00000136};37 38static const unsigned int src_iir_coeff_44_to_32[] = {39 0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003,40 0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002,41 0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002,42 0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002,43 0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002,44 0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002,45 0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x00000146};47 48static const unsigned int src_iir_coeff_48_to_16[] = {49 0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002,50 0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002,51 0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002,52 0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002,53 0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002,54 0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002,55 0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001,56 0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x00000457};58 59static const unsigned int src_iir_coeff_48_to_32[] = {60 0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002,61 0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002,62 0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002,63 0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002,64 0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002,65 0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002,66 0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x00000167};68 69static const unsigned int src_iir_coeff_48_to_44[] = {70 0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003,71 0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003,72 0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003,73 0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003,74 0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x00000175};76 77static const unsigned int src_iir_coeff_96_to_16[] = {78 0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002,79 0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003,80 0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003,81 0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003,82 0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002,83 0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002,84 0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002,85 0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001,86};87 88static const unsigned int src_iir_coeff_96_to_44[] = {89 0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002,90 0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002,91 0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002,92 0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002,93 0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002,94 0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002,95 0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001,96 0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001,97};98 99static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate)100{101 switch (rate) {102 case 8000:103 return 0x50000;104 case 11025:105 return 0x6e400;106 case 12000:107 return 0x78000;108 case 16000:109 return 0xa0000;110 case 22050:111 return 0xdc800;112 case 24000:113 return 0xf0000;114 case 32000:115 return 0x140000;116 case 44100:117 return 0x1b9000;118 case 48000:119 return 0x1e0000;120 case 88200:121 return 0x372000;122 case 96000:123 return 0x3c0000;124 case 176400:125 return 0x6e4000;126 case 192000:127 return 0x780000;128 default:129 dev_err(afe->dev, "%s(), rate %d invalid!!!\n",130 __func__, rate);131 return 0;132 }133}134 135static const unsigned int *get_iir_coeff(unsigned int rate_in,136 unsigned int rate_out,137 unsigned int *param_num)138{139 if (rate_in == 32000 && rate_out == 16000) {140 *param_num = ARRAY_SIZE(src_iir_coeff_32_to_16);141 return src_iir_coeff_32_to_16;142 } else if (rate_in == 44100 && rate_out == 16000) {143 *param_num = ARRAY_SIZE(src_iir_coeff_44_to_16);144 return src_iir_coeff_44_to_16;145 } else if (rate_in == 44100 && rate_out == 32000) {146 *param_num = ARRAY_SIZE(src_iir_coeff_44_to_32);147 return src_iir_coeff_44_to_32;148 } else if ((rate_in == 48000 && rate_out == 16000) ||149 (rate_in == 96000 && rate_out == 32000)) {150 *param_num = ARRAY_SIZE(src_iir_coeff_48_to_16);151 return src_iir_coeff_48_to_16;152 } else if (rate_in == 48000 && rate_out == 32000) {153 *param_num = ARRAY_SIZE(src_iir_coeff_48_to_32);154 return src_iir_coeff_48_to_32;155 } else if (rate_in == 48000 && rate_out == 44100) {156 *param_num = ARRAY_SIZE(src_iir_coeff_48_to_44);157 return src_iir_coeff_48_to_44;158 } else if (rate_in == 96000 && rate_out == 16000) {159 *param_num = ARRAY_SIZE(src_iir_coeff_96_to_16);160 return src_iir_coeff_96_to_16;161 } else if ((rate_in == 96000 && rate_out == 44100) ||162 (rate_in == 48000 && rate_out == 22050)) {163 *param_num = ARRAY_SIZE(src_iir_coeff_96_to_44);164 return src_iir_coeff_96_to_44;165 }166 167 *param_num = 0;168 return NULL;169}170 171static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id)172{173 struct mt8186_afe_private *afe_priv = afe->platform_priv;174 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];175 unsigned int iir_coeff_num;176 unsigned int iir_stage;177 int rate_in = src_priv->dl_rate;178 int rate_out = src_priv->ul_rate;179 unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);180 unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);181 182 /* set out freq mode */183 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3,184 G_SRC_ASM_FREQ_4_MASK_SFT,185 out_freq_mode << G_SRC_ASM_FREQ_4_SFT);186 187 /* set in freq mode */188 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4,189 G_SRC_ASM_FREQ_5_MASK_SFT,190 in_freq_mode << G_SRC_ASM_FREQ_5_SFT);191 192 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5986);193 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, 0x3f5987);194 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, 0x1fbd);195 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, 0);196 197 /* set iir if in_rate > out_rate */198 if (rate_in > rate_out) {199 int i;200 const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,201 &iir_coeff_num);202 203 if (iir_coeff_num == 0 || !iir_coeff) {204 dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",205 __func__, iir_coeff_num, iir_coeff);206 return -EINVAL;207 }208 209 /* COEFF_SRAM_CTRL */210 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,211 G_SRC_COEFF_SRAM_CTRL_MASK_SFT,212 BIT(G_SRC_COEFF_SRAM_CTRL_SFT));213 /* Clear coeff history to r/w coeff from the first position */214 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13,215 G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);216 /* Write SRC coeff, should not read the reg during write */217 for (i = 0; i < iir_coeff_num; i++)218 regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12,219 iir_coeff[i]);220 /* disable sram access */221 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,222 G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);223 /* CHSET_IIR_STAGE */224 iir_stage = (iir_coeff_num / 6) - 1;225 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,226 G_SRC_CHSET_IIR_STAGE_MASK_SFT,227 iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);228 /* CHSET_IIR_EN */229 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,230 G_SRC_CHSET_IIR_EN_MASK_SFT,231 BIT(G_SRC_CHSET_IIR_EN_SFT));232 } else {233 /* CHSET_IIR_EN off */234 regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,235 G_SRC_CHSET_IIR_EN_MASK_SFT, 0);236 }237 238 return 0;239}240 241static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id)242{243 struct mt8186_afe_private *afe_priv = afe->platform_priv;244 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];245 unsigned int iir_coeff_num;246 unsigned int iir_stage;247 int rate_in = src_priv->dl_rate;248 int rate_out = src_priv->ul_rate;249 unsigned int out_freq_mode = mtk_get_src_freq_mode(afe, rate_out);250 unsigned int in_freq_mode = mtk_get_src_freq_mode(afe, rate_in);251 252 /* set out freq mode */253 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3,254 G_SRC_ASM_FREQ_4_MASK_SFT,255 out_freq_mode << G_SRC_ASM_FREQ_4_SFT);256 257 /* set in freq mode */258 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4,259 G_SRC_ASM_FREQ_5_MASK_SFT,260 in_freq_mode << G_SRC_ASM_FREQ_5_SFT);261 262 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5986);263 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, 0x3f5987);264 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, 0x1fbd);265 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, 0);266 267 /* set iir if in_rate > out_rate */268 if (rate_in > rate_out) {269 int i;270 const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,271 &iir_coeff_num);272 273 if (iir_coeff_num == 0 || !iir_coeff) {274 dev_err(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",275 __func__, iir_coeff_num, iir_coeff);276 return -EINVAL;277 }278 279 /* COEFF_SRAM_CTRL */280 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,281 G_SRC_COEFF_SRAM_CTRL_MASK_SFT,282 BIT(G_SRC_COEFF_SRAM_CTRL_SFT));283 /* Clear coeff history to r/w coeff from the first position */284 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13,285 G_SRC_COEFF_SRAM_ADR_MASK_SFT, 0);286 /* Write SRC coeff, should not read the reg during write */287 for (i = 0; i < iir_coeff_num; i++)288 regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12,289 iir_coeff[i]);290 /* disable sram access */291 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,292 G_SRC_COEFF_SRAM_CTRL_MASK_SFT, 0);293 /* CHSET_IIR_STAGE */294 iir_stage = (iir_coeff_num / 6) - 1;295 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,296 G_SRC_CHSET_IIR_STAGE_MASK_SFT,297 iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);298 /* CHSET_IIR_EN */299 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,300 G_SRC_CHSET_IIR_EN_MASK_SFT,301 BIT(G_SRC_CHSET_IIR_EN_SFT));302 } else {303 /* CHSET_IIR_EN off */304 regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,305 G_SRC_CHSET_IIR_EN_MASK_SFT, 0);306 }307 308 return 0;309}310 311#define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable"312#define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable"313 314static int mtk_hw_src_event(struct snd_soc_dapm_widget *w,315 struct snd_kcontrol *kcontrol,316 int event)317{318 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);319 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);320 struct mt8186_afe_private *afe_priv = afe->platform_priv;321 int id;322 struct mtk_afe_src_priv *src_priv;323 unsigned int reg;324 325 if (snd_soc_dapm_widget_name_cmp(w, HW_SRC_1_EN_W_NAME) == 0)326 id = MT8186_DAI_SRC_1;327 else328 id = MT8186_DAI_SRC_2;329 330 src_priv = afe_priv->dai_priv[id];331 332 dev_dbg(afe->dev,333 "%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n",334 __func__, w->name, event, id, src_priv,335 src_priv->dl_rate, src_priv->ul_rate);336 337 switch (event) {338 case SND_SOC_DAPM_PRE_PMU:339 if (id == MT8186_DAI_SRC_1)340 mtk_set_src_1_param(afe, id);341 else342 mtk_set_src_2_param(afe, id);343 break;344 case SND_SOC_DAPM_POST_PMU:345 reg = (id == MT8186_DAI_SRC_1) ?346 AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;347 /* ASM_ON */348 regmap_update_bits(afe->regmap, reg,349 G_SRC_ASM_ON_MASK_SFT,350 BIT(G_SRC_ASM_ON_SFT));351 /* CHSET_ON */352 regmap_update_bits(afe->regmap, reg,353 G_SRC_CHSET_ON_MASK_SFT,354 BIT(G_SRC_CHSET_ON_SFT));355 /* CHSET_STR_CLR */356 regmap_update_bits(afe->regmap, reg,357 G_SRC_CHSET_STR_CLR_MASK_SFT,358 BIT(G_SRC_CHSET_STR_CLR_SFT));359 break;360 case SND_SOC_DAPM_PRE_PMD:361 reg = (id == MT8186_DAI_SRC_1) ?362 AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;363 /* ASM_OFF */364 regmap_update_bits(afe->regmap, reg, G_SRC_ASM_ON_MASK_SFT, 0);365 /* CHSET_OFF */366 regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_ON_MASK_SFT, 0);367 /* CHSET_STR_CLR */368 regmap_update_bits(afe->regmap, reg, G_SRC_CHSET_STR_CLR_MASK_SFT, 0);369 break;370 default:371 break;372 }373 374 return 0;375}376 377/* dai component */378static const struct snd_kcontrol_new mtk_hw_src_1_in_ch1_mix[] = {379 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN40,380 I_DL1_CH1, 1, 0),381 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN40,382 I_DL2_CH1, 1, 0),383 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN40,384 I_DL3_CH1, 1, 0),385 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN40_1,386 I_DL4_CH1, 1, 0),387 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN40_1,388 I_DL6_CH1, 1, 0),389 SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH1 Switch", AFE_CONN40,390 I_I2S0_CH1, 1, 0),391 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN40_1,392 I_DL5_CH1, 1, 0),393};394 395static const struct snd_kcontrol_new mtk_hw_src_1_in_ch2_mix[] = {396 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN41,397 I_DL1_CH2, 1, 0),398 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN41,399 I_DL2_CH2, 1, 0),400 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN41,401 I_DL3_CH2, 1, 0),402 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN41_1,403 I_DL4_CH2, 1, 0),404 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN41_1,405 I_DL6_CH2, 1, 0),406 SOC_DAPM_SINGLE_AUTODISABLE("I2S0_CH2 Switch", AFE_CONN41,407 I_I2S0_CH2, 1, 0),408 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN41_1,409 I_DL5_CH2, 1, 0),410};411 412static const struct snd_kcontrol_new mtk_hw_src_2_in_ch1_mix[] = {413 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN42,414 I_DL1_CH1, 1, 0),415 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN42,416 I_DL2_CH1, 1, 0),417 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN42,418 I_DL3_CH1, 1, 0),419 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN42,420 I_DL4_CH1, 1, 0),421 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN42_1,422 I_DL5_CH1, 1, 0),423 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN42_1,424 I_DL6_CH1, 1, 0),425 SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH1 Switch", AFE_CONN42,426 I_GAIN2_OUT_CH1, 1, 0),427};428 429static const struct snd_kcontrol_new mtk_hw_src_2_in_ch2_mix[] = {430 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN43,431 I_DL1_CH2, 1, 0),432 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN43,433 I_DL2_CH2, 1, 0),434 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN43,435 I_DL3_CH2, 1, 0),436 SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN43,437 I_DL4_CH2, 1, 0),438 SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN43_1,439 I_DL5_CH2, 1, 0),440 SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN43_1,441 I_DL6_CH2, 1, 0),442 SOC_DAPM_SINGLE_AUTODISABLE("HW_GAIN2_OUT_CH2 Switch", AFE_CONN43,443 I_GAIN2_OUT_CH2, 1, 0),444};445 446static const struct snd_soc_dapm_widget mtk_dai_src_widgets[] = {447 /* inter-connections */448 SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH1", SND_SOC_NOPM, 0, 0,449 mtk_hw_src_1_in_ch1_mix,450 ARRAY_SIZE(mtk_hw_src_1_in_ch1_mix)),451 SND_SOC_DAPM_MIXER("HW_SRC_1_IN_CH2", SND_SOC_NOPM, 0, 0,452 mtk_hw_src_1_in_ch2_mix,453 ARRAY_SIZE(mtk_hw_src_1_in_ch2_mix)),454 SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH1", SND_SOC_NOPM, 0, 0,455 mtk_hw_src_2_in_ch1_mix,456 ARRAY_SIZE(mtk_hw_src_2_in_ch1_mix)),457 SND_SOC_DAPM_MIXER("HW_SRC_2_IN_CH2", SND_SOC_NOPM, 0, 0,458 mtk_hw_src_2_in_ch2_mix,459 ARRAY_SIZE(mtk_hw_src_2_in_ch2_mix)),460 461 SND_SOC_DAPM_SUPPLY(HW_SRC_1_EN_W_NAME,462 GENERAL_ASRC_EN_ON, GENERAL1_ASRC_EN_ON_SFT, 0,463 mtk_hw_src_event,464 SND_SOC_DAPM_PRE_PMU |465 SND_SOC_DAPM_POST_PMU |466 SND_SOC_DAPM_PRE_PMD),467 468 SND_SOC_DAPM_SUPPLY(HW_SRC_2_EN_W_NAME,469 GENERAL_ASRC_EN_ON, GENERAL2_ASRC_EN_ON_SFT, 0,470 mtk_hw_src_event,471 SND_SOC_DAPM_PRE_PMU |472 SND_SOC_DAPM_POST_PMU |473 SND_SOC_DAPM_PRE_PMD),474 475 SND_SOC_DAPM_INPUT("HW SRC 1 Out Endpoint"),476 SND_SOC_DAPM_INPUT("HW SRC 2 Out Endpoint"),477 SND_SOC_DAPM_OUTPUT("HW SRC 1 In Endpoint"),478 SND_SOC_DAPM_OUTPUT("HW SRC 2 In Endpoint"),479};480 481static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source,482 struct snd_soc_dapm_widget *sink)483{484 struct snd_soc_dapm_widget *w = source;485 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);486 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);487 struct mt8186_afe_private *afe_priv = afe->platform_priv;488 struct mtk_afe_src_priv *src_priv;489 490 if (snd_soc_dapm_widget_name_cmp(w, HW_SRC_1_EN_W_NAME) == 0)491 src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1];492 else493 src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2];494 495 dev_dbg(afe->dev,496 "%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n",497 __func__, source->name, sink->name,498 src_priv->dl_rate, src_priv->ul_rate);499 500 return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0;501}502 503static const struct snd_soc_dapm_route mtk_dai_src_routes[] = {504 {"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"},505 {"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"},506 {"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"},507 {"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"},508 {"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"},509 {"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"},510 {"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"},511 {"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"},512 {"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"},513 {"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"},514 {"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"},515 {"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"},516 {"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"},517 {"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"},518 {"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"},519 {"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"},520 {"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"},521 {"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"},522 {"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"},523 {"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"},524 {"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"},525 {"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"},526 {"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"},527 {"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"},528 529 {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"},530 {"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"},531 532 {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"},533 {"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"},534 535 {"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},536 {"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},537 {"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},538 {"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},539 540 {"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"},541 {"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"},542 {"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"},543 {"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"},544};545 546/* dai ops */547static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream,548 struct snd_pcm_hw_params *params,549 struct snd_soc_dai *dai)550{551 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);552 struct mt8186_afe_private *afe_priv = afe->platform_priv;553 int id = dai->id;554 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];555 unsigned int sft, mask;556 unsigned int rate = params_rate(params);557 unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id);558 559 dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",560 __func__, id, substream->stream, rate);561 562 /* rate */563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {564 src_priv->dl_rate = rate;565 if (id == MT8186_DAI_SRC_1) {566 sft = GENERAL1_ASRCIN_MODE_SFT;567 mask = GENERAL1_ASRCIN_MODE_MASK;568 } else {569 sft = GENERAL2_ASRCIN_MODE_SFT;570 mask = GENERAL2_ASRCIN_MODE_MASK;571 }572 } else {573 src_priv->ul_rate = rate;574 if (id == MT8186_DAI_SRC_1) {575 sft = GENERAL1_ASRCOUT_MODE_SFT;576 mask = GENERAL1_ASRCOUT_MODE_MASK;577 } else {578 sft = GENERAL2_ASRCOUT_MODE_SFT;579 mask = GENERAL2_ASRCOUT_MODE_MASK;580 }581 }582 583 regmap_update_bits(afe->regmap, GENERAL_ASRC_MODE, mask << sft, rate_reg << sft);584 585 return 0;586}587 588static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream,589 struct snd_soc_dai *dai)590{591 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);592 struct mt8186_afe_private *afe_priv = afe->platform_priv;593 int id = dai->id;594 struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];595 596 dev_dbg(afe->dev, "%s(), id %d, stream %d\n",597 __func__, id, substream->stream);598 599 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)600 src_priv->dl_rate = 0;601 else602 src_priv->ul_rate = 0;603 604 return 0;605}606 607static const struct snd_soc_dai_ops mtk_dai_src_ops = {608 .hw_params = mtk_dai_src_hw_params,609 .hw_free = mtk_dai_src_hw_free,610};611 612/* dai driver */613#define MTK_SRC_RATES (SNDRV_PCM_RATE_8000_48000 |\614 SNDRV_PCM_RATE_88200 |\615 SNDRV_PCM_RATE_96000 |\616 SNDRV_PCM_RATE_176400 |\617 SNDRV_PCM_RATE_192000)618 619#define MTK_SRC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\620 SNDRV_PCM_FMTBIT_S24_LE |\621 SNDRV_PCM_FMTBIT_S32_LE)622 623static struct snd_soc_dai_driver mtk_dai_src_driver[] = {624 {625 .name = "HW_SRC_1",626 .id = MT8186_DAI_SRC_1,627 .playback = {628 .stream_name = "HW_SRC_1_In",629 .channels_min = 1,630 .channels_max = 2,631 .rates = MTK_SRC_RATES,632 .formats = MTK_SRC_FORMATS,633 },634 .capture = {635 .stream_name = "HW_SRC_1_Out",636 .channels_min = 1,637 .channels_max = 2,638 .rates = MTK_SRC_RATES,639 .formats = MTK_SRC_FORMATS,640 },641 .ops = &mtk_dai_src_ops,642 },643 {644 .name = "HW_SRC_2",645 .id = MT8186_DAI_SRC_2,646 .playback = {647 .stream_name = "HW_SRC_2_In",648 .channels_min = 1,649 .channels_max = 2,650 .rates = MTK_SRC_RATES,651 .formats = MTK_SRC_FORMATS,652 },653 .capture = {654 .stream_name = "HW_SRC_2_Out",655 .channels_min = 1,656 .channels_max = 2,657 .rates = MTK_SRC_RATES,658 .formats = MTK_SRC_FORMATS,659 },660 .ops = &mtk_dai_src_ops,661 },662};663 664int mt8186_dai_src_register(struct mtk_base_afe *afe)665{666 struct mtk_base_afe_dai *dai;667 int ret;668 669 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);670 if (!dai)671 return -ENOMEM;672 673 list_add(&dai->list, &afe->sub_dais);674 675 dai->dai_drivers = mtk_dai_src_driver;676 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_src_driver);677 678 dai->dapm_widgets = mtk_dai_src_widgets;679 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_src_widgets);680 dai->dapm_routes = mtk_dai_src_routes;681 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_src_routes);682 683 /* set dai priv */684 ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_1,685 sizeof(struct mtk_afe_src_priv), NULL);686 if (ret)687 return ret;688 689 ret = mt8186_dai_set_priv(afe, MT8186_DAI_SRC_2,690 sizeof(struct mtk_afe_src_priv), NULL);691 if (ret)692 return ret;693 694 return 0;695}696