Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Enable DMIC for Genio 700/510 EVK

Merge series from "Nícolas F. R. A. Prado" <nfraprado@collabora.com>:

This series enables the dual digital microphones present on the Genio
700 and 510 EVK boards.

+762 -6
+1
Documentation/devicetree/bindings/sound/mediatek,mt8188-mt6359.yaml
··· 62 62 - PCM1_BE 63 63 - DL_SRC_BE 64 64 - UL_SRC_BE 65 + - DMIC_BE 65 66 66 67 codec: 67 68 description: Holds subnode which indicates codec dai.
+1
sound/soc/mediatek/mt8188/Makefile
··· 6 6 mt8188-afe-pcm.o \ 7 7 mt8188-audsys-clk.o \ 8 8 mt8188-dai-adda.o \ 9 + mt8188-dai-dmic.o \ 9 10 mt8188-dai-etdm.o \ 10 11 mt8188-dai-pcm.o 11 12
+8
sound/soc/mediatek/mt8188/mt8188-afe-clk.c
··· 58 58 [MT8188_CLK_AUD_ADC] = "aud_adc", 59 59 [MT8188_CLK_AUD_DAC_HIRES] = "aud_dac_hires", 60 60 [MT8188_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp", 61 + [MT8188_CLK_AUD_AFE_DMIC1] = "aud_afe_dmic1", 62 + [MT8188_CLK_AUD_AFE_DMIC2] = "aud_afe_dmic2", 63 + [MT8188_CLK_AUD_AFE_DMIC3] = "aud_afe_dmic3", 64 + [MT8188_CLK_AUD_AFE_DMIC4] = "aud_afe_dmic4", 61 65 [MT8188_CLK_AUD_ADC_HIRES] = "aud_adc_hires", 66 + [MT8188_CLK_AUD_DMIC_HIRES1] = "aud_dmic_hires1", 67 + [MT8188_CLK_AUD_DMIC_HIRES2] = "aud_dmic_hires2", 68 + [MT8188_CLK_AUD_DMIC_HIRES3] = "aud_dmic_hires3", 69 + [MT8188_CLK_AUD_DMIC_HIRES4] = "aud_dmic_hires4", 62 70 [MT8188_CLK_AUD_I2SIN] = "aud_i2sin", 63 71 [MT8188_CLK_AUD_TDM_IN] = "aud_tdm_in", 64 72 [MT8188_CLK_AUD_I2S_OUT] = "aud_i2s_out",
+8
sound/soc/mediatek/mt8188/mt8188-afe-clk.h
··· 54 54 MT8188_CLK_AUD_ADC, 55 55 MT8188_CLK_AUD_DAC_HIRES, 56 56 MT8188_CLK_AUD_A1SYS_HP, 57 + MT8188_CLK_AUD_AFE_DMIC1, 58 + MT8188_CLK_AUD_AFE_DMIC2, 59 + MT8188_CLK_AUD_AFE_DMIC3, 60 + MT8188_CLK_AUD_AFE_DMIC4, 57 61 MT8188_CLK_AUD_ADC_HIRES, 62 + MT8188_CLK_AUD_DMIC_HIRES1, 63 + MT8188_CLK_AUD_DMIC_HIRES2, 64 + MT8188_CLK_AUD_DMIC_HIRES3, 65 + MT8188_CLK_AUD_DMIC_HIRES4, 58 66 MT8188_CLK_AUD_I2SIN, 59 67 MT8188_CLK_AUD_TDM_IN, 60 68 MT8188_CLK_AUD_I2S_OUT,
+1
sound/soc/mediatek/mt8188/mt8188-afe-common.h
··· 137 137 int mt8188_afe_fs_timing(unsigned int rate); 138 138 /* dai register */ 139 139 int mt8188_dai_adda_register(struct mtk_base_afe *afe); 140 + int mt8188_dai_dmic_register(struct mtk_base_afe *afe); 140 141 int mt8188_dai_etdm_register(struct mtk_base_afe *afe); 141 142 int mt8188_dai_pcm_register(struct mtk_base_afe *afe); 142 143
+24 -4
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
··· 652 652 653 653 static const struct snd_kcontrol_new o002_mix[] = { 654 654 SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN2, 0, 1, 0), 655 + SOC_DAPM_SINGLE_AUTODISABLE("I004 Switch", AFE_CONN2, 4, 1, 0), 655 656 SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN2, 12, 1, 0), 656 657 SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN2, 20, 1, 0), 657 658 SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN2, 22, 1, 0), ··· 663 662 664 663 static const struct snd_kcontrol_new o003_mix[] = { 665 664 SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN3, 1, 1, 0), 665 + SOC_DAPM_SINGLE_AUTODISABLE("I005 Switch", AFE_CONN3, 5, 1, 0), 666 + SOC_DAPM_SINGLE_AUTODISABLE("I006 Switch", AFE_CONN3, 6, 1, 0), 666 667 SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN3, 13, 1, 0), 667 668 SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN3, 21, 1, 0), 668 669 SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN3, 23, 1, 0), ··· 675 672 676 673 static const struct snd_kcontrol_new o004_mix[] = { 677 674 SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN4, 0, 1, 0), 675 + SOC_DAPM_SINGLE_AUTODISABLE("I006 Switch", AFE_CONN4, 6, 1, 0), 676 + SOC_DAPM_SINGLE_AUTODISABLE("I008 Switch", AFE_CONN4, 8, 1, 0), 678 677 SOC_DAPM_SINGLE_AUTODISABLE("I014 Switch", AFE_CONN4, 14, 1, 0), 679 678 SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN4, 24, 1, 0), 680 679 SOC_DAPM_SINGLE_AUTODISABLE("I074 Switch", AFE_CONN4_2, 10, 1, 0), ··· 684 679 685 680 static const struct snd_kcontrol_new o005_mix[] = { 686 681 SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN5, 1, 1, 0), 682 + SOC_DAPM_SINGLE_AUTODISABLE("I007 Switch", AFE_CONN5, 7, 1, 0), 683 + SOC_DAPM_SINGLE_AUTODISABLE("I010 Switch", AFE_CONN5, 10, 1, 0), 687 684 SOC_DAPM_SINGLE_AUTODISABLE("I015 Switch", AFE_CONN5, 15, 1, 0), 688 685 SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN5, 25, 1, 0), 689 686 SOC_DAPM_SINGLE_AUTODISABLE("I075 Switch", AFE_CONN5_2, 11, 1, 0), ··· 693 686 694 687 static const struct snd_kcontrol_new o006_mix[] = { 695 688 SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN6, 0, 1, 0), 689 + SOC_DAPM_SINGLE_AUTODISABLE("I008 Switch", AFE_CONN6, 8, 1, 0), 696 690 SOC_DAPM_SINGLE_AUTODISABLE("I016 Switch", AFE_CONN6, 16, 1, 0), 697 691 SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN6, 26, 1, 0), 698 692 SOC_DAPM_SINGLE_AUTODISABLE("I076 Switch", AFE_CONN6_2, 12, 1, 0), ··· 701 693 702 694 static const struct snd_kcontrol_new o007_mix[] = { 703 695 SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN7, 1, 1, 0), 696 + SOC_DAPM_SINGLE_AUTODISABLE("I009 Switch", AFE_CONN7, 9, 1, 0), 704 697 SOC_DAPM_SINGLE_AUTODISABLE("I017 Switch", AFE_CONN7, 17, 1, 0), 705 698 SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN7, 27, 1, 0), 706 699 SOC_DAPM_SINGLE_AUTODISABLE("I077 Switch", AFE_CONN7_2, 13, 1, 0), 707 700 }; 708 701 709 702 static const struct snd_kcontrol_new o008_mix[] = { 703 + SOC_DAPM_SINGLE_AUTODISABLE("I010 Switch", AFE_CONN8, 10, 1, 0), 710 704 SOC_DAPM_SINGLE_AUTODISABLE("I018 Switch", AFE_CONN8, 18, 1, 0), 711 705 SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN8, 28, 1, 0), 712 706 SOC_DAPM_SINGLE_AUTODISABLE("I078 Switch", AFE_CONN8_2, 14, 1, 0), 713 707 }; 714 708 715 709 static const struct snd_kcontrol_new o009_mix[] = { 710 + SOC_DAPM_SINGLE_AUTODISABLE("I011 Switch", AFE_CONN9, 11, 1, 0), 716 711 SOC_DAPM_SINGLE_AUTODISABLE("I019 Switch", AFE_CONN9, 19, 1, 0), 717 712 SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN9, 29, 1, 0), 718 713 SOC_DAPM_SINGLE_AUTODISABLE("I079 Switch", AFE_CONN9_2, 15, 1, 0), ··· 1285 1274 {"O003", "I021 Switch", "I021"}, 1286 1275 {"O002", "I070 Switch", "I070"}, 1287 1276 {"O003", "I071 Switch", "I071"}, 1277 + 1278 + {"O002", "I004 Switch", "I004"}, 1279 + {"O003", "I005 Switch", "I005"}, 1280 + {"O003", "I006 Switch", "I006"}, 1281 + {"O004", "I006 Switch", "I006"}, 1282 + {"O004", "I008 Switch", "I008"}, 1283 + {"O005", "I007 Switch", "I007"}, 1284 + {"O005", "I010 Switch", "I010"}, 1285 + {"O006", "I008 Switch", "I008"}, 1286 + {"O007", "I009 Switch", "I009"}, 1287 + {"O008", "I010 Switch", "I010"}, 1288 + {"O009", "I011 Switch", "I011"}, 1288 1289 1289 1290 {"O034", "I000 Switch", "I000"}, 1290 1291 {"O035", "I001 Switch", "I001"}, ··· 2878 2855 case AFE_DMIC3_SRC_DEBUG_MON0: 2879 2856 case AFE_DMIC3_UL_SRC_MON0: 2880 2857 case AFE_DMIC3_UL_SRC_MON1: 2881 - case DMIC_GAIN1_CUR: 2882 - case DMIC_GAIN2_CUR: 2883 - case DMIC_GAIN3_CUR: 2884 - case DMIC_GAIN4_CUR: 2885 2858 case ETDM_IN1_MONITOR: 2886 2859 case ETDM_IN2_MONITOR: 2887 2860 case ETDM_OUT1_MONITOR: ··· 3095 3076 typedef int (*dai_register_cb)(struct mtk_base_afe *); 3096 3077 static const dai_register_cb dai_register_cbs[] = { 3097 3078 mt8188_dai_adda_register, 3079 + mt8188_dai_dmic_register, 3098 3080 mt8188_dai_etdm_register, 3099 3081 mt8188_dai_pcm_register, 3100 3082 mt8188_dai_memif_register,
+4
sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
··· 84 84 GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "top_a1sys_hp", 14), 85 85 GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "top_audio_h", 16), 86 86 GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "top_audio_h", 17), 87 + GATE_AUD1(CLK_AUD_DMIC_HIRES1, "aud_dmic_hires1", "top_audio_h", 20), 88 + GATE_AUD1(CLK_AUD_DMIC_HIRES2, "aud_dmic_hires2", "top_audio_h", 21), 89 + GATE_AUD1(CLK_AUD_DMIC_HIRES3, "aud_dmic_hires3", "top_audio_h", 22), 90 + GATE_AUD1(CLK_AUD_DMIC_HIRES4, "aud_dmic_hires4", "top_audio_h", 23), 87 91 88 92 /* AUD3 */ 89 93 GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "top_apll5", 5),
+4
sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h
··· 33 33 CLK_AUD_AFE_26M_DMIC_TM, 34 34 CLK_AUD_UL_TML_HIRES, 35 35 CLK_AUD_ADC_HIRES, 36 + CLK_AUD_DMIC_HIRES1, 37 + CLK_AUD_DMIC_HIRES2, 38 + CLK_AUD_DMIC_HIRES3, 39 + CLK_AUD_DMIC_HIRES4, 36 40 CLK_AUD_LINEIN_TUNER, 37 41 CLK_AUD_EARC_TUNER, 38 42 CLK_AUD_I2SIN,
+682
sound/soc/mediatek/mt8188/mt8188-dai-dmic.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * MediaTek ALSA SoC Audio DAI DMIC I/F Control 4 + * 5 + * Copyright (c) 2020 MediaTek Inc. 6 + * Author: Bicycle Tsai <bicycle.tsai@mediatek.com> 7 + * Trevor Wu <trevor.wu@mediatek.com> 8 + * Parker Yang <parker.yang@mediatek.com> 9 + */ 10 + 11 + #include <linux/delay.h> 12 + #include <linux/pm_runtime.h> 13 + #include <linux/regmap.h> 14 + #include <sound/pcm_params.h> 15 + #include "mt8188-afe-clk.h" 16 + #include "mt8188-afe-common.h" 17 + #include "mt8188-reg.h" 18 + 19 + /* DMIC HW Gain configuration maximum value. */ 20 + #define DMIC_GAIN_MAX_STEP GENMASK(19, 0) 21 + #define DMIC_GAIN_MAX_PER_STEP GENMASK(7, 0) 22 + #define DMIC_GAIN_MAX_TARGET GENMASK(27, 0) 23 + #define DMIC_GAIN_MAX_CURRENT GENMASK(27, 0) 24 + 25 + #define CLK_PHASE_SEL_CH1 0 26 + #define CLK_PHASE_SEL_CH2 ((CLK_PHASE_SEL_CH1) + 4) 27 + 28 + #define DMIC1_SRC_SEL 0 29 + #define DMIC2_SRC_SEL 0 30 + #define DMIC3_SRC_SEL 2 31 + #define DMIC4_SRC_SEL 0 32 + #define DMIC5_SRC_SEL 4 33 + #define DMIC6_SRC_SEL 0 34 + #define DMIC7_SRC_SEL 6 35 + #define DMIC8_SRC_SEL 0 36 + 37 + enum { 38 + SUPPLY_SEQ_DMIC_GAIN, 39 + SUPPLY_SEQ_DMIC_CK, 40 + }; 41 + 42 + enum { 43 + DMIC0, 44 + DMIC1, 45 + DMIC2, 46 + DMIC3, 47 + DMIC_NUM, 48 + }; 49 + 50 + struct mtk_dai_dmic_ctrl_reg { 51 + unsigned int con0; 52 + }; 53 + 54 + struct mtk_dai_dmic_hw_gain_ctrl_reg { 55 + unsigned int bypass; 56 + unsigned int con0; 57 + }; 58 + 59 + struct mtk_dai_dmic_priv { 60 + unsigned int gain_on[DMIC_NUM]; 61 + unsigned int channels; 62 + bool hires_required; 63 + }; 64 + 65 + static const struct mtk_dai_dmic_ctrl_reg dmic_ctrl_regs[DMIC_NUM] = { 66 + [DMIC0] = { 67 + .con0 = AFE_DMIC0_UL_SRC_CON0, 68 + }, 69 + [DMIC1] = { 70 + .con0 = AFE_DMIC1_UL_SRC_CON0, 71 + }, 72 + [DMIC2] = { 73 + .con0 = AFE_DMIC2_UL_SRC_CON0, 74 + }, 75 + [DMIC3] = { 76 + .con0 = AFE_DMIC3_UL_SRC_CON0, 77 + }, 78 + }; 79 + 80 + static const struct mtk_dai_dmic_ctrl_reg *get_dmic_ctrl_reg(int id) 81 + { 82 + if (id < 0 || id >= DMIC_NUM) 83 + return NULL; 84 + 85 + return &dmic_ctrl_regs[id]; 86 + } 87 + 88 + static const struct mtk_dai_dmic_hw_gain_ctrl_reg 89 + dmic_hw_gain_ctrl_regs[DMIC_NUM] = { 90 + [DMIC0] = { 91 + .bypass = DMIC_BYPASS_HW_GAIN, 92 + .con0 = DMIC_GAIN1_CON0, 93 + }, 94 + [DMIC1] = { 95 + .bypass = DMIC_BYPASS_HW_GAIN, 96 + .con0 = DMIC_GAIN2_CON0, 97 + }, 98 + [DMIC2] = { 99 + .bypass = DMIC_BYPASS_HW_GAIN, 100 + .con0 = DMIC_GAIN3_CON0, 101 + }, 102 + [DMIC3] = { 103 + .bypass = DMIC_BYPASS_HW_GAIN, 104 + .con0 = DMIC_GAIN4_CON0, 105 + }, 106 + }; 107 + 108 + static const struct mtk_dai_dmic_hw_gain_ctrl_reg 109 + *get_dmic_hw_gain_ctrl_reg(struct mtk_base_afe *afe, int id) 110 + { 111 + if ((id < 0) || (id >= DMIC_NUM)) { 112 + dev_dbg(afe->dev, "%s invalid id\n", __func__); 113 + return NULL; 114 + } 115 + 116 + return &dmic_hw_gain_ctrl_regs[id]; 117 + } 118 + 119 + static void mtk_dai_dmic_hw_gain_bypass(struct mtk_base_afe *afe, 120 + unsigned int id, bool bypass) 121 + { 122 + const struct mtk_dai_dmic_hw_gain_ctrl_reg *reg; 123 + unsigned int msk; 124 + 125 + reg = get_dmic_hw_gain_ctrl_reg(afe, id); 126 + if (!reg) 127 + return; 128 + 129 + switch (id) { 130 + case DMIC0: 131 + msk = DMIC_BYPASS_HW_GAIN_DMIC1_BYPASS; 132 + break; 133 + case DMIC1: 134 + msk = DMIC_BYPASS_HW_GAIN_DMIC2_BYPASS; 135 + break; 136 + case DMIC2: 137 + msk = DMIC_BYPASS_HW_GAIN_DMIC3_BYPASS; 138 + break; 139 + case DMIC3: 140 + msk = DMIC_BYPASS_HW_GAIN_DMIC4_BYPASS; 141 + break; 142 + default: 143 + return; 144 + } 145 + 146 + if (bypass) 147 + regmap_set_bits(afe->regmap, reg->bypass, msk); 148 + else 149 + regmap_clear_bits(afe->regmap, reg->bypass, msk); 150 + } 151 + 152 + static void mtk_dai_dmic_hw_gain_on(struct mtk_base_afe *afe, unsigned int id, 153 + bool on) 154 + { 155 + const struct mtk_dai_dmic_hw_gain_ctrl_reg *reg = get_dmic_hw_gain_ctrl_reg(afe, id); 156 + 157 + if (!reg) 158 + return; 159 + 160 + if (on) 161 + regmap_set_bits(afe->regmap, reg->con0, DMIC_GAIN_CON0_GAIN_ON); 162 + else 163 + regmap_clear_bits(afe->regmap, reg->con0, DMIC_GAIN_CON0_GAIN_ON); 164 + } 165 + 166 + static const struct reg_sequence mtk_dai_dmic_iir_coeff_reg_defaults[] = { 167 + { AFE_DMIC0_IIR_COEF_02_01, 0x00000000 }, 168 + { AFE_DMIC0_IIR_COEF_04_03, 0x00003FB8 }, 169 + { AFE_DMIC0_IIR_COEF_06_05, 0x3FB80000 }, 170 + { AFE_DMIC0_IIR_COEF_08_07, 0x3FB80000 }, 171 + { AFE_DMIC0_IIR_COEF_10_09, 0x0000C048 }, 172 + { AFE_DMIC1_IIR_COEF_02_01, 0x00000000 }, 173 + { AFE_DMIC1_IIR_COEF_04_03, 0x00003FB8 }, 174 + { AFE_DMIC1_IIR_COEF_06_05, 0x3FB80000 }, 175 + { AFE_DMIC1_IIR_COEF_08_07, 0x3FB80000 }, 176 + { AFE_DMIC1_IIR_COEF_10_09, 0x0000C048 }, 177 + { AFE_DMIC2_IIR_COEF_02_01, 0x00000000 }, 178 + { AFE_DMIC2_IIR_COEF_04_03, 0x00003FB8 }, 179 + { AFE_DMIC2_IIR_COEF_06_05, 0x3FB80000 }, 180 + { AFE_DMIC2_IIR_COEF_08_07, 0x3FB80000 }, 181 + { AFE_DMIC2_IIR_COEF_10_09, 0x0000C048 }, 182 + { AFE_DMIC3_IIR_COEF_02_01, 0x00000000 }, 183 + { AFE_DMIC3_IIR_COEF_04_03, 0x00003FB8 }, 184 + { AFE_DMIC3_IIR_COEF_06_05, 0x3FB80000 }, 185 + { AFE_DMIC3_IIR_COEF_08_07, 0x3FB80000 }, 186 + { AFE_DMIC3_IIR_COEF_10_09, 0x0000C048 }, 187 + }; 188 + 189 + static int mtk_dai_dmic_load_iir_coeff_table(struct mtk_base_afe *afe) 190 + { 191 + return regmap_multi_reg_write(afe->regmap, 192 + mtk_dai_dmic_iir_coeff_reg_defaults, 193 + ARRAY_SIZE(mtk_dai_dmic_iir_coeff_reg_defaults)); 194 + } 195 + 196 + static int mtk_dai_dmic_configure_array(struct snd_soc_dai *dai) 197 + { 198 + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 199 + const u32 mask = PWR2_TOP_CON_DMIC8_SRC_SEL_MASK | 200 + PWR2_TOP_CON_DMIC7_SRC_SEL_MASK | 201 + PWR2_TOP_CON_DMIC6_SRC_SEL_MASK | 202 + PWR2_TOP_CON_DMIC5_SRC_SEL_MASK | 203 + PWR2_TOP_CON_DMIC4_SRC_SEL_MASK | 204 + PWR2_TOP_CON_DMIC3_SRC_SEL_MASK | 205 + PWR2_TOP_CON_DMIC2_SRC_SEL_MASK | 206 + PWR2_TOP_CON_DMIC1_SRC_SEL_MASK; 207 + const u32 val = PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(DMIC8_SRC_SEL) | 208 + PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(DMIC7_SRC_SEL) | 209 + PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(DMIC6_SRC_SEL) | 210 + PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(DMIC5_SRC_SEL) | 211 + PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(DMIC4_SRC_SEL) | 212 + PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(DMIC3_SRC_SEL) | 213 + PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(DMIC2_SRC_SEL) | 214 + PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(DMIC1_SRC_SEL); 215 + 216 + return regmap_update_bits(afe->regmap, PWR2_TOP_CON0, mask, val); 217 + } 218 + 219 + /* This function assumes that the caller checked that channels is valid */ 220 + static u8 mtk_dmic_channels_to_dmic_number(unsigned int channels) 221 + { 222 + switch (channels) { 223 + case 1: 224 + return DMIC0; 225 + case 2: 226 + return DMIC1; 227 + case 3: 228 + return DMIC2; 229 + case 4: 230 + default: 231 + return DMIC3; 232 + } 233 + } 234 + 235 + static void mtk_dai_dmic_hw_gain_enable(struct mtk_base_afe *afe, 236 + unsigned int channels, bool enable) 237 + { 238 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 239 + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; 240 + u8 dmic_num; 241 + int i; 242 + 243 + dmic_num = mtk_dmic_channels_to_dmic_number(channels); 244 + for (i = dmic_num; i >= DMIC0; i--) { 245 + if (enable && dmic_priv->gain_on[i]) { 246 + mtk_dai_dmic_hw_gain_bypass(afe, i, false); 247 + mtk_dai_dmic_hw_gain_on(afe, i, true); 248 + } else { 249 + mtk_dai_dmic_hw_gain_on(afe, i, false); 250 + mtk_dai_dmic_hw_gain_bypass(afe, i, true); 251 + } 252 + } 253 + } 254 + 255 + static int mtk_dmic_gain_event(struct snd_soc_dapm_widget *w, 256 + struct snd_kcontrol *kcontrol, 257 + int event) 258 + { 259 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 260 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 261 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 262 + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; 263 + unsigned int channels = dmic_priv->channels; 264 + 265 + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", 266 + __func__, w->name, event); 267 + 268 + if (!channels) 269 + return -EINVAL; 270 + 271 + switch (event) { 272 + case SND_SOC_DAPM_PRE_PMU: 273 + mtk_dai_dmic_hw_gain_enable(afe, channels, true); 274 + break; 275 + case SND_SOC_DAPM_POST_PMD: 276 + mtk_dai_dmic_hw_gain_enable(afe, channels, false); 277 + break; 278 + default: 279 + break; 280 + } 281 + 282 + return 0; 283 + } 284 + 285 + static int mtk_dmic_event(struct snd_soc_dapm_widget *w, 286 + struct snd_kcontrol *kcontrol, 287 + int event) 288 + { 289 + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); 290 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); 291 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 292 + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; 293 + const struct mtk_dai_dmic_ctrl_reg *reg = NULL; 294 + unsigned int channels = dmic_priv->channels; 295 + unsigned int msk; 296 + u8 dmic_num; 297 + int i; 298 + 299 + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", 300 + __func__, w->name, event); 301 + 302 + if (!channels) 303 + return -EINVAL; 304 + 305 + dmic_num = mtk_dmic_channels_to_dmic_number(channels); 306 + 307 + switch (event) { 308 + case SND_SOC_DAPM_PRE_PMU: 309 + /* request fifo soft rst */ 310 + for (i = dmic_num; i >= DMIC0; i--) 311 + msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i); 312 + 313 + regmap_set_bits(afe->regmap, PWR2_TOP_CON1, msk); 314 + 315 + msk = AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL | 316 + AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL | 317 + AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL | 318 + AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL; 319 + 320 + for (i = dmic_num; i >= DMIC0; i--) { 321 + reg = get_dmic_ctrl_reg(i); 322 + if (reg) 323 + regmap_set_bits(afe->regmap, reg->con0, msk); 324 + } 325 + break; 326 + case SND_SOC_DAPM_POST_PMU: 327 + msk = AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL; 328 + 329 + for (i = dmic_num; i >= DMIC0; i--) { 330 + reg = get_dmic_ctrl_reg(i); 331 + if (reg) 332 + regmap_set_bits(afe->regmap, reg->con0, msk); 333 + } 334 + 335 + if (dmic_priv->hires_required) { 336 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]); 337 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]); 338 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]); 339 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]); 340 + } 341 + 342 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]); 343 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]); 344 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]); 345 + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]); 346 + 347 + /* release fifo soft rst */ 348 + msk = 0; 349 + for (i = dmic_num; i >= DMIC0; i--) 350 + msk |= PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(i); 351 + 352 + regmap_clear_bits(afe->regmap, PWR2_TOP_CON1, msk); 353 + break; 354 + case SND_SOC_DAPM_PRE_PMD: 355 + msk = AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL | 356 + AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL | 357 + AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL | 358 + AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL | 359 + AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL; 360 + 361 + for (i = dmic_num; i >= DMIC0; i--) { 362 + reg = get_dmic_ctrl_reg(i); 363 + if (reg) 364 + regmap_set_bits(afe->regmap, reg->con0, msk); 365 + } 366 + break; 367 + case SND_SOC_DAPM_POST_PMD: 368 + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ 369 + usleep_range(125, 126); 370 + 371 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC1]); 372 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC2]); 373 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC3]); 374 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE_DMIC4]); 375 + 376 + if (dmic_priv->hires_required) { 377 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES1]); 378 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES2]); 379 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES3]); 380 + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_DMIC_HIRES4]); 381 + } 382 + break; 383 + default: 384 + break; 385 + } 386 + 387 + return 0; 388 + } 389 + 390 + static int mtk_dai_dmic_hw_params(struct snd_pcm_substream *substream, 391 + struct snd_pcm_hw_params *params, 392 + struct snd_soc_dai *dai) 393 + { 394 + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); 395 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 396 + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; 397 + unsigned int rate = params_rate(params); 398 + unsigned int channels = params_channels(params); 399 + const struct mtk_dai_dmic_ctrl_reg *reg = NULL; 400 + u32 val = AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH1(CLK_PHASE_SEL_CH1) | 401 + AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH2(CLK_PHASE_SEL_CH2) | 402 + AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(0); 403 + const u32 msk = AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL | 404 + AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_MASK | 405 + AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL_MASK | 406 + AFE_DMIC_UL_VOICE_MODE_MASK; 407 + u8 dmic_num; 408 + int ret; 409 + int i; 410 + 411 + if (!channels || channels > 8) 412 + return -EINVAL; 413 + 414 + ret = mtk_dai_dmic_configure_array(dai); 415 + if (ret < 0) 416 + return ret; 417 + 418 + ret = mtk_dai_dmic_load_iir_coeff_table(afe); 419 + if (ret < 0) 420 + return ret; 421 + 422 + switch (rate) { 423 + case 96000: 424 + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_96K; 425 + dmic_priv->hires_required = 1; 426 + break; 427 + case 48000: 428 + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_48K; 429 + dmic_priv->hires_required = 0; 430 + break; 431 + case 32000: 432 + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_32K; 433 + dmic_priv->hires_required = 0; 434 + break; 435 + case 16000: 436 + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_16K; 437 + dmic_priv->hires_required = 0; 438 + break; 439 + case 8000: 440 + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_8K; 441 + dmic_priv->hires_required = 0; 442 + break; 443 + default: 444 + dev_dbg(afe->dev, "%s invalid rate %u, use 48000Hz\n", __func__, rate); 445 + val |= AFE_DMIC_UL_CON0_VOCIE_MODE_48K; 446 + dmic_priv->hires_required = 0; 447 + break; 448 + } 449 + 450 + dmic_num = mtk_dmic_channels_to_dmic_number(channels); 451 + for (i = dmic_num; i >= DMIC0; i--) { 452 + reg = get_dmic_ctrl_reg(i); 453 + if (reg) { 454 + ret = regmap_update_bits(afe->regmap, reg->con0, msk, val); 455 + if (ret < 0) 456 + return ret; 457 + } 458 + } 459 + 460 + dmic_priv->channels = channels; 461 + 462 + return 0; 463 + } 464 + 465 + static const struct snd_soc_dai_ops mtk_dai_dmic_ops = { 466 + .hw_params = mtk_dai_dmic_hw_params, 467 + }; 468 + 469 + #define MTK_DMIC_RATES (SNDRV_PCM_RATE_8000 |\ 470 + SNDRV_PCM_RATE_16000 |\ 471 + SNDRV_PCM_RATE_32000 |\ 472 + SNDRV_PCM_RATE_48000 |\ 473 + SNDRV_PCM_RATE_96000) 474 + 475 + #define MTK_DMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 476 + SNDRV_PCM_FMTBIT_S32_LE) 477 + 478 + static struct snd_soc_dai_driver mtk_dai_dmic_driver[] = { 479 + { 480 + .name = "DMIC", 481 + .id = MT8188_AFE_IO_DMIC_IN, 482 + .capture = { 483 + .stream_name = "DMIC Capture", 484 + .channels_min = 1, 485 + .channels_max = 8, 486 + .rates = MTK_DMIC_RATES, 487 + .formats = MTK_DMIC_FORMATS, 488 + }, 489 + .ops = &mtk_dai_dmic_ops, 490 + }, 491 + }; 492 + 493 + static const struct snd_soc_dapm_widget mtk_dai_dmic_widgets[] = { 494 + SND_SOC_DAPM_MIXER("I004", SND_SOC_NOPM, 0, 0, NULL, 0), 495 + SND_SOC_DAPM_MIXER("I005", SND_SOC_NOPM, 0, 0, NULL, 0), 496 + SND_SOC_DAPM_MIXER("I006", SND_SOC_NOPM, 0, 0, NULL, 0), 497 + SND_SOC_DAPM_MIXER("I007", SND_SOC_NOPM, 0, 0, NULL, 0), 498 + SND_SOC_DAPM_MIXER("I008", SND_SOC_NOPM, 0, 0, NULL, 0), 499 + SND_SOC_DAPM_MIXER("I009", SND_SOC_NOPM, 0, 0, NULL, 0), 500 + SND_SOC_DAPM_MIXER("I010", SND_SOC_NOPM, 0, 0, NULL, 0), 501 + SND_SOC_DAPM_MIXER("I011", SND_SOC_NOPM, 0, 0, NULL, 0), 502 + 503 + SND_SOC_DAPM_SUPPLY_S("DMIC_GAIN_ON", SUPPLY_SEQ_DMIC_GAIN, 504 + SND_SOC_NOPM, 0, 0, 505 + mtk_dmic_gain_event, 506 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 507 + SND_SOC_DAPM_SUPPLY_S("DMIC_CK_ON", SUPPLY_SEQ_DMIC_CK, 508 + PWR2_TOP_CON1, 509 + PWR2_TOP_CON1_DMIC_CKDIV_ON_SHIFT, 0, 510 + mtk_dmic_event, 511 + SND_SOC_DAPM_PRE_POST_PMU | 512 + SND_SOC_DAPM_PRE_POST_PMD), 513 + SND_SOC_DAPM_INPUT("DMIC_INPUT"), 514 + }; 515 + 516 + static const struct snd_soc_dapm_route mtk_dai_dmic_routes[] = { 517 + {"I004", NULL, "DMIC Capture"}, 518 + {"I005", NULL, "DMIC Capture"}, 519 + {"I006", NULL, "DMIC Capture"}, 520 + {"I007", NULL, "DMIC Capture"}, 521 + {"I008", NULL, "DMIC Capture"}, 522 + {"I009", NULL, "DMIC Capture"}, 523 + {"I010", NULL, "DMIC Capture"}, 524 + {"I011", NULL, "DMIC Capture"}, 525 + {"DMIC Capture", NULL, "DMIC_CK_ON"}, 526 + {"DMIC Capture", NULL, "DMIC_GAIN_ON"}, 527 + {"DMIC Capture", NULL, "DMIC_INPUT"}, 528 + }; 529 + 530 + static const char * const mt8188_dmic_gain_enable_text[] = { 531 + "Bypass", "Connect", 532 + }; 533 + 534 + static SOC_ENUM_SINGLE_EXT_DECL(dmic_gain_on_enum, 535 + mt8188_dmic_gain_enable_text); 536 + 537 + static int mtk_dai_dmic_hw_gain_ctrl_put(struct snd_kcontrol *kcontrol, 538 + struct snd_ctl_elem_value *ucontrol) 539 + { 540 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 541 + struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 542 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 543 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 544 + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; 545 + unsigned int source = ucontrol->value.enumerated.item[0]; 546 + unsigned int *cached; 547 + 548 + if (source >= e->items) 549 + return -EINVAL; 550 + 551 + if (!strcmp(kcontrol->id.name, "DMIC1_HW_GAIN_EN")) 552 + cached = &dmic_priv->gain_on[0]; 553 + else if (!strcmp(kcontrol->id.name, "DMIC2_HW_GAIN_EN")) 554 + cached = &dmic_priv->gain_on[1]; 555 + else if (!strcmp(kcontrol->id.name, "DMIC3_HW_GAIN_EN")) 556 + cached = &dmic_priv->gain_on[2]; 557 + else if (!strcmp(kcontrol->id.name, "DMIC4_HW_GAIN_EN")) 558 + cached = &dmic_priv->gain_on[3]; 559 + else 560 + return -EINVAL; 561 + 562 + if (source == *cached) 563 + return 0; 564 + 565 + *cached = source; 566 + return 1; 567 + } 568 + 569 + static int mtk_dai_dmic_hw_gain_ctrl_get(struct snd_kcontrol *kcontrol, 570 + struct snd_ctl_elem_value *ucontrol) 571 + { 572 + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 573 + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); 574 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 575 + struct mtk_dai_dmic_priv *dmic_priv = afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN]; 576 + unsigned int val; 577 + 578 + if (!strcmp(kcontrol->id.name, "DMIC1_HW_GAIN_EN")) 579 + val = dmic_priv->gain_on[0]; 580 + else if (!strcmp(kcontrol->id.name, "DMIC2_HW_GAIN_EN")) 581 + val = dmic_priv->gain_on[1]; 582 + else if (!strcmp(kcontrol->id.name, "DMIC3_HW_GAIN_EN")) 583 + val = dmic_priv->gain_on[2]; 584 + else if (!strcmp(kcontrol->id.name, "DMIC4_HW_GAIN_EN")) 585 + val = dmic_priv->gain_on[3]; 586 + else 587 + return -EINVAL; 588 + 589 + ucontrol->value.enumerated.item[0] = val; 590 + return 0; 591 + } 592 + 593 + static const struct snd_kcontrol_new mtk_dai_dmic_controls[] = { 594 + SOC_ENUM_EXT("DMIC1_HW_GAIN_EN", dmic_gain_on_enum, 595 + mtk_dai_dmic_hw_gain_ctrl_get, 596 + mtk_dai_dmic_hw_gain_ctrl_put), 597 + SOC_ENUM_EXT("DMIC2_HW_GAIN_EN", dmic_gain_on_enum, 598 + mtk_dai_dmic_hw_gain_ctrl_get, 599 + mtk_dai_dmic_hw_gain_ctrl_put), 600 + SOC_ENUM_EXT("DMIC3_HW_GAIN_EN", dmic_gain_on_enum, 601 + mtk_dai_dmic_hw_gain_ctrl_get, 602 + mtk_dai_dmic_hw_gain_ctrl_put), 603 + SOC_ENUM_EXT("DMIC4_HW_GAIN_EN", dmic_gain_on_enum, 604 + mtk_dai_dmic_hw_gain_ctrl_get, 605 + mtk_dai_dmic_hw_gain_ctrl_put), 606 + SOC_SINGLE("DMIC1_HW_GAIN_TARGET", DMIC_GAIN1_CON1, 607 + 0, DMIC_GAIN_MAX_TARGET, 0), 608 + SOC_SINGLE("DMIC2_HW_GAIN_TARGET", DMIC_GAIN2_CON1, 609 + 0, DMIC_GAIN_MAX_TARGET, 0), 610 + SOC_SINGLE("DMIC3_HW_GAIN_TARGET", DMIC_GAIN3_CON1, 611 + 0, DMIC_GAIN_MAX_TARGET, 0), 612 + SOC_SINGLE("DMIC4_HW_GAIN_TARGET", DMIC_GAIN4_CON1, 613 + 0, DMIC_GAIN_MAX_TARGET, 0), 614 + SOC_SINGLE("DMIC1_HW_GAIN_CURRENT", DMIC_GAIN1_CUR, 615 + 0, DMIC_GAIN_MAX_CURRENT, 0), 616 + SOC_SINGLE("DMIC2_HW_GAIN_CURRENT", DMIC_GAIN2_CUR, 617 + 0, DMIC_GAIN_MAX_CURRENT, 0), 618 + SOC_SINGLE("DMIC3_HW_GAIN_CURRENT", DMIC_GAIN3_CUR, 619 + 0, DMIC_GAIN_MAX_CURRENT, 0), 620 + SOC_SINGLE("DMIC4_HW_GAIN_CURRENT", DMIC_GAIN4_CUR, 621 + 0, DMIC_GAIN_MAX_CURRENT, 0), 622 + SOC_SINGLE("DMIC1_HW_GAIN_UP_STEP", DMIC_GAIN1_CON3, 623 + 0, DMIC_GAIN_MAX_STEP, 0), 624 + SOC_SINGLE("DMIC2_HW_GAIN_UP_STEP", DMIC_GAIN2_CON3, 625 + 0, DMIC_GAIN_MAX_STEP, 0), 626 + SOC_SINGLE("DMIC3_HW_GAIN_UP_STEP", DMIC_GAIN3_CON3, 627 + 0, DMIC_GAIN_MAX_STEP, 0), 628 + SOC_SINGLE("DMIC4_HW_GAIN_UP_STEP", DMIC_GAIN4_CON3, 629 + 0, DMIC_GAIN_MAX_STEP, 0), 630 + SOC_SINGLE("DMIC1_HW_GAIN_DOWN_STEP", DMIC_GAIN1_CON2, 631 + 0, DMIC_GAIN_MAX_STEP, 0), 632 + SOC_SINGLE("DMIC2_HW_GAIN_DOWN_STEP", DMIC_GAIN2_CON2, 633 + 0, DMIC_GAIN_MAX_STEP, 0), 634 + SOC_SINGLE("DMIC3_HW_GAIN_DOWN_STEP", DMIC_GAIN3_CON2, 635 + 0, DMIC_GAIN_MAX_STEP, 0), 636 + SOC_SINGLE("DMIC4_HW_GAIN_DOWN_STEP", DMIC_GAIN4_CON2, 637 + 0, DMIC_GAIN_MAX_STEP, 0), 638 + SOC_SINGLE("DMIC1_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN1_CON0, 639 + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), 640 + SOC_SINGLE("DMIC2_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN2_CON0, 641 + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), 642 + SOC_SINGLE("DMIC3_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN3_CON0, 643 + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), 644 + SOC_SINGLE("DMIC4_HW_GAIN_SAMPLE_PER_STEP", DMIC_GAIN4_CON0, 645 + DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT, DMIC_GAIN_MAX_PER_STEP, 0), 646 + }; 647 + 648 + static int init_dmic_priv_data(struct mtk_base_afe *afe) 649 + { 650 + struct mt8188_afe_private *afe_priv = afe->platform_priv; 651 + struct mtk_dai_dmic_priv *dmic_priv; 652 + 653 + dmic_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_dmic_priv), 654 + GFP_KERNEL); 655 + if (!dmic_priv) 656 + return -ENOMEM; 657 + 658 + afe_priv->dai_priv[MT8188_AFE_IO_DMIC_IN] = dmic_priv; 659 + return 0; 660 + } 661 + 662 + int mt8188_dai_dmic_register(struct mtk_base_afe *afe) 663 + { 664 + struct mtk_base_afe_dai *dai; 665 + 666 + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); 667 + if (!dai) 668 + return -ENOMEM; 669 + 670 + list_add(&dai->list, &afe->sub_dais); 671 + 672 + dai->dai_drivers = mtk_dai_dmic_driver; 673 + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_dmic_driver); 674 + dai->dapm_widgets = mtk_dai_dmic_widgets; 675 + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_dmic_widgets); 676 + dai->dapm_routes = mtk_dai_dmic_routes; 677 + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_dmic_routes); 678 + dai->controls = mtk_dai_dmic_controls; 679 + dai->num_controls = ARRAY_SIZE(mtk_dai_dmic_controls); 680 + 681 + return init_dmic_priv_data(afe); 682 + }
+14
sound/soc/mediatek/mt8188/mt8188-mt6359.c
··· 150 150 "mt6359-snd-codec-aif1")), 151 151 DAILINK_COMP_ARRAY(COMP_EMPTY())); 152 152 153 + SND_SOC_DAILINK_DEFS(DMIC_BE, 154 + DAILINK_COMP_ARRAY(COMP_CPU("DMIC")), 155 + DAILINK_COMP_ARRAY(COMP_DUMMY()), 156 + DAILINK_COMP_ARRAY(COMP_EMPTY())); 157 + 153 158 SND_SOC_DAILINK_DEFS(dptx, 154 159 DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), 155 160 DAILINK_COMP_ARRAY(COMP_DUMMY()), ··· 302 297 static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = { 303 298 SND_SOC_DAPM_HP("Headphone", NULL), 304 299 SND_SOC_DAPM_MIC("Headset Mic", NULL), 300 + SND_SOC_DAPM_MIC("AP DMIC", NULL), 305 301 SND_SOC_DAPM_SINK("HDMI"), 306 302 SND_SOC_DAPM_SINK("DP"), 307 303 SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), ··· 539 533 DAI_LINK_UL9_FE, 540 534 DAI_LINK_UL10_FE, 541 535 DAI_LINK_DL_SRC_BE, 536 + DAI_LINK_DMIC_BE, 542 537 DAI_LINK_DPTX_BE, 543 538 DAI_LINK_ETDM1_IN_BE, 544 539 DAI_LINK_ETDM2_IN_BE, ··· 1126 1119 .no_pcm = 1, 1127 1120 .playback_only = 1, 1128 1121 SND_SOC_DAILINK_REG(dl_src), 1122 + }, 1123 + [DAI_LINK_DMIC_BE] = { 1124 + .name = "DMIC_BE", 1125 + .no_pcm = 1, 1126 + .capture_only = 1, 1127 + .ignore_suspend = 1, 1128 + SND_SOC_DAILINK_REG(DMIC_BE), 1129 1129 }, 1130 1130 [DAI_LINK_DPTX_BE] = { 1131 1131 .name = "DPTX_BE",
+15 -2
sound/soc/mediatek/mt8188/mt8188-reg.h
··· 2837 2837 #define PWR2_TOP_CON_DMIC3_SRC_SEL_MASK GENMASK(16, 14) 2838 2838 #define PWR2_TOP_CON_DMIC2_SRC_SEL_MASK GENMASK(13, 11) 2839 2839 #define PWR2_TOP_CON_DMIC1_SRC_SEL_MASK GENMASK(10, 8) 2840 + #define PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(x) ((x) << 29) 2841 + #define PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(x) ((x) << 26) 2842 + #define PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(x) ((x) << 23) 2843 + #define PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(x) ((x) << 20) 2844 + #define PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(x) ((x) << 17) 2845 + #define PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(x) ((x) << 14) 2846 + #define PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(x) ((x) << 11) 2847 + #define PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(x) ((x) << 8) 2840 2848 2841 2849 /* PWR2_TOP_CON1 */ 2842 - #define PWR2_TOP_CON1_DMIC_CKDIV_ON BIT(1) 2850 + #define PWR2_TOP_CON1_DMIC_FIFO_SOFT_RST_EN(x) BIT(5 + 6 * (x)) 2851 + #define PWR2_TOP_CON1_DMIC_CKDIV_ON BIT(1) 2852 + #define PWR2_TOP_CON1_DMIC_CKDIV_ON_SHIFT 1 2853 + 2843 2854 2844 2855 /* PCM_INTF_CON1 */ 2845 2856 #define PCM_INTF_CON1_SYNC_OUT_INV BIT(23) ··· 2932 2921 #define AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL BIT(23) 2933 2922 #define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL BIT(22) 2934 2923 #define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL BIT(21) 2935 - 2924 + #define AFE_DMIC_UL_VOICE_MODE(x) (((x) & GENMASK(2, 0)) << 17) 2936 2925 #define AFE_DMIC_UL_VOICE_MODE_MASK GENMASK(19, 17) 2937 2926 #define AFE_DMIC_UL_CON0_VOCIE_MODE_8K AFE_DMIC_UL_VOICE_MODE(0) 2938 2927 #define AFE_DMIC_UL_CON0_VOCIE_MODE_16K AFE_DMIC_UL_VOICE_MODE(1) 2939 2928 #define AFE_DMIC_UL_CON0_VOCIE_MODE_32K AFE_DMIC_UL_VOICE_MODE(2) 2940 2929 #define AFE_DMIC_UL_CON0_VOCIE_MODE_48K AFE_DMIC_UL_VOICE_MODE(3) 2941 2930 #define AFE_DMIC_UL_CON0_VOCIE_MODE_96K AFE_DMIC_UL_VOICE_MODE(4) 2931 + #define AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(x) (((x) & GENMASK(2, 0)) << 7) 2942 2932 #define AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL_MASK GENMASK(9, 7) 2943 2933 #define AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL BIT(10) 2944 2934 #define AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL BIT(1) ··· 2956 2944 2957 2945 /* DMIC_GAINx_CON0 */ 2958 2946 #define DMIC_GAIN_CON0_GAIN_ON BIT(0) 2947 + #define DMIC_GAIN_CON0_SAMPLE_PER_STEP_SHIFT 8 2959 2948 #define DMIC_GAIN_CON0_SAMPLE_PER_STEP_MASK GENMASK(15, 8) 2960 2949 2961 2950 /* DMIC_GAINx_CON1 */