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 "mt8183-afe-common.h" 118c2ecf20Sopenharmony_ci#include "mt8183-interconnection.h" 128c2ecf20Sopenharmony_ci#include "mt8183-reg.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cienum { 158c2ecf20Sopenharmony_ci AUDIO_SDM_LEVEL_MUTE = 0, 168c2ecf20Sopenharmony_ci AUDIO_SDM_LEVEL_NORMAL = 0x1d, 178c2ecf20Sopenharmony_ci /* if you change level normal */ 188c2ecf20Sopenharmony_ci /* you need to change formula of hp impedance and dc trim too */ 198c2ecf20Sopenharmony_ci}; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cienum { 228c2ecf20Sopenharmony_ci DELAY_DATA_MISO1 = 0, 238c2ecf20Sopenharmony_ci DELAY_DATA_MISO2, 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cienum { 278c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_8K = 0, 288c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_11K = 1, 298c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_12K = 2, 308c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_16K = 3, 318c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_22K = 4, 328c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_24K = 5, 338c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_32K = 6, 348c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_44K = 7, 358c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_48K = 8, 368c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_96K = 9, 378c2ecf20Sopenharmony_ci MTK_AFE_ADDA_DL_RATE_192K = 10, 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cienum { 418c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_8K = 0, 428c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_16K = 1, 438c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_32K = 2, 448c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_48K = 3, 458c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_96K = 4, 468c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_192K = 5, 478c2ecf20Sopenharmony_ci MTK_AFE_ADDA_UL_RATE_48K_HD = 6, 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic unsigned int adda_dl_rate_transform(struct mtk_base_afe *afe, 518c2ecf20Sopenharmony_ci unsigned int rate) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci switch (rate) { 548c2ecf20Sopenharmony_ci case 8000: 558c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_8K; 568c2ecf20Sopenharmony_ci case 11025: 578c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_11K; 588c2ecf20Sopenharmony_ci case 12000: 598c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_12K; 608c2ecf20Sopenharmony_ci case 16000: 618c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_16K; 628c2ecf20Sopenharmony_ci case 22050: 638c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_22K; 648c2ecf20Sopenharmony_ci case 24000: 658c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_24K; 668c2ecf20Sopenharmony_ci case 32000: 678c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_32K; 688c2ecf20Sopenharmony_ci case 44100: 698c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_44K; 708c2ecf20Sopenharmony_ci case 48000: 718c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_48K; 728c2ecf20Sopenharmony_ci case 96000: 738c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_96K; 748c2ecf20Sopenharmony_ci case 192000: 758c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_192K; 768c2ecf20Sopenharmony_ci default: 778c2ecf20Sopenharmony_ci dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 788c2ecf20Sopenharmony_ci __func__, rate); 798c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_DL_RATE_48K; 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic unsigned int adda_ul_rate_transform(struct mtk_base_afe *afe, 848c2ecf20Sopenharmony_ci unsigned int rate) 858c2ecf20Sopenharmony_ci{ 868c2ecf20Sopenharmony_ci switch (rate) { 878c2ecf20Sopenharmony_ci case 8000: 888c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_8K; 898c2ecf20Sopenharmony_ci case 16000: 908c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_16K; 918c2ecf20Sopenharmony_ci case 32000: 928c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_32K; 938c2ecf20Sopenharmony_ci case 48000: 948c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_48K; 958c2ecf20Sopenharmony_ci case 96000: 968c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_96K; 978c2ecf20Sopenharmony_ci case 192000: 988c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_192K; 998c2ecf20Sopenharmony_ci default: 1008c2ecf20Sopenharmony_ci dev_warn(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", 1018c2ecf20Sopenharmony_ci __func__, rate); 1028c2ecf20Sopenharmony_ci return MTK_AFE_ADDA_UL_RATE_48K; 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci/* dai component */ 1078c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_dl_ch1_mix[] = { 1088c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN3, I_DL1_CH1, 1, 0), 1098c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN3, I_DL2_CH1, 1, 0), 1108c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN3, I_DL3_CH1, 1, 0), 1118c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN3, 1128c2ecf20Sopenharmony_ci I_ADDA_UL_CH2, 1, 0), 1138c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN3, 1148c2ecf20Sopenharmony_ci I_ADDA_UL_CH1, 1, 0), 1158c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN3, 1168c2ecf20Sopenharmony_ci I_PCM_1_CAP_CH1, 1, 0), 1178c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN3, 1188c2ecf20Sopenharmony_ci I_PCM_2_CAP_CH1, 1, 0), 1198c2ecf20Sopenharmony_ci}; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_dl_ch2_mix[] = { 1228c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1", AFE_CONN4, I_DL1_CH1, 1, 0), 1238c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2", AFE_CONN4, I_DL1_CH2, 1, 0), 1248c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1", AFE_CONN4, I_DL2_CH1, 1, 0), 1258c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2", AFE_CONN4, I_DL2_CH2, 1, 0), 1268c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1", AFE_CONN4, I_DL3_CH1, 1, 0), 1278c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2", AFE_CONN4, I_DL3_CH2, 1, 0), 1288c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2", AFE_CONN4, 1298c2ecf20Sopenharmony_ci I_ADDA_UL_CH2, 1, 0), 1308c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1", AFE_CONN4, 1318c2ecf20Sopenharmony_ci I_ADDA_UL_CH1, 1, 0), 1328c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1", AFE_CONN4, 1338c2ecf20Sopenharmony_ci I_PCM_1_CAP_CH1, 1, 0), 1348c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH1", AFE_CONN4, 1358c2ecf20Sopenharmony_ci I_PCM_2_CAP_CH1, 1, 0), 1368c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2", AFE_CONN4, 1378c2ecf20Sopenharmony_ci I_PCM_1_CAP_CH2, 1, 0), 1388c2ecf20Sopenharmony_ci SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2", AFE_CONN4, 1398c2ecf20Sopenharmony_ci I_PCM_2_CAP_CH2, 1, 0), 1408c2ecf20Sopenharmony_ci}; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, 1438c2ecf20Sopenharmony_ci struct snd_kcontrol *kcontrol, 1448c2ecf20Sopenharmony_ci int event) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 1478c2ecf20Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 1488c2ecf20Sopenharmony_ci struct mt8183_afe_private *afe_priv = afe->platform_priv; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", 1518c2ecf20Sopenharmony_ci __func__, w->name, event); 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci switch (event) { 1548c2ecf20Sopenharmony_ci case SND_SOC_DAPM_PRE_PMU: 1558c2ecf20Sopenharmony_ci /* update setting to dmic */ 1568c2ecf20Sopenharmony_ci if (afe_priv->mtkaif_dmic) { 1578c2ecf20Sopenharmony_ci /* mtkaif_rxif_data_mode = 1, dmic */ 1588c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, 1598c2ecf20Sopenharmony_ci 0x1, 0x1); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci /* dmic mode, 3.25M*/ 1628c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, 1638c2ecf20Sopenharmony_ci 0x0, 0xf << 20); 1648c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 1658c2ecf20Sopenharmony_ci 0x0, 0x1 << 5); 1668c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 1678c2ecf20Sopenharmony_ci 0x0, 0x3 << 14); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci /* turn on dmic, ch1, ch2 */ 1708c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 1718c2ecf20Sopenharmony_ci 0x1 << 1, 0x1 << 1); 1728c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, 1738c2ecf20Sopenharmony_ci 0x3 << 21, 0x3 << 21); 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci break; 1768c2ecf20Sopenharmony_ci case SND_SOC_DAPM_POST_PMD: 1778c2ecf20Sopenharmony_ci /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ 1788c2ecf20Sopenharmony_ci usleep_range(125, 135); 1798c2ecf20Sopenharmony_ci break; 1808c2ecf20Sopenharmony_ci default: 1818c2ecf20Sopenharmony_ci break; 1828c2ecf20Sopenharmony_ci } 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci return 0; 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci/* mtkaif dmic */ 1888c2ecf20Sopenharmony_cistatic const char * const mt8183_adda_off_on_str[] = { 1898c2ecf20Sopenharmony_ci "Off", "On" 1908c2ecf20Sopenharmony_ci}; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic const struct soc_enum mt8183_adda_enum[] = { 1938c2ecf20Sopenharmony_ci SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8183_adda_off_on_str), 1948c2ecf20Sopenharmony_ci mt8183_adda_off_on_str), 1958c2ecf20Sopenharmony_ci}; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic int mt8183_adda_dmic_get(struct snd_kcontrol *kcontrol, 1988c2ecf20Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 2018c2ecf20Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 2028c2ecf20Sopenharmony_ci struct mt8183_afe_private *afe_priv = afe->platform_priv; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci return 0; 2078c2ecf20Sopenharmony_ci} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_cistatic int mt8183_adda_dmic_set(struct snd_kcontrol *kcontrol, 2108c2ecf20Sopenharmony_ci struct snd_ctl_elem_value *ucontrol) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 2138c2ecf20Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 2148c2ecf20Sopenharmony_ci struct mt8183_afe_private *afe_priv = afe->platform_priv; 2158c2ecf20Sopenharmony_ci struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci if (ucontrol->value.enumerated.item[0] >= e->items) 2188c2ecf20Sopenharmony_ci return -EINVAL; 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci afe_priv->mtkaif_dmic = ucontrol->value.integer.value[0]; 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_dmic %d\n", 2238c2ecf20Sopenharmony_ci __func__, kcontrol->id.name, afe_priv->mtkaif_dmic); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci return 0; 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistatic const struct snd_kcontrol_new mtk_adda_controls[] = { 2298c2ecf20Sopenharmony_ci SOC_ENUM_EXT("MTKAIF_DMIC", mt8183_adda_enum[0], 2308c2ecf20Sopenharmony_ci mt8183_adda_dmic_get, mt8183_adda_dmic_set), 2318c2ecf20Sopenharmony_ci}; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cienum { 2348c2ecf20Sopenharmony_ci SUPPLY_SEQ_ADDA_AFE_ON, 2358c2ecf20Sopenharmony_ci SUPPLY_SEQ_ADDA_DL_ON, 2368c2ecf20Sopenharmony_ci SUPPLY_SEQ_ADDA_UL_ON, 2378c2ecf20Sopenharmony_ci}; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { 2408c2ecf20Sopenharmony_ci /* adda */ 2418c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("ADDA_DL_CH1", SND_SOC_NOPM, 0, 0, 2428c2ecf20Sopenharmony_ci mtk_adda_dl_ch1_mix, 2438c2ecf20Sopenharmony_ci ARRAY_SIZE(mtk_adda_dl_ch1_mix)), 2448c2ecf20Sopenharmony_ci SND_SOC_DAPM_MIXER("ADDA_DL_CH2", SND_SOC_NOPM, 0, 0, 2458c2ecf20Sopenharmony_ci mtk_adda_dl_ch2_mix, 2468c2ecf20Sopenharmony_ci ARRAY_SIZE(mtk_adda_dl_ch2_mix)), 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, 2498c2ecf20Sopenharmony_ci AFE_ADDA_UL_DL_CON0, ADDA_AFE_ON_SFT, 0, 2508c2ecf20Sopenharmony_ci NULL, 0), 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, 2538c2ecf20Sopenharmony_ci AFE_ADDA_DL_SRC2_CON0, 2548c2ecf20Sopenharmony_ci DL_2_SRC_ON_TMP_CTL_PRE_SFT, 0, 2558c2ecf20Sopenharmony_ci NULL, 0), 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, 2588c2ecf20Sopenharmony_ci AFE_ADDA_UL_SRC_CON0, 2598c2ecf20Sopenharmony_ci UL_SRC_ON_TMP_CTL_SFT, 0, 2608c2ecf20Sopenharmony_ci mtk_adda_ul_event, 2618c2ecf20Sopenharmony_ci SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_clk"), 2648c2ecf20Sopenharmony_ci SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_predis_clk"), 2658c2ecf20Sopenharmony_ci SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_clk"), 2668c2ecf20Sopenharmony_ci SND_SOC_DAPM_CLOCK_SUPPLY("mtkaif_26m_clk"), 2678c2ecf20Sopenharmony_ci}; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { 2708c2ecf20Sopenharmony_ci /* playback */ 2718c2ecf20Sopenharmony_ci {"ADDA_DL_CH1", "DL1_CH1", "DL1"}, 2728c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL1_CH1", "DL1"}, 2738c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL1_CH2", "DL1"}, 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci {"ADDA_DL_CH1", "DL2_CH1", "DL2"}, 2768c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL2_CH1", "DL2"}, 2778c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL2_CH2", "DL2"}, 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci {"ADDA_DL_CH1", "DL3_CH1", "DL3"}, 2808c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL3_CH1", "DL3"}, 2818c2ecf20Sopenharmony_ci {"ADDA_DL_CH2", "DL3_CH2", "DL3"}, 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA_DL_CH1"}, 2848c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA_DL_CH2"}, 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci /* adda enable */ 2878c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA Enable"}, 2888c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "ADDA Playback Enable"}, 2898c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "ADDA Enable"}, 2908c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "ADDA Capture Enable"}, 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci /* clk */ 2938c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "mtkaif_26m_clk"}, 2948c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "aud_dac_clk"}, 2958c2ecf20Sopenharmony_ci {"ADDA Playback", NULL, "aud_dac_predis_clk"}, 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "mtkaif_26m_clk"}, 2988c2ecf20Sopenharmony_ci {"ADDA Capture", NULL, "aud_adc_clk"}, 2998c2ecf20Sopenharmony_ci}; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_cistatic int set_mtkaif_rx(struct mtk_base_afe *afe) 3028c2ecf20Sopenharmony_ci{ 3038c2ecf20Sopenharmony_ci struct mt8183_afe_private *afe_priv = afe->platform_priv; 3048c2ecf20Sopenharmony_ci int delay_data; 3058c2ecf20Sopenharmony_ci int delay_cycle; 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci switch (afe_priv->mtkaif_protocol) { 3088c2ecf20Sopenharmony_ci case MT8183_MTKAIF_PROTOCOL_2_CLK_P2: 3098c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x38); 3108c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x39); 3118c2ecf20Sopenharmony_ci /* mtkaif_rxif_clkinv_adc inverse for calibration */ 3128c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 3138c2ecf20Sopenharmony_ci 0x80010000); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci if (afe_priv->mtkaif_phase_cycle[0] >= 3168c2ecf20Sopenharmony_ci afe_priv->mtkaif_phase_cycle[1]) { 3178c2ecf20Sopenharmony_ci delay_data = DELAY_DATA_MISO1; 3188c2ecf20Sopenharmony_ci delay_cycle = afe_priv->mtkaif_phase_cycle[0] - 3198c2ecf20Sopenharmony_ci afe_priv->mtkaif_phase_cycle[1]; 3208c2ecf20Sopenharmony_ci } else { 3218c2ecf20Sopenharmony_ci delay_data = DELAY_DATA_MISO2; 3228c2ecf20Sopenharmony_ci delay_cycle = afe_priv->mtkaif_phase_cycle[1] - 3238c2ecf20Sopenharmony_ci afe_priv->mtkaif_phase_cycle[0]; 3248c2ecf20Sopenharmony_ci } 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3278c2ecf20Sopenharmony_ci AFE_ADDA_MTKAIF_RX_CFG2, 3288c2ecf20Sopenharmony_ci MTKAIF_RXIF_DELAY_DATA_MASK_SFT, 3298c2ecf20Sopenharmony_ci delay_data << MTKAIF_RXIF_DELAY_DATA_SFT); 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 3328c2ecf20Sopenharmony_ci AFE_ADDA_MTKAIF_RX_CFG2, 3338c2ecf20Sopenharmony_ci MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT, 3348c2ecf20Sopenharmony_ci delay_cycle << MTKAIF_RXIF_DELAY_CYCLE_SFT); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci case MT8183_MTKAIF_PROTOCOL_2: 3378c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31); 3388c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 3398c2ecf20Sopenharmony_ci 0x00010000); 3408c2ecf20Sopenharmony_ci break; 3418c2ecf20Sopenharmony_ci case MT8183_MTKAIF_PROTOCOL_1: 3428c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_AUD_PAD_TOP, 0x31); 3438c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x0); 3448c2ecf20Sopenharmony_ci default: 3458c2ecf20Sopenharmony_ci break; 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci return 0; 3498c2ecf20Sopenharmony_ci} 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci/* dai ops */ 3528c2ecf20Sopenharmony_cistatic int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, 3538c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 3548c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 3578c2ecf20Sopenharmony_ci unsigned int rate = params_rate(params); 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ci dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", 3608c2ecf20Sopenharmony_ci __func__, dai->id, substream->stream, rate); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 3638c2ecf20Sopenharmony_ci unsigned int dl_src2_con0 = 0; 3648c2ecf20Sopenharmony_ci unsigned int dl_src2_con1 = 0; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci /* clean predistortion */ 3678c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0); 3688c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci /* set sampling rate */ 3718c2ecf20Sopenharmony_ci dl_src2_con0 = adda_dl_rate_transform(afe, rate) << 28; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci /* set output mode */ 3748c2ecf20Sopenharmony_ci switch (rate) { 3758c2ecf20Sopenharmony_ci case 192000: 3768c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x1 << 24); /* UP_SAMPLING_RATE_X2 */ 3778c2ecf20Sopenharmony_ci dl_src2_con0 |= 1 << 14; 3788c2ecf20Sopenharmony_ci break; 3798c2ecf20Sopenharmony_ci case 96000: 3808c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x2 << 24); /* UP_SAMPLING_RATE_X4 */ 3818c2ecf20Sopenharmony_ci dl_src2_con0 |= 1 << 14; 3828c2ecf20Sopenharmony_ci break; 3838c2ecf20Sopenharmony_ci default: 3848c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x3 << 24); /* UP_SAMPLING_RATE_X8 */ 3858c2ecf20Sopenharmony_ci break; 3868c2ecf20Sopenharmony_ci } 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci /* turn off mute function */ 3898c2ecf20Sopenharmony_ci dl_src2_con0 |= (0x03 << 11); 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci /* set voice input data if input sample rate is 8k or 16k */ 3928c2ecf20Sopenharmony_ci if (rate == 8000 || rate == 16000) 3938c2ecf20Sopenharmony_ci dl_src2_con0 |= 0x01 << 5; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci /* SA suggest apply -0.3db to audio/speech path */ 3968c2ecf20Sopenharmony_ci dl_src2_con1 = 0xf74f0000; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci /* turn on down-link gain */ 3998c2ecf20Sopenharmony_ci dl_src2_con0 = dl_src2_con0 | (0x01 << 1); 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON0, dl_src2_con0); 4028c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_DL_SRC2_CON1, dl_src2_con1); 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci /* set sdm gain */ 4058c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 4068c2ecf20Sopenharmony_ci AFE_ADDA_DL_SDM_DCCOMP_CON, 4078c2ecf20Sopenharmony_ci ATTGAIN_CTL_MASK_SFT, 4088c2ecf20Sopenharmony_ci AUDIO_SDM_LEVEL_NORMAL << ATTGAIN_CTL_SFT); 4098c2ecf20Sopenharmony_ci } else { 4108c2ecf20Sopenharmony_ci unsigned int voice_mode = 0; 4118c2ecf20Sopenharmony_ci unsigned int ul_src_con0 = 0; /* default value */ 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci /* set mtkaif protocol */ 4148c2ecf20Sopenharmony_ci set_mtkaif_rx(afe); 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci /* Using Internal ADC */ 4178c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 4188c2ecf20Sopenharmony_ci AFE_ADDA_TOP_CON0, 4198c2ecf20Sopenharmony_ci 0x1 << 0, 4208c2ecf20Sopenharmony_ci 0x0 << 0); 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci voice_mode = adda_ul_rate_transform(afe, rate); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci ul_src_con0 |= (voice_mode << 17) & (0x7 << 17); 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_ci /* enable iir */ 4278c2ecf20Sopenharmony_ci ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) & 4288c2ecf20Sopenharmony_ci UL_IIR_ON_TMP_CTL_MASK_SFT; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci /* 35Hz @ 48k */ 4318c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_02_01, 0x00000000); 4328c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_04_03, 0x00003FB8); 4338c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_06_05, 0x3FB80000); 4348c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_08_07, 0x3FB80000); 4358c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_10_09, 0x0000C048); 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci regmap_write(afe->regmap, AFE_ADDA_UL_SRC_CON0, ul_src_con0); 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci /* mtkaif_rxif_data_mode = 0, amic */ 4408c2ecf20Sopenharmony_ci regmap_update_bits(afe->regmap, 4418c2ecf20Sopenharmony_ci AFE_ADDA_MTKAIF_RX_CFG0, 4428c2ecf20Sopenharmony_ci 0x1 << 0, 4438c2ecf20Sopenharmony_ci 0x0 << 0); 4448c2ecf20Sopenharmony_ci } 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci return 0; 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops mtk_dai_adda_ops = { 4508c2ecf20Sopenharmony_ci .hw_params = mtk_dai_adda_hw_params, 4518c2ecf20Sopenharmony_ci}; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci/* dai driver */ 4548c2ecf20Sopenharmony_ci#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ 4558c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_96000 |\ 4568c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_192000) 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_ci#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ 4598c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_16000 |\ 4608c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_32000 |\ 4618c2ecf20Sopenharmony_ci SNDRV_PCM_RATE_48000) 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 4648c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S24_LE |\ 4658c2ecf20Sopenharmony_ci SNDRV_PCM_FMTBIT_S32_LE) 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver mtk_dai_adda_driver[] = { 4688c2ecf20Sopenharmony_ci { 4698c2ecf20Sopenharmony_ci .name = "ADDA", 4708c2ecf20Sopenharmony_ci .id = MT8183_DAI_ADDA, 4718c2ecf20Sopenharmony_ci .playback = { 4728c2ecf20Sopenharmony_ci .stream_name = "ADDA Playback", 4738c2ecf20Sopenharmony_ci .channels_min = 1, 4748c2ecf20Sopenharmony_ci .channels_max = 2, 4758c2ecf20Sopenharmony_ci .rates = MTK_ADDA_PLAYBACK_RATES, 4768c2ecf20Sopenharmony_ci .formats = MTK_ADDA_FORMATS, 4778c2ecf20Sopenharmony_ci }, 4788c2ecf20Sopenharmony_ci .capture = { 4798c2ecf20Sopenharmony_ci .stream_name = "ADDA Capture", 4808c2ecf20Sopenharmony_ci .channels_min = 1, 4818c2ecf20Sopenharmony_ci .channels_max = 2, 4828c2ecf20Sopenharmony_ci .rates = MTK_ADDA_CAPTURE_RATES, 4838c2ecf20Sopenharmony_ci .formats = MTK_ADDA_FORMATS, 4848c2ecf20Sopenharmony_ci }, 4858c2ecf20Sopenharmony_ci .ops = &mtk_dai_adda_ops, 4868c2ecf20Sopenharmony_ci }, 4878c2ecf20Sopenharmony_ci}; 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ciint mt8183_dai_adda_register(struct mtk_base_afe *afe) 4908c2ecf20Sopenharmony_ci{ 4918c2ecf20Sopenharmony_ci struct mtk_base_afe_dai *dai; 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 4948c2ecf20Sopenharmony_ci if (!dai) 4958c2ecf20Sopenharmony_ci return -ENOMEM; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci list_add(&dai->list, &afe->sub_dais); 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci dai->dai_drivers = mtk_dai_adda_driver; 5008c2ecf20Sopenharmony_ci dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci dai->controls = mtk_adda_controls; 5038c2ecf20Sopenharmony_ci dai->num_controls = ARRAY_SIZE(mtk_adda_controls); 5048c2ecf20Sopenharmony_ci dai->dapm_widgets = mtk_dai_adda_widgets; 5058c2ecf20Sopenharmony_ci dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); 5068c2ecf20Sopenharmony_ci dai->dapm_routes = mtk_dai_adda_routes; 5078c2ecf20Sopenharmony_ci dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); 5088c2ecf20Sopenharmony_ci return 0; 5098c2ecf20Sopenharmony_ci} 510