18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// MediaTek ALSA SoC Audio DAI ADDA Control 48c2ecf20Sopenharmony_ci// 58c2ecf20Sopenharmony_ci// Copyright (c) 2018 MediaTek Inc. 68c2ecf20Sopenharmony_ci// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/regmap.h> 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci#include "mt6797-afe-common.h" 118c2ecf20Sopenharmony_ci#include "mt6797-interconnection.h" 128c2ecf20Sopenharmony_ci#include "mt6797-reg.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cienum { 158c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_8K = 0, 168c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_11K = 1, 178c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_12K = 2, 188c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_16K = 3, 198c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_22K = 4, 208c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_24K = 5, 218c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_32K = 6, 228c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_44K = 7, 238c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_48K = 8, 248c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_96K = 9, 258c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_192K = 10, 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cienum { 298c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_8K = 0, 308c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_16K = 1, 318c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_32K = 2, 328c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_48K = 3, 338c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_96K = 4, 348c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_192K = 5, 358c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_48K_HD = 6, 368c2ecf20Sopenharmony_ci}; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, 398c2ecf20Sopenharmony_ci unsigned int rate) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci switch (rate) { 428c2ecf20Sopenharmony_ci case 8000: 438c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_8K; 448c2ecf20Sopenharmony_ci case 11025: 458c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_11K; 468c2ecf20Sopenharmony_ci case 12000: 478c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_12K; 488c2ecf20Sopenharmony_ci case 16000: 498c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_16K; 508c2ecf20Sopenharmony_ci case 22050: 518c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_22K; 528c2ecf20Sopenharmony_ci case 24000: 538c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_24K; 548c2ecf20Sopenharmony_ci case 32000: 558c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_32K; 568c2ecf20Sopenharmony_ci case 44100: 578c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_44K; 588c2ecf20Sopenharmony_ci case 48000: 598c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_48K; 608c2ecf20Sopenharmony_ci case 96000: 618c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_96K; 628c2ecf20Sopenharmony_ci case 192000: 638c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_192K; 648c2ecf20Sopenharmony_ci default: 658c2ecf20Sopenharmony_ci dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 668c2ecf20Sopenharmony_ci __func__, rate); 678c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_48K; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, 728c2ecf20Sopenharmony_ci unsigned int rate) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci switch (rate) { 758c2ecf20Sopenharmony_ci case 8000: 768c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_8K; 778c2ecf20Sopenharmony_ci case 16000: 788c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_16K; 798c2ecf20Sopenharmony_ci case 32000: 808c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_32K; 818c2ecf20Sopenharmony_ci case 48000: 828c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_48K; 838c2ecf20Sopenharmony_ci case 96000: 848c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_96K; 858c2ecf20Sopenharmony_ci case 192000: 868c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_192K; 878c2ecf20Sopenharmony_ci default: 888c2ecf20Sopenharmony_ci dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 898c2ecf20Sopenharmony_ci __func__, rate); 908c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_48K; 918c2ecf20Sopenharmony_ci } 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/* dai component */ 958c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { 968c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0), 978c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0), 988c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0), 998c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3, 1008c2ecf20Sopenharmony_ci I_ADDA_UL_CH2, 1, 0), 1018c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3, 1028c2ecf20Sopenharmony_ci I_ADDA_UL_CH1, 1, 0), 1038c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3, 1048c2ecf20Sopenharmony_ci I_PCM_1_CAP_CH1, 1, 0), 1058c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3, 1068c2ecf20Sopenharmony_ci I_PCM_2_CAP_CH1, 1, 0), 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { 1108c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0), 1118c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0), 1128c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0), 1138c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0), 1148c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0), 1158c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0), 1168c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4, 1178c2ecf20Sopenharmony_ci I_ADDA_UL_CH2, 1, 0), 1188c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4, 1198c2ecf20Sopenharmony_ci I_ADDA_UL_CH1, 1, 0), 1208c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4, 1218c2ecf20Sopenharmony_ci I_PCM_1_CAP_CH1, 1, 0), 1228c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4, 1238c2ecf20Sopenharmony_ci I_PCM_2_CAP_CH1, 1, 0), 1248c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4, 1258c2ecf20Sopenharmony_ci I_PCM_1_CAP_CH2, 1, 0), 1268c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4, 1278c2ecf20Sopenharmony_ci I_PCM_2_CAP_CH2, 1, 0), 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistatic int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, 1318c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, 1328c2ecf20Sopenharmony_ci int event) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 1358c2ecf20Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", 1388c2ecf20Sopenharmony_ci __func__, w->name, event); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci switch (event) { 1418c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMD: 1428c2ecf20Sopenharmony_ci /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ 1438c2ecf20Sopenharmony_ci usleep_range(125, 135); 1448c2ecf20Sopenharmony_ci break; 1458c2ecf20Sopenharmony_ci default: 1468c2ecf20Sopenharmony_ci break; 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci return 0; 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cienum { 1538c2ecf20Sopenharmony_ci SUPPLY_SEQ_AUD_TOP_PDN, 1548c2ecf20Sopenharmony_ci SUPPLY_SEQ_ADDA_AFE_ON, 1558c2ecf20Sopenharmony_ci SUPPLY_SEQ_ADDA_DL_ON, 1568c2ecf20Sopenharmony_ci SUPPLY_SEQ_ADDA_UL_ON, 1578c2ecf20Sopenharmony_ci}; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { 1608c2ecf20Sopenharmony_ci /* adda */ 1618c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, 1628c2ecf20Sopenharmony_ci mtk_adda_dl_ch1_mix, 1638c2ecf20Sopenharmony_ci ARRAY_SIZE(mtk_adda_dl_ch1_mix)), 1648c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, 1658c2ecf20Sopenharmony_ci mtk_adda_dl_ch2_mix, 1668c2ecf20Sopenharmony_ci ARRAY_SIZE(mtk_adda_dl_ch2_mix)), 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, 1698c2ecf20Sopenharmony_ci AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, 1708c2ecf20Sopenharmony_ci NULL, 0), 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, 1738c2ecf20Sopenharmony_ci AFE_ADDA_DL_SRC2_CON0, 1748c2ecf20Sopenharmony_ci DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, 1758c2ecf20Sopenharmony_ci NULL, 0), 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, 1788c2ecf20Sopenharmony_ci AFE_ADDA_UL_SRC_CON0, 1798c2ecf20Sopenharmony_ci UL_SRC_ON_TMP_CTL_SFT, 0, 1808c2ecf20Sopenharmony_ci mtk_adda_ul_event, 1818c2ecf20Sopenharmony_ci SND_SOC_DAPM_POST_PMD), 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("aud_dac_clk", SUPPLY_SEQ_AUD_TOP_PDN, 1848c2ecf20Sopenharmony_ci AUDIO_TOP_CON0, PDN_DAC_SFT, 1, 1858c2ecf20Sopenharmony_ci NULL, 0), 1868c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("aud_dac_predis_clk", SUPPLY_SEQ_AUD_TOP_PDN, 1878c2ecf20Sopenharmony_ci AUDIO_TOP_CON0, PDN_DAC_PREDIS_SFT, 1, 1888c2ecf20Sopenharmony_ci NULL, 0), 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("aud_adc_clk", SUPPLY_SEQ_AUD_TOP_PDN, 1918c2ecf20Sopenharmony_ci AUDIO_TOP_CON0, PDN_ADC_SFT, 1, 1928c2ecf20Sopenharmony_ci NULL, 0), 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"), 1958c2ecf20Sopenharmony_ci}; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { 1988c2ecf20Sopenharmony_ci /* playback */ 1998c2ecf20Sopenharmony_ci {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, 2008c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL1_CH1", "DL1"}, 2018c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, 2048c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL2_CH1", "DL2"}, 2058c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, 2088c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL3_CH1", "DL3"}, 2098c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA_DL_CH1"}, 2128c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA_DL_CH2"}, 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci /* adda enable */ 2158c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA Enable"}, 2168c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA Playback Enable"}, 2178c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "ADDA Enable"}, 2188c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "ADDA Capture Enable"}, 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci /* clk */ 2218c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "mtkaif_26m_clk"}, 2228c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "aud_dac_clk"}, 2238c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "aud_dac_predis_clk"}, 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "mtkaif_26m_clk"}, 2268c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "aud_adc_clk"}, 2278c2ecf20Sopenharmony_ci}; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci/* dai ops */ 2308c2ecf20Sopenharmony_cistatic int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, 2318c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 2328c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 2338c2ecf20Sopenharmony_ci{ 2348c2ecf20Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 2358c2ecf20Sopenharmony_ci unsigned int rate = params_rate(params); 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", 2388c2ecf20Sopenharmony_ci __func__, dai->id, substream->stream, rate); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 2418c2ecf20Sopenharmony_ci unsigned int dl_src2_con0 = 0; 2428c2ecf20Sopenharmony_ci unsigned int dl_src2_con1 = 0; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci /* clean predistortion */ 2458c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); 2468c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci /* set input sampling rate */ 2498c2ecf20Sopenharmony_ci dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci /* set output mode */ 2528c2ecf20Sopenharmony_ci switch (rate) { 2538c2ecf20Sopenharmony_ci case 192000: 2548c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */ 2558c2ecf20Sopenharmony_ci dl_src2_con0 |= 1 << 14; 2568c2ecf20Sopenharmony_ci break; 2578c2ecf20Sopenharmony_ci case 96000: 2588c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */ 2598c2ecf20Sopenharmony_ci dl_src2_con0 |= 1 << 14; 2608c2ecf20Sopenharmony_ci break; 2618c2ecf20Sopenharmony_ci default: 2628c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */ 2638c2ecf20Sopenharmony_ci break; 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci /* turn off mute function */ 2678c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x03 << 11); 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci /* set voice input data if input sample rate is 8k or 16k */ 2708c2ecf20Sopenharmony_ci if (rate == 8000 || rate == 16000) 2718c2ecf20Sopenharmony_ci dl_src2_con0 |= 0x01 << 5; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci if (rate < 96000) { 2748c2ecf20Sopenharmony_ci /* SA suggest apply -0.3db to audio/speech path */ 2758c2ecf20Sopenharmony_ci dl_src2_con1 = 0xf74f0000; 2768c2ecf20Sopenharmony_ci } else { 2778c2ecf20Sopenharmony_ci /* SA suggest apply -0.3db to audio/speech path 2788c2ecf20Sopenharmony_ci * with DL gain set to half, 2798c2ecf20Sopenharmony_ci * 0xFFFF = 0dB -> 0x8000 = 0dB when 96k, 192k 2808c2ecf20Sopenharmony_ci */ 2818c2ecf20Sopenharmony_ci dl_src2_con1 = 0x7ba70000; 2828c2ecf20Sopenharmony_ci } 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci /* turn on down-link gain */ 2858c2ecf20Sopenharmony_ci dl_src2_con0 = dl_src2_con0 | (0x01 << 1); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); 2888c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); 2898c2ecf20Sopenharmony_ci } else { 2908c2ecf20Sopenharmony_ci unsigned int voice_mode = 0; 2918c2ecf20Sopenharmony_ci unsigned int ul_src_con0 = 0; /* default value */ 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci /* Using Internal ADC */ 2948c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 2958c2ecf20Sopenharmony_ci AFE_ADDA_TOP_CON0, 2968c2ecf20Sopenharmony_ci 0x1 << 0, 2978c2ecf20Sopenharmony_ci 0x0 << 0); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci voice_mode = adda_ul_rate_transform(afe, rate); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* up8x txif sat on */ 3048c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_NEWIF_CFG0, 0x03F87201); 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (rate >= 96000) { /* hires */ 3078c2ecf20Sopenharmony_ci /* use hires format [1 0 23] */ 3088c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3098c2ecf20Sopenharmony_ci AFE_ADDA_NEWIF_CFG0, 3108c2ecf20Sopenharmony_ci 0x1 << 5, 3118c2ecf20Sopenharmony_ci 0x1 << 5); 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3148c2ecf20Sopenharmony_ci AFE_ADDA_NEWIF_CFG2, 3158c2ecf20Sopenharmony_ci 0xf << 28, 3168c2ecf20Sopenharmony_ci voice_mode << 28); 3178c2ecf20Sopenharmony_ci } else { /* normal 8~48k */ 3188c2ecf20Sopenharmony_ci /* use fixed 260k anc path */ 3198c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3208c2ecf20Sopenharmony_ci AFE_ADDA_NEWIF_CFG2, 3218c2ecf20Sopenharmony_ci 0xf << 28, 3228c2ecf20Sopenharmony_ci 8 << 28); 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci /* ul_use_cic_out */ 3258c2ecf20Sopenharmony_ci ul_src_con0 |= 0x1 << 20; 3268c2ecf20Sopenharmony_ci } 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3298c2ecf20Sopenharmony_ci AFE_ADDA_NEWIF_CFG2, 3308c2ecf20Sopenharmony_ci 0xf << 28, 3318c2ecf20Sopenharmony_ci 8 << 28); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3348c2ecf20Sopenharmony_ci AFE_ADDA_UL_SRC_CON0, 3358c2ecf20Sopenharmony_ci 0xfffffffe, 3368c2ecf20Sopenharmony_ci ul_src_con0); 3378c2ecf20Sopenharmony_ci } 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci return 0; 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops mtk_dai_adda_ops = { 3438c2ecf20Sopenharmony_ci .hw_params = mtk_dai_adda_hw_params, 3448c2ecf20Sopenharmony_ci}; 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci/* dai driver */ 3478c2ecf20Sopenharmony_ci#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ 3488c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_96000 |\ 3498c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_192000) 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ 3528c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_16000 |\ 3538c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_32000 |\ 3548c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_48000 |\ 3558c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_96000 |\ 3568c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_192000) 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 3598c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE |\ 3608c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE) 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver mtk_dai_adda_driver[] = { 3638c2ecf20Sopenharmony_ci { 3648c2ecf20Sopenharmony_ci .name = "ADDA", 3658c2ecf20Sopenharmony_ci .id = MT6797_DAI_ADDA, 3668c2ecf20Sopenharmony_ci .playback = { 3678c2ecf20Sopenharmony_ci .stream_name = "ADDA Playback", 3688c2ecf20Sopenharmony_ci .channels_min = 1, 3698c2ecf20Sopenharmony_ci .channels_max = 2, 3708c2ecf20Sopenharmony_ci .rates = MTK_ADDA_PLAYBACK_RATES, 3718c2ecf20Sopenharmony_ci .formats = MTK_ADDA_FORMATS, 3728c2ecf20Sopenharmony_ci }, 3738c2ecf20Sopenharmony_ci .capture = { 3748c2ecf20Sopenharmony_ci .stream_name = "ADDA Capture", 3758c2ecf20Sopenharmony_ci .channels_min = 1, 3768c2ecf20Sopenharmony_ci .channels_max = 2, 3778c2ecf20Sopenharmony_ci .rates = MTK_ADDA_CAPTURE_RATES, 3788c2ecf20Sopenharmony_ci .formats = MTK_ADDA_FORMATS, 3798c2ecf20Sopenharmony_ci }, 3808c2ecf20Sopenharmony_ci .ops = &mtk_dai_adda_ops, 3818c2ecf20Sopenharmony_ci }, 3828c2ecf20Sopenharmony_ci}; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ciint mt6797_dai_adda_register(struct mtk_base_afe *afe) 3858c2ecf20Sopenharmony_ci{ 3868c2ecf20Sopenharmony_ci struct mtk_base_afe_dai *dai; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 3898c2ecf20Sopenharmony_ci if (!dai) 3908c2ecf20Sopenharmony_ci return -ENOMEM; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_ci list_add(&dai->list, &afe->sub_dais); 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci dai->dai_drivers = mtk_dai_adda_driver; 3958c2ecf20Sopenharmony_ci dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci dai->dapm_widgets = mtk_dai_adda_widgets; 3988c2ecf20Sopenharmony_ci dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); 3998c2ecf20Sopenharmony_ci dai->dapm_routes = mtk_dai_adda_routes; 4008c2ecf20Sopenharmony_ci dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); 4018c2ecf20Sopenharmony_ci return 0; 4028c2ecf20Sopenharmony_ci} 403