mt6797-dai-adda.c (11113B)
1// SPDX-License-Identifier: GPL-2.0 2// 3// MediaTek ALSA SoC Audio DAI ADDA Control 4// 5// Copyright (c) 2018 MediaTek Inc. 6// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> 7 8#include <linux/regmap.h> 9#include <linux/delay.h> 10#include "mt6797-afe-common.h" 11#include "mt6797-interconnection.h" 12#include "mt6797-reg.h" 13 14enum { 15 MTK_AFE_ADDA_DL_RATE_8K = 0, 16 MTK_AFE_ADDA_DL_RATE_11K = 1, 17 MTK_AFE_ADDA_DL_RATE_12K = 2, 18 MTK_AFE_ADDA_DL_RATE_16K = 3, 19 MTK_AFE_ADDA_DL_RATE_22K = 4, 20 MTK_AFE_ADDA_DL_RATE_24K = 5, 21 MTK_AFE_ADDA_DL_RATE_32K = 6, 22 MTK_AFE_ADDA_DL_RATE_44K = 7, 23 MTK_AFE_ADDA_DL_RATE_48K = 8, 24 MTK_AFE_ADDA_DL_RATE_96K = 9, 25 MTK_AFE_ADDA_DL_RATE_192K = 10, 26}; 27 28enum { 29 MTK_AFE_ADDA_UL_RATE_8K = 0, 30 MTK_AFE_ADDA_UL_RATE_16K = 1, 31 MTK_AFE_ADDA_UL_RATE_32K = 2, 32 MTK_AFE_ADDA_UL_RATE_48K = 3, 33 MTK_AFE_ADDA_UL_RATE_96K = 4, 34 MTK_AFE_ADDA_UL_RATE_192K = 5, 35 MTK_AFE_ADDA_UL_RATE_48K_HD = 6, 36}; 37 38static unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, 39 unsigned int rate) 40{ 41 switch (rate) { 42 case 8000: 43 return MTK_AFE_ADDA_DL_RATE_8K; 44 case 11025: 45 return MTK_AFE_ADDA_DL_RATE_11K; 46 case 12000: 47 return MTK_AFE_ADDA_DL_RATE_12K; 48 case 16000: 49 return MTK_AFE_ADDA_DL_RATE_16K; 50 case 22050: 51 return MTK_AFE_ADDA_DL_RATE_22K; 52 case 24000: 53 return MTK_AFE_ADDA_DL_RATE_24K; 54 case 32000: 55 return MTK_AFE_ADDA_DL_RATE_32K; 56 case 44100: 57 return MTK_AFE_ADDA_DL_RATE_44K; 58 case 48000: 59 return MTK_AFE_ADDA_DL_RATE_48K; 60 case 96000: 61 return MTK_AFE_ADDA_DL_RATE_96K; 62 case 192000: 63 return MTK_AFE_ADDA_DL_RATE_192K; 64 default: 65 dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 66 __func__, rate); 67 return MTK_AFE_ADDA_DL_RATE_48K; 68 } 69} 70 71static unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, 72 unsigned int rate) 73{ 74 switch (rate) { 75 case 8000: 76 return MTK_AFE_ADDA_UL_RATE_8K; 77 case 16000: 78 return MTK_AFE_ADDA_UL_RATE_16K; 79 case 32000: 80 return MTK_AFE_ADDA_UL_RATE_32K; 81 case 48000: 82 return MTK_AFE_ADDA_UL_RATE_48K; 83 case 96000: 84 return MTK_AFE_ADDA_UL_RATE_96K; 85 case 192000: 86 return MTK_AFE_ADDA_UL_RATE_192K; 87 default: 88 dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 89 __func__, rate); 90 return MTK_AFE_ADDA_UL_RATE_48K; 91 } 92} 93 94/* dai component */ 95static const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { 96 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0), 97 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0), 98 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0), 99 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3, 100 I_ADDA_UL_CH2, 1, 0), 101 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3, 102 I_ADDA_UL_CH1, 1, 0), 103 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3, 104 I_PCM_1_CAP_CH1, 1, 0), 105 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3, 106 I_PCM_2_CAP_CH1, 1, 0), 107}; 108 109static const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { 110 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0), 111 SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0), 112 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0), 113 SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0), 114 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0), 115 SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0), 116 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4, 117 I_ADDA_UL_CH2, 1, 0), 118 SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4, 119 I_ADDA_UL_CH1, 1, 0), 120 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4, 121 I_PCM_1_CAP_CH1, 1, 0), 122 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4, 123 I_PCM_2_CAP_CH1, 1, 0), 124 SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4, 125 I_PCM_1_CAP_CH2, 1, 0), 126 SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4, 127 I_PCM_2_CAP_CH2, 1, 0), 128}; 129 130static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, 131 struct snd_kcontrol *kcontrol, 132 int event) 133{ 134 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 135 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 136 137 dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", 138 __func__, w->name, event); 139 140 switch (event) { 141 case SND_SOC_DAPM_POST_PMD: 142 /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ 143 usleep_range(125, 135); 144 break; 145 default: 146 break; 147 } 148 149 return 0; 150} 151 152enum { 153 SUPPLY_SEQ_AUD_TOP_PDN, 154 SUPPLY_SEQ_ADDA_AFE_ON, 155 SUPPLY_SEQ_ADDA_DL_ON, 156 SUPPLY_SEQ_ADDA_UL_ON, 157}; 158 159static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { 160 /* adda */ 161 SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, 162 mtk_adda_dl_ch1_mix, 163 ARRAY_SIZE(mtk_adda_dl_ch1_mix)), 164 SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, 165 mtk_adda_dl_ch2_mix, 166 ARRAY_SIZE(mtk_adda_dl_ch2_mix)), 167 168 SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, 169 AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, 170 NULL, 0), 171 172 SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, 173 AFE_ADDA_DL_SRC2_CON0, 174 DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, 175 NULL, 0), 176 177 SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, 178 AFE_ADDA_UL_SRC_CON0, 179 UL_SRC_ON_TMP_CTL_SFT, 0, 180 mtk_adda_ul_event, 181 SND_SOC_DAPM_POST_PMD), 182 183 SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN, 184 AUDIO_TOP_CON0, PDN_DAC_SFT, 1, 185 NULL, 0), 186 SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN, 187 AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1, 188 NULL, 0), 189 190 SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN, 191 AUDIO_TOP_CON0, PDN_ADC_SFT, 1, 192 NULL, 0), 193 194 SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"), 195}; 196 197static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { 198 /* playback */ 199 {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, 200 {"ADDA_DL_CH2", "DL1_CH1", "DL1"}, 201 {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, 202 203 {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, 204 {"ADDA_DL_CH2", "DL2_CH1", "DL2"}, 205 {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, 206 207 {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, 208 {"ADDA_DL_CH2", "DL3_CH1", "DL3"}, 209 {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, 210 211 {"ADDA Playback", NULL, "ADDA_DL_CH1"}, 212 {"ADDA Playback", NULL, "ADDA_DL_CH2"}, 213 214 /* adda enable */ 215 {"ADDA Playback", NULL, "ADDA Enable"}, 216 {"ADDA Playback", NULL, "ADDA Playback Enable"}, 217 {"ADDA Capture", NULL, "ADDA Enable"}, 218 {"ADDA Capture", NULL, "ADDA Capture Enable"}, 219 220 /* clk */ 221 {"ADDA Playback", NULL, "mtkaif_26m_clk"}, 222 {"ADDA Playback", NULL, "aud_dac_clk"}, 223 {"ADDA Playback", NULL, "aud_dac_predis_clk"}, 224 225 {"ADDA Capture", NULL, "mtkaif_26m_clk"}, 226 {"ADDA Capture", NULL, "aud_adc_clk"}, 227}; 228 229/* dai ops */ 230static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, 231 struct snd_pcm_hw_params *params, 232 struct snd_soc_dai *dai) 233{ 234 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 235 unsigned int rate = params_rate(params); 236 237 dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", 238 __func__, dai->id, substream->stream, rate); 239 240 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 241 unsigned int dl_src2_con0 = 0; 242 unsigned int dl_src2_con1 = 0; 243 244 /* clean predistortion */ 245 regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); 246 regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); 247 248 /* set input sampling rate */ 249 dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28; 250 251 /* set output mode */ 252 switch (rate) { 253 case 192000: 254 dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */ 255 dl_src2_con0 |= 1 << 14; 256 break; 257 case 96000: 258 dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */ 259 dl_src2_con0 |= 1 << 14; 260 break; 261 default: 262 dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */ 263 break; 264 } 265 266 /* turn off mute function */ 267 dl_src2_con0 |= (0x03 << 11); 268 269 /* set voice input data if input sample rate is 8k or 16k */ 270 if (rate == 8000 || rate == 16000) 271 dl_src2_con0 |= 0x01 << 5; 272 273 if (rate < 96000) { 274 /* SA suggest apply -0.3db to audio/speech path */ 275 dl_src2_con1 = 0xf74f0000; 276 } else { 277 /* SA suggest apply -0.3db to audio/speech path 278 * with DL gain set to half, 279 * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k 280 */ 281 dl_src2_con1 = 0x7ba70000; 282 } 283 284 /* turn on down-link gain */ 285 dl_src2_con0 = dl_src2_con0 | (0x01 << 1); 286 287 regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); 288 regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); 289 } else { 290 unsigned int voice_mode = 0; 291 unsigned int ul_src_con0 = 0; /* default value */ 292 293 /* Using Internal ADC */ 294 regmap_update_bits(afe->regmap, 295 AFE_ADDA_TOP_CON0, 296 0x1 << 0, 297 0x0 << 0); 298 299 voice_mode = adda_ul_rate_transform(afe, rate); 300 301 ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); 302 303 /* up8x txif sat on */ 304 regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201); 305 306 if (rate >= 96000) { /* hires */ 307 /* use hires format [1 0 23] */ 308 regmap_update_bits(afe->regmap, 309 AFE_ADDA_NEWIF_CFG0, 310 0x1 << 5, 311 0x1 << 5); 312 313 regmap_update_bits(afe->regmap, 314 AFE_ADDA_NEWIF_CFG2, 315 0xf << 28, 316 voice_mode << 28); 317 } else { /* normal 8~48k */ 318 /* use fixed 260k anc path */ 319 regmap_update_bits(afe->regmap, 320 AFE_ADDA_NEWIF_CFG2, 321 0xf << 28, 322 8 << 28); 323 324 /* ul_use_cic_out */ 325 ul_src_con0 |= 0x1 << 20; 326 } 327 328 regmap_update_bits(afe->regmap, 329 AFE_ADDA_NEWIF_CFG2, 330 0xf << 28, 331 8 << 28); 332 333 regmap_update_bits(afe->regmap, 334 AFE_ADDA_UL_SRC_CON0, 335 0xfffffffe, 336 ul_src_con0); 337 } 338 339 return 0; 340} 341 342static const struct snd_soc_dai_ops mtk_dai_adda_ops = { 343 .hw_params = mtk_dai_adda_hw_params, 344}; 345 346/* dai driver */ 347#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ 348 SNDRV_PCM_RATE_96000 |\ 349 SNDRV_PCM_RATE_192000) 350 351#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ 352 SNDRV_PCM_RATE_16000 |\ 353 SNDRV_PCM_RATE_32000 |\ 354 SNDRV_PCM_RATE_48000 |\ 355 SNDRV_PCM_RATE_96000 |\ 356 SNDRV_PCM_RATE_192000) 357 358#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 359 SNDRV_PCM_FMTBIT_S24_LE |\ 360 SNDRV_PCM_FMTBIT_S32_LE) 361 362static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { 363 { 364 .name = "ADDA", 365 .id = MT6797_DAI_ADDA, 366 .playback = { 367 .stream_name = "ADDA Playback", 368 .channels_min = 1, 369 .channels_max = 2, 370 .rates = MTK_ADDA_PLAYBACK_RATES, 371 .formats = MTK_ADDA_FORMATS, 372 }, 373 .capture = { 374 .stream_name = "ADDA Capture", 375 .channels_min = 1, 376 .channels_max = 2, 377 .rates = MTK_ADDA_CAPTURE_RATES, 378 .formats = MTK_ADDA_FORMATS, 379 }, 380 .ops = &mtk_dai_adda_ops, 381 }, 382}; 383 384int mt6797_dai_adda_register(struct mtk_base_afe *afe) 385{ 386 struct mtk_base_afe_dai *dai; 387 388 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 389 if (!dai) 390 return -ENOMEM; 391 392 list_add(&dai->list, &afe->sub_dais); 393 394 dai->dai_drivers = mtk_dai_adda_driver; 395 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); 396 397 dai->dapm_widgets = mtk_dai_adda_widgets; 398 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); 399 dai->dapm_routes = mtk_dai_adda_routes; 400 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); 401 return 0; 402}