1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2016, The Linux Foundation. All rights reserved. 3 4 #include <linux/module.h> 5 #include <linux/err.h> 6 #include <linux/kernel.h> 7 #include <linux/delay.h> 8 #include <linux/types.h> 9 #include <linux/clk.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 #include <linux/mfd/syscon.h> 14 #include <sound/soc.h> 15 #include <sound/pcm.h> 16 #include <sound/pcm_params.h> 17 #include <sound/tlv.h> 18 19 #define LPASS_CDC_CLK_RX_RESET_CTL (0x000) 20 #define LPASS_CDC_CLK_TX_RESET_B1_CTL (0x004) 21 #define CLK_RX_RESET_B1_CTL_TX1_RESET_MASK BIT(0) 22 #define CLK_RX_RESET_B1_CTL_TX2_RESET_MASK BIT(1) 23 #define LPASS_CDC_CLK_DMIC_B1_CTL (0x008) 24 #define DMIC_B1_CTL_DMIC0_CLK_SEL_MASK GENMASK(3, 1) 25 #define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV2 (0x0 << 1) 26 #define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3 (0x1 << 1) 27 #define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV4 (0x2 << 1) 28 #define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV6 (0x3 << 1) 29 #define DMIC_B1_CTL_DMIC0_CLK_SEL_DIV16 (0x4 << 1) 30 #define DMIC_B1_CTL_DMIC0_CLK_EN_MASK BIT(0) 31 #define DMIC_B1_CTL_DMIC0_CLK_EN_ENABLE BIT(0) 32 33 #define LPASS_CDC_CLK_RX_I2S_CTL (0x00C) 34 #define RX_I2S_CTL_RX_I2S_MODE_MASK BIT(5) 35 #define RX_I2S_CTL_RX_I2S_MODE_16 BIT(5) 36 #define RX_I2S_CTL_RX_I2S_MODE_32 0 37 #define RX_I2S_CTL_RX_I2S_FS_RATE_MASK GENMASK(2, 0) 38 #define RX_I2S_CTL_RX_I2S_FS_RATE_F_8_KHZ 0x0 39 #define RX_I2S_CTL_RX_I2S_FS_RATE_F_16_KHZ 0x1 40 #define RX_I2S_CTL_RX_I2S_FS_RATE_F_32_KHZ 0x2 41 #define RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ 0x3 42 #define RX_I2S_CTL_RX_I2S_FS_RATE_F_96_KHZ 0x4 43 #define RX_I2S_CTL_RX_I2S_FS_RATE_F_192_KHZ 0x5 44 #define LPASS_CDC_CLK_TX_I2S_CTL (0x010) 45 #define TX_I2S_CTL_TX_I2S_MODE_MASK BIT(5) 46 #define TX_I2S_CTL_TX_I2S_MODE_16 BIT(5) 47 #define TX_I2S_CTL_TX_I2S_MODE_32 0 48 #define TX_I2S_CTL_TX_I2S_FS_RATE_MASK GENMASK(2, 0) 49 #define TX_I2S_CTL_TX_I2S_FS_RATE_F_8_KHZ 0x0 50 #define TX_I2S_CTL_TX_I2S_FS_RATE_F_16_KHZ 0x1 51 #define TX_I2S_CTL_TX_I2S_FS_RATE_F_32_KHZ 0x2 52 #define TX_I2S_CTL_TX_I2S_FS_RATE_F_48_KHZ 0x3 53 #define TX_I2S_CTL_TX_I2S_FS_RATE_F_96_KHZ 0x4 54 #define TX_I2S_CTL_TX_I2S_FS_RATE_F_192_KHZ 0x5 55 56 #define LPASS_CDC_CLK_OTHR_RESET_B1_CTL (0x014) 57 #define LPASS_CDC_CLK_TX_CLK_EN_B1_CTL (0x018) 58 #define LPASS_CDC_CLK_OTHR_CTL (0x01C) 59 #define LPASS_CDC_CLK_RX_B1_CTL (0x020) 60 #define LPASS_CDC_CLK_MCLK_CTL (0x024) 61 #define MCLK_CTL_MCLK_EN_MASK BIT(0) 62 #define MCLK_CTL_MCLK_EN_ENABLE BIT(0) 63 #define MCLK_CTL_MCLK_EN_DISABLE 0 64 #define LPASS_CDC_CLK_PDM_CTL (0x028) 65 #define LPASS_CDC_CLK_PDM_CTL_PDM_EN_MASK BIT(0) 66 #define LPASS_CDC_CLK_PDM_CTL_PDM_EN BIT(0) 67 #define LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK BIT(1) 68 #define LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB BIT(1) 69 #define LPASS_CDC_CLK_PDM_CTL_PDM_CLK_PDM_CLK 0 70 71 #define LPASS_CDC_CLK_SD_CTL (0x02C) 72 #define LPASS_CDC_RX1_B1_CTL (0x040) 73 #define LPASS_CDC_RX2_B1_CTL (0x060) 74 #define LPASS_CDC_RX3_B1_CTL (0x080) 75 #define LPASS_CDC_RX1_B2_CTL (0x044) 76 #define LPASS_CDC_RX2_B2_CTL (0x064) 77 #define LPASS_CDC_RX3_B2_CTL (0x084) 78 #define LPASS_CDC_RX1_B3_CTL (0x048) 79 #define LPASS_CDC_RX2_B3_CTL (0x068) 80 #define LPASS_CDC_RX3_B3_CTL (0x088) 81 #define LPASS_CDC_RX1_B4_CTL (0x04C) 82 #define LPASS_CDC_RX2_B4_CTL (0x06C) 83 #define LPASS_CDC_RX3_B4_CTL (0x08C) 84 #define LPASS_CDC_RX1_B5_CTL (0x050) 85 #define LPASS_CDC_RX2_B5_CTL (0x070) 86 #define LPASS_CDC_RX3_B5_CTL (0x090) 87 #define LPASS_CDC_RX1_B6_CTL (0x054) 88 #define RXn_B6_CTL_MUTE_MASK BIT(0) 89 #define RXn_B6_CTL_MUTE_ENABLE BIT(0) 90 #define RXn_B6_CTL_MUTE_DISABLE 0 91 #define LPASS_CDC_RX2_B6_CTL (0x074) 92 #define LPASS_CDC_RX3_B6_CTL (0x094) 93 #define LPASS_CDC_RX1_VOL_CTL_B1_CTL (0x058) 94 #define LPASS_CDC_RX2_VOL_CTL_B1_CTL (0x078) 95 #define LPASS_CDC_RX3_VOL_CTL_B1_CTL (0x098) 96 #define LPASS_CDC_RX1_VOL_CTL_B2_CTL (0x05C) 97 #define LPASS_CDC_RX2_VOL_CTL_B2_CTL (0x07C) 98 #define LPASS_CDC_RX3_VOL_CTL_B2_CTL (0x09C) 99 #define LPASS_CDC_TOP_GAIN_UPDATE (0x0A0) 100 #define LPASS_CDC_TOP_CTL (0x0A4) 101 #define TOP_CTL_DIG_MCLK_FREQ_MASK BIT(0) 102 #define TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ 0 103 #define TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ BIT(0) 104 105 #define LPASS_CDC_DEBUG_DESER1_CTL (0x0E0) 106 #define LPASS_CDC_DEBUG_DESER2_CTL (0x0E4) 107 #define LPASS_CDC_DEBUG_B1_CTL_CFG (0x0E8) 108 #define LPASS_CDC_DEBUG_B2_CTL_CFG (0x0EC) 109 #define LPASS_CDC_DEBUG_B3_CTL_CFG (0x0F0) 110 #define LPASS_CDC_IIR1_GAIN_B1_CTL (0x100) 111 #define LPASS_CDC_IIR2_GAIN_B1_CTL (0x140) 112 #define LPASS_CDC_IIR1_GAIN_B2_CTL (0x104) 113 #define LPASS_CDC_IIR2_GAIN_B2_CTL (0x144) 114 #define LPASS_CDC_IIR1_GAIN_B3_CTL (0x108) 115 #define LPASS_CDC_IIR2_GAIN_B3_CTL (0x148) 116 #define LPASS_CDC_IIR1_GAIN_B4_CTL (0x10C) 117 #define LPASS_CDC_IIR2_GAIN_B4_CTL (0x14C) 118 #define LPASS_CDC_IIR1_GAIN_B5_CTL (0x110) 119 #define LPASS_CDC_IIR2_GAIN_B5_CTL (0x150) 120 #define LPASS_CDC_IIR1_GAIN_B6_CTL (0x114) 121 #define LPASS_CDC_IIR2_GAIN_B6_CTL (0x154) 122 #define LPASS_CDC_IIR1_GAIN_B7_CTL (0x118) 123 #define LPASS_CDC_IIR2_GAIN_B7_CTL (0x158) 124 #define LPASS_CDC_IIR1_GAIN_B8_CTL (0x11C) 125 #define LPASS_CDC_IIR2_GAIN_B8_CTL (0x15C) 126 #define LPASS_CDC_IIR1_CTL (0x120) 127 #define LPASS_CDC_IIR2_CTL (0x160) 128 #define LPASS_CDC_IIR1_GAIN_TIMER_CTL (0x124) 129 #define LPASS_CDC_IIR2_GAIN_TIMER_CTL (0x164) 130 #define LPASS_CDC_IIR1_COEF_B1_CTL (0x128) 131 #define LPASS_CDC_IIR2_COEF_B1_CTL (0x168) 132 #define LPASS_CDC_IIR1_COEF_B2_CTL (0x12C) 133 #define LPASS_CDC_IIR2_COEF_B2_CTL (0x16C) 134 #define LPASS_CDC_CONN_RX1_B1_CTL (0x180) 135 #define LPASS_CDC_CONN_RX1_B2_CTL (0x184) 136 #define LPASS_CDC_CONN_RX1_B3_CTL (0x188) 137 #define LPASS_CDC_CONN_RX2_B1_CTL (0x18C) 138 #define LPASS_CDC_CONN_RX2_B2_CTL (0x190) 139 #define LPASS_CDC_CONN_RX2_B3_CTL (0x194) 140 #define LPASS_CDC_CONN_RX3_B1_CTL (0x198) 141 #define LPASS_CDC_CONN_RX3_B2_CTL (0x19C) 142 #define LPASS_CDC_CONN_TX_B1_CTL (0x1A0) 143 #define LPASS_CDC_CONN_EQ1_B1_CTL (0x1A8) 144 #define LPASS_CDC_CONN_EQ1_B2_CTL (0x1AC) 145 #define LPASS_CDC_CONN_EQ1_B3_CTL (0x1B0) 146 #define LPASS_CDC_CONN_EQ1_B4_CTL (0x1B4) 147 #define LPASS_CDC_CONN_EQ2_B1_CTL (0x1B8) 148 #define LPASS_CDC_CONN_EQ2_B2_CTL (0x1BC) 149 #define LPASS_CDC_CONN_EQ2_B3_CTL (0x1C0) 150 #define LPASS_CDC_CONN_EQ2_B4_CTL (0x1C4) 151 #define LPASS_CDC_CONN_TX_I2S_SD1_CTL (0x1C8) 152 #define LPASS_CDC_TX1_VOL_CTL_TIMER (0x280) 153 #define LPASS_CDC_TX2_VOL_CTL_TIMER (0x2A0) 154 #define LPASS_CDC_TX1_VOL_CTL_GAIN (0x284) 155 #define LPASS_CDC_TX2_VOL_CTL_GAIN (0x2A4) 156 #define LPASS_CDC_TX1_VOL_CTL_CFG (0x288) 157 #define TX_VOL_CTL_CFG_MUTE_EN_MASK BIT(0) 158 #define TX_VOL_CTL_CFG_MUTE_EN_ENABLE BIT(0) 159 160 #define LPASS_CDC_TX2_VOL_CTL_CFG (0x2A8) 161 #define LPASS_CDC_TX1_MUX_CTL (0x28C) 162 #define TX_MUX_CTL_CUT_OFF_FREQ_MASK GENMASK(5, 4) 163 #define TX_MUX_CTL_CUT_OFF_FREQ_SHIFT 4 164 #define TX_MUX_CTL_CF_NEG_3DB_4HZ (0x0 << 4) 165 #define TX_MUX_CTL_CF_NEG_3DB_75HZ (0x1 << 4) 166 #define TX_MUX_CTL_CF_NEG_3DB_150HZ (0x2 << 4) 167 #define TX_MUX_CTL_HPF_BP_SEL_MASK BIT(3) 168 #define TX_MUX_CTL_HPF_BP_SEL_BYPASS BIT(3) 169 #define TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS 0 170 171 #define LPASS_CDC_TX2_MUX_CTL (0x2AC) 172 #define LPASS_CDC_TX1_CLK_FS_CTL (0x290) 173 #define LPASS_CDC_TX2_CLK_FS_CTL (0x2B0) 174 #define LPASS_CDC_TX1_DMIC_CTL (0x294) 175 #define LPASS_CDC_TX2_DMIC_CTL (0x2B4) 176 #define TXN_DMIC_CTL_CLK_SEL_MASK GENMASK(2, 0) 177 #define TXN_DMIC_CTL_CLK_SEL_DIV2 0x0 178 #define TXN_DMIC_CTL_CLK_SEL_DIV3 0x1 179 #define TXN_DMIC_CTL_CLK_SEL_DIV4 0x2 180 #define TXN_DMIC_CTL_CLK_SEL_DIV6 0x3 181 #define TXN_DMIC_CTL_CLK_SEL_DIV16 0x4 182 183 #define MSM8916_WCD_DIGITAL_RATES (SNDRV_PCM_RATE_8000 | \ 184 SNDRV_PCM_RATE_16000 | \ 185 SNDRV_PCM_RATE_32000 | \ 186 SNDRV_PCM_RATE_48000) 187 #define MSM8916_WCD_DIGITAL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 188 SNDRV_PCM_FMTBIT_S32_LE) 189 190 struct msm8916_wcd_digital_priv { 191 struct clk *ahbclk, *mclk; 192 }; 193 194 static const unsigned long rx_gain_reg[] = { 195 LPASS_CDC_RX1_VOL_CTL_B2_CTL, 196 LPASS_CDC_RX2_VOL_CTL_B2_CTL, 197 LPASS_CDC_RX3_VOL_CTL_B2_CTL, 198 }; 199 200 static const unsigned long tx_gain_reg[] = { 201 LPASS_CDC_TX1_VOL_CTL_GAIN, 202 LPASS_CDC_TX2_VOL_CTL_GAIN, 203 }; 204 205 static const char *const rx_mix1_text[] = { 206 "ZERO", "IIR1", "IIR2", "RX1", "RX2", "RX3" 207 }; 208 209 static const char *const dec_mux_text[] = { 210 "ZERO", "ADC1", "ADC2", "ADC3", "DMIC1", "DMIC2" 211 }; 212 213 static const char *const cic_mux_text[] = { "AMIC", "DMIC" }; 214 215 /* RX1 MIX1 */ 216 static const struct soc_enum rx_mix1_inp_enum[] = { 217 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B1_CTL, 0, 6, rx_mix1_text), 218 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B1_CTL, 3, 6, rx_mix1_text), 219 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX1_B2_CTL, 0, 6, rx_mix1_text), 220 }; 221 222 /* RX2 MIX1 */ 223 static const struct soc_enum rx2_mix1_inp_enum[] = { 224 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 0, 6, rx_mix1_text), 225 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B1_CTL, 3, 6, rx_mix1_text), 226 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX2_B2_CTL, 0, 6, rx_mix1_text), 227 }; 228 229 /* RX3 MIX1 */ 230 static const struct soc_enum rx3_mix1_inp_enum[] = { 231 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 0, 6, rx_mix1_text), 232 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B1_CTL, 3, 6, rx_mix1_text), 233 SOC_ENUM_SINGLE(LPASS_CDC_CONN_RX3_B2_CTL, 0, 6, rx_mix1_text), 234 }; 235 236 /* DEC */ 237 static const struct soc_enum dec1_mux_enum = SOC_ENUM_SINGLE( 238 LPASS_CDC_CONN_TX_B1_CTL, 0, 6, dec_mux_text); 239 static const struct soc_enum dec2_mux_enum = SOC_ENUM_SINGLE( 240 LPASS_CDC_CONN_TX_B1_CTL, 3, 6, dec_mux_text); 241 242 /* CIC */ 243 static const struct soc_enum cic1_mux_enum = SOC_ENUM_SINGLE( 244 LPASS_CDC_TX1_MUX_CTL, 0, 2, cic_mux_text); 245 static const struct soc_enum cic2_mux_enum = SOC_ENUM_SINGLE( 246 LPASS_CDC_TX2_MUX_CTL, 0, 2, cic_mux_text); 247 248 /* RDAC2 MUX */ 249 static const struct snd_kcontrol_new dec1_mux = SOC_DAPM_ENUM( 250 "DEC1 MUX Mux", dec1_mux_enum); 251 static const struct snd_kcontrol_new dec2_mux = SOC_DAPM_ENUM( 252 "DEC2 MUX Mux", dec2_mux_enum); 253 static const struct snd_kcontrol_new cic1_mux = SOC_DAPM_ENUM( 254 "CIC1 MUX Mux", cic1_mux_enum); 255 static const struct snd_kcontrol_new cic2_mux = SOC_DAPM_ENUM( 256 "CIC2 MUX Mux", cic2_mux_enum); 257 static const struct snd_kcontrol_new rx_mix1_inp1_mux = SOC_DAPM_ENUM( 258 "RX1 MIX1 INP1 Mux", rx_mix1_inp_enum[0]); 259 static const struct snd_kcontrol_new rx_mix1_inp2_mux = SOC_DAPM_ENUM( 260 "RX1 MIX1 INP2 Mux", rx_mix1_inp_enum[1]); 261 static const struct snd_kcontrol_new rx_mix1_inp3_mux = SOC_DAPM_ENUM( 262 "RX1 MIX1 INP3 Mux", rx_mix1_inp_enum[2]); 263 static const struct snd_kcontrol_new rx2_mix1_inp1_mux = SOC_DAPM_ENUM( 264 "RX2 MIX1 INP1 Mux", rx2_mix1_inp_enum[0]); 265 static const struct snd_kcontrol_new rx2_mix1_inp2_mux = SOC_DAPM_ENUM( 266 "RX2 MIX1 INP2 Mux", rx2_mix1_inp_enum[1]); 267 static const struct snd_kcontrol_new rx2_mix1_inp3_mux = SOC_DAPM_ENUM( 268 "RX2 MIX1 INP3 Mux", rx2_mix1_inp_enum[2]); 269 static const struct snd_kcontrol_new rx3_mix1_inp1_mux = SOC_DAPM_ENUM( 270 "RX3 MIX1 INP1 Mux", rx3_mix1_inp_enum[0]); 271 static const struct snd_kcontrol_new rx3_mix1_inp2_mux = SOC_DAPM_ENUM( 272 "RX3 MIX1 INP2 Mux", rx3_mix1_inp_enum[1]); 273 static const struct snd_kcontrol_new rx3_mix1_inp3_mux = SOC_DAPM_ENUM( 274 "RX3 MIX1 INP3 Mux", rx3_mix1_inp_enum[2]); 275 276 /* Digital Gain control -38.4 dB to +38.4 dB in 0.3 dB steps */ 277 static const DECLARE_TLV_DB_SCALE(digital_gain, -3840, 30, 0); 278 279 /* Cutoff Freq for High Pass Filter at -3dB */ 280 static const char * const hpf_cutoff_text[] = { 281 "4Hz", "75Hz", "150Hz", 282 }; 283 284 static SOC_ENUM_SINGLE_DECL(tx1_hpf_cutoff_enum, LPASS_CDC_TX1_MUX_CTL, 4, 285 hpf_cutoff_text); 286 static SOC_ENUM_SINGLE_DECL(tx2_hpf_cutoff_enum, LPASS_CDC_TX2_MUX_CTL, 4, 287 hpf_cutoff_text); 288 289 /* cut off for dc blocker inside rx chain */ 290 static const char * const dc_blocker_cutoff_text[] = { 291 "4Hz", "75Hz", "150Hz", 292 }; 293 294 static SOC_ENUM_SINGLE_DECL(rx1_dcb_cutoff_enum, LPASS_CDC_RX1_B4_CTL, 0, 295 dc_blocker_cutoff_text); 296 static SOC_ENUM_SINGLE_DECL(rx2_dcb_cutoff_enum, LPASS_CDC_RX2_B4_CTL, 0, 297 dc_blocker_cutoff_text); 298 static SOC_ENUM_SINGLE_DECL(rx3_dcb_cutoff_enum, LPASS_CDC_RX3_B4_CTL, 0, 299 dc_blocker_cutoff_text); 300 301 static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = { 302 SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL, 303 -128, 127, digital_gain), 304 SOC_SINGLE_S8_TLV("RX2 Digital Volume", LPASS_CDC_RX2_VOL_CTL_B2_CTL, 305 -128, 127, digital_gain), 306 SOC_SINGLE_S8_TLV("RX3 Digital Volume", LPASS_CDC_RX3_VOL_CTL_B2_CTL, 307 -128, 127, digital_gain), 308 SOC_SINGLE_S8_TLV("TX1 Digital Volume", LPASS_CDC_TX1_VOL_CTL_GAIN, 309 -128, 127, digital_gain), 310 SOC_SINGLE_S8_TLV("TX2 Digital Volume", LPASS_CDC_TX2_VOL_CTL_GAIN, 311 -128, 127, digital_gain), 312 SOC_ENUM("TX1 HPF Cutoff", tx1_hpf_cutoff_enum), 313 SOC_ENUM("TX2 HPF Cutoff", tx2_hpf_cutoff_enum), 314 SOC_SINGLE("TX1 HPF Switch", LPASS_CDC_TX1_MUX_CTL, 3, 1, 0), 315 SOC_SINGLE("TX2 HPF Switch", LPASS_CDC_TX2_MUX_CTL, 3, 1, 0), 316 SOC_ENUM("RX1 DCB Cutoff", rx1_dcb_cutoff_enum), 317 SOC_ENUM("RX2 DCB Cutoff", rx2_dcb_cutoff_enum), 318 SOC_ENUM("RX3 DCB Cutoff", rx3_dcb_cutoff_enum), 319 SOC_SINGLE("RX1 DCB Switch", LPASS_CDC_RX1_B5_CTL, 2, 1, 0), 320 SOC_SINGLE("RX2 DCB Switch", LPASS_CDC_RX2_B5_CTL, 2, 1, 0), 321 SOC_SINGLE("RX3 DCB Switch", LPASS_CDC_RX3_B5_CTL, 2, 1, 0), 322 SOC_SINGLE("RX1 Mute Switch", LPASS_CDC_RX1_B6_CTL, 0, 1, 0), 323 SOC_SINGLE("RX2 Mute Switch", LPASS_CDC_RX2_B6_CTL, 0, 1, 0), 324 SOC_SINGLE("RX3 Mute Switch", LPASS_CDC_RX3_B6_CTL, 0, 1, 0), 325 }; 326 327 static int msm8916_wcd_digital_enable_interpolator( 328 struct snd_soc_dapm_widget *w, 329 struct snd_kcontrol *kcontrol, 330 int event) 331 { 332 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 333 334 switch (event) { 335 case SND_SOC_DAPM_POST_PMU: 336 /* apply the digital gain after the interpolator is enabled */ 337 usleep_range(10000, 10100); 338 snd_soc_component_write(component, rx_gain_reg[w->shift], 339 snd_soc_component_read32(component, rx_gain_reg[w->shift])); 340 break; 341 } 342 return 0; 343 } 344 345 static int msm8916_wcd_digital_enable_dec(struct snd_soc_dapm_widget *w, 346 struct snd_kcontrol *kcontrol, 347 int event) 348 { 349 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 350 unsigned int decimator = w->shift + 1; 351 u16 dec_reset_reg, tx_vol_ctl_reg, tx_mux_ctl_reg; 352 u8 dec_hpf_cut_of_freq; 353 354 dec_reset_reg = LPASS_CDC_CLK_TX_RESET_B1_CTL; 355 tx_vol_ctl_reg = LPASS_CDC_TX1_VOL_CTL_CFG + 32 * (decimator - 1); 356 tx_mux_ctl_reg = LPASS_CDC_TX1_MUX_CTL + 32 * (decimator - 1); 357 358 switch (event) { 359 case SND_SOC_DAPM_PRE_PMU: 360 /* Enable TX digital mute */ 361 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 362 TX_VOL_CTL_CFG_MUTE_EN_MASK, 363 TX_VOL_CTL_CFG_MUTE_EN_ENABLE); 364 dec_hpf_cut_of_freq = snd_soc_component_read32(component, tx_mux_ctl_reg) & 365 TX_MUX_CTL_CUT_OFF_FREQ_MASK; 366 dec_hpf_cut_of_freq >>= TX_MUX_CTL_CUT_OFF_FREQ_SHIFT; 367 if (dec_hpf_cut_of_freq != TX_MUX_CTL_CF_NEG_3DB_150HZ) { 368 /* set cut of freq to CF_MIN_3DB_150HZ (0x1) */ 369 snd_soc_component_update_bits(component, tx_mux_ctl_reg, 370 TX_MUX_CTL_CUT_OFF_FREQ_MASK, 371 TX_MUX_CTL_CF_NEG_3DB_150HZ); 372 } 373 break; 374 case SND_SOC_DAPM_POST_PMU: 375 /* enable HPF */ 376 snd_soc_component_update_bits(component, tx_mux_ctl_reg, 377 TX_MUX_CTL_HPF_BP_SEL_MASK, 378 TX_MUX_CTL_HPF_BP_SEL_NO_BYPASS); 379 /* apply the digital gain after the decimator is enabled */ 380 snd_soc_component_write(component, tx_gain_reg[w->shift], 381 snd_soc_component_read32(component, tx_gain_reg[w->shift])); 382 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 383 TX_VOL_CTL_CFG_MUTE_EN_MASK, 0); 384 break; 385 case SND_SOC_DAPM_PRE_PMD: 386 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 387 TX_VOL_CTL_CFG_MUTE_EN_MASK, 388 TX_VOL_CTL_CFG_MUTE_EN_ENABLE); 389 snd_soc_component_update_bits(component, tx_mux_ctl_reg, 390 TX_MUX_CTL_HPF_BP_SEL_MASK, 391 TX_MUX_CTL_HPF_BP_SEL_BYPASS); 392 break; 393 case SND_SOC_DAPM_POST_PMD: 394 snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift, 395 1 << w->shift); 396 snd_soc_component_update_bits(component, dec_reset_reg, 1 << w->shift, 0x0); 397 snd_soc_component_update_bits(component, tx_mux_ctl_reg, 398 TX_MUX_CTL_HPF_BP_SEL_MASK, 399 TX_MUX_CTL_HPF_BP_SEL_BYPASS); 400 snd_soc_component_update_bits(component, tx_vol_ctl_reg, 401 TX_VOL_CTL_CFG_MUTE_EN_MASK, 0); 402 break; 403 } 404 405 return 0; 406 } 407 408 static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w, 409 struct snd_kcontrol *kcontrol, 410 int event) 411 { 412 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 413 unsigned int dmic; 414 int ret; 415 /* get dmic number out of widget name */ 416 char *dmic_num = strpbrk(w->name, "12"); 417 418 if (dmic_num == NULL) { 419 dev_err(component->dev, "Invalid DMIC\n"); 420 return -EINVAL; 421 } 422 ret = kstrtouint(dmic_num, 10, &dmic); 423 if (ret < 0 || dmic > 2) { 424 dev_err(component->dev, "Invalid DMIC line on the component\n"); 425 return -EINVAL; 426 } 427 428 switch (event) { 429 case SND_SOC_DAPM_PRE_PMU: 430 snd_soc_component_update_bits(component, LPASS_CDC_CLK_DMIC_B1_CTL, 431 DMIC_B1_CTL_DMIC0_CLK_SEL_MASK, 432 DMIC_B1_CTL_DMIC0_CLK_SEL_DIV3); 433 switch (dmic) { 434 case 1: 435 snd_soc_component_update_bits(component, LPASS_CDC_TX1_DMIC_CTL, 436 TXN_DMIC_CTL_CLK_SEL_MASK, 437 TXN_DMIC_CTL_CLK_SEL_DIV3); 438 break; 439 case 2: 440 snd_soc_component_update_bits(component, LPASS_CDC_TX2_DMIC_CTL, 441 TXN_DMIC_CTL_CLK_SEL_MASK, 442 TXN_DMIC_CTL_CLK_SEL_DIV3); 443 break; 444 } 445 break; 446 } 447 448 return 0; 449 } 450 451 static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = { 452 /*RX stuff */ 453 SND_SOC_DAPM_AIF_IN("I2S RX1", NULL, 0, SND_SOC_NOPM, 0, 0), 454 SND_SOC_DAPM_AIF_IN("I2S RX2", NULL, 0, SND_SOC_NOPM, 0, 0), 455 SND_SOC_DAPM_AIF_IN("I2S RX3", NULL, 0, SND_SOC_NOPM, 0, 0), 456 457 SND_SOC_DAPM_OUTPUT("PDM_RX1"), 458 SND_SOC_DAPM_OUTPUT("PDM_RX2"), 459 SND_SOC_DAPM_OUTPUT("PDM_RX3"), 460 461 SND_SOC_DAPM_INPUT("LPASS_PDM_TX"), 462 463 SND_SOC_DAPM_MIXER("RX1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 464 SND_SOC_DAPM_MIXER("RX2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 465 SND_SOC_DAPM_MIXER("RX3 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 466 467 /* Interpolator */ 468 SND_SOC_DAPM_MIXER_E("RX1 INT", LPASS_CDC_CLK_RX_B1_CTL, 0, 0, NULL, 469 0, msm8916_wcd_digital_enable_interpolator, 470 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 471 SND_SOC_DAPM_MIXER_E("RX2 INT", LPASS_CDC_CLK_RX_B1_CTL, 1, 0, NULL, 472 0, msm8916_wcd_digital_enable_interpolator, 473 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 474 SND_SOC_DAPM_MIXER_E("RX3 INT", LPASS_CDC_CLK_RX_B1_CTL, 2, 0, NULL, 475 0, msm8916_wcd_digital_enable_interpolator, 476 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 477 SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 478 &rx_mix1_inp1_mux), 479 SND_SOC_DAPM_MUX("RX1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 480 &rx_mix1_inp2_mux), 481 SND_SOC_DAPM_MUX("RX1 MIX1 INP3", SND_SOC_NOPM, 0, 0, 482 &rx_mix1_inp3_mux), 483 SND_SOC_DAPM_MUX("RX2 MIX1 INP1", SND_SOC_NOPM, 0, 0, 484 &rx2_mix1_inp1_mux), 485 SND_SOC_DAPM_MUX("RX2 MIX1 INP2", SND_SOC_NOPM, 0, 0, 486 &rx2_mix1_inp2_mux), 487 SND_SOC_DAPM_MUX("RX2 MIX1 INP3", SND_SOC_NOPM, 0, 0, 488 &rx2_mix1_inp3_mux), 489 SND_SOC_DAPM_MUX("RX3 MIX1 INP1", SND_SOC_NOPM, 0, 0, 490 &rx3_mix1_inp1_mux), 491 SND_SOC_DAPM_MUX("RX3 MIX1 INP2", SND_SOC_NOPM, 0, 0, 492 &rx3_mix1_inp2_mux), 493 SND_SOC_DAPM_MUX("RX3 MIX1 INP3", SND_SOC_NOPM, 0, 0, 494 &rx3_mix1_inp3_mux), 495 496 SND_SOC_DAPM_MUX("CIC1 MUX", SND_SOC_NOPM, 0, 0, &cic1_mux), 497 SND_SOC_DAPM_MUX("CIC2 MUX", SND_SOC_NOPM, 0, 0, &cic2_mux), 498 /* TX */ 499 SND_SOC_DAPM_MIXER("ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), 500 SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), 501 SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0), 502 503 SND_SOC_DAPM_MUX_E("DEC1 MUX", LPASS_CDC_CLK_TX_CLK_EN_B1_CTL, 0, 0, 504 &dec1_mux, msm8916_wcd_digital_enable_dec, 505 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 506 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 507 SND_SOC_DAPM_MUX_E("DEC2 MUX", LPASS_CDC_CLK_TX_CLK_EN_B1_CTL, 1, 0, 508 &dec2_mux, msm8916_wcd_digital_enable_dec, 509 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 510 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 511 SND_SOC_DAPM_AIF_OUT("I2S TX1", NULL, 0, SND_SOC_NOPM, 0, 0), 512 SND_SOC_DAPM_AIF_OUT("I2S TX2", NULL, 0, SND_SOC_NOPM, 0, 0), 513 SND_SOC_DAPM_AIF_OUT("I2S TX3", NULL, 0, SND_SOC_NOPM, 0, 0), 514 515 /* Digital Mic Inputs */ 516 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, 517 msm8916_wcd_digital_enable_dmic, 518 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 519 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, 520 msm8916_wcd_digital_enable_dmic, 521 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 522 SND_SOC_DAPM_SUPPLY("DMIC_CLK", LPASS_CDC_CLK_DMIC_B1_CTL, 0, 0, 523 NULL, 0), 524 SND_SOC_DAPM_SUPPLY("RX_I2S_CLK", LPASS_CDC_CLK_RX_I2S_CTL, 525 4, 0, NULL, 0), 526 SND_SOC_DAPM_SUPPLY("TX_I2S_CLK", LPASS_CDC_CLK_TX_I2S_CTL, 4, 0, 527 NULL, 0), 528 529 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, NULL, 0), 530 SND_SOC_DAPM_SUPPLY("PDM_CLK", LPASS_CDC_CLK_PDM_CTL, 0, 0, NULL, 0), 531 /* Connectivity Clock */ 532 SND_SOC_DAPM_SUPPLY_S("CDC_CONN", -2, LPASS_CDC_CLK_OTHR_CTL, 2, 0, 533 NULL, 0), 534 SND_SOC_DAPM_MIC("Digital Mic1", NULL), 535 SND_SOC_DAPM_MIC("Digital Mic2", NULL), 536 537 }; 538 539 static int msm8916_wcd_digital_get_clks(struct platform_device *pdev, 540 struct msm8916_wcd_digital_priv *priv) 541 { 542 struct device *dev = &pdev->dev; 543 544 priv->ahbclk = devm_clk_get(dev, "ahbix-clk"); 545 if (IS_ERR(priv->ahbclk)) { 546 dev_err(dev, "failed to get ahbix clk\n"); 547 return PTR_ERR(priv->ahbclk); 548 } 549 550 priv->mclk = devm_clk_get(dev, "mclk"); 551 if (IS_ERR(priv->mclk)) { 552 dev_err(dev, "failed to get mclk\n"); 553 return PTR_ERR(priv->mclk); 554 } 555 556 return 0; 557 } 558 559 static int msm8916_wcd_digital_component_probe(struct snd_soc_component *component) 560 { 561 struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(component->dev); 562 563 snd_soc_component_set_drvdata(component, priv); 564 565 return 0; 566 } 567 568 static int msm8916_wcd_digital_component_set_sysclk(struct snd_soc_component *component, 569 int clk_id, int source, 570 unsigned int freq, int dir) 571 { 572 struct msm8916_wcd_digital_priv *p = dev_get_drvdata(component->dev); 573 574 return clk_set_rate(p->mclk, freq); 575 } 576 577 static int msm8916_wcd_digital_hw_params(struct snd_pcm_substream *substream, 578 struct snd_pcm_hw_params *params, 579 struct snd_soc_dai *dai) 580 { 581 u8 tx_fs_rate; 582 u8 rx_fs_rate; 583 584 switch (params_rate(params)) { 585 case 8000: 586 tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_8_KHZ; 587 rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_8_KHZ; 588 break; 589 case 16000: 590 tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_16_KHZ; 591 rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_16_KHZ; 592 break; 593 case 32000: 594 tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_32_KHZ; 595 rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_32_KHZ; 596 break; 597 case 48000: 598 tx_fs_rate = TX_I2S_CTL_TX_I2S_FS_RATE_F_48_KHZ; 599 rx_fs_rate = RX_I2S_CTL_RX_I2S_FS_RATE_F_48_KHZ; 600 break; 601 default: 602 dev_err(dai->component->dev, "Invalid sampling rate %d\n", 603 params_rate(params)); 604 return -EINVAL; 605 } 606 607 switch (substream->stream) { 608 case SNDRV_PCM_STREAM_CAPTURE: 609 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL, 610 TX_I2S_CTL_TX_I2S_FS_RATE_MASK, tx_fs_rate); 611 break; 612 case SNDRV_PCM_STREAM_PLAYBACK: 613 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL, 614 RX_I2S_CTL_RX_I2S_FS_RATE_MASK, rx_fs_rate); 615 break; 616 default: 617 return -EINVAL; 618 } 619 620 switch (params_format(params)) { 621 case SNDRV_PCM_FORMAT_S16_LE: 622 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL, 623 TX_I2S_CTL_TX_I2S_MODE_MASK, 624 TX_I2S_CTL_TX_I2S_MODE_16); 625 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL, 626 RX_I2S_CTL_RX_I2S_MODE_MASK, 627 RX_I2S_CTL_RX_I2S_MODE_16); 628 break; 629 630 case SNDRV_PCM_FORMAT_S32_LE: 631 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_TX_I2S_CTL, 632 TX_I2S_CTL_TX_I2S_MODE_MASK, 633 TX_I2S_CTL_TX_I2S_MODE_32); 634 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_RX_I2S_CTL, 635 RX_I2S_CTL_RX_I2S_MODE_MASK, 636 RX_I2S_CTL_RX_I2S_MODE_32); 637 break; 638 default: 639 dev_err(dai->dev, "%s: wrong format selected\n", __func__); 640 return -EINVAL; 641 } 642 643 return 0; 644 } 645 646 static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = { 647 648 {"I2S RX1", NULL, "AIF1 Playback"}, 649 {"I2S RX2", NULL, "AIF1 Playback"}, 650 {"I2S RX3", NULL, "AIF1 Playback"}, 651 652 {"AIF1 Capture", NULL, "I2S TX1"}, 653 {"AIF1 Capture", NULL, "I2S TX2"}, 654 {"AIF1 Capture", NULL, "I2S TX3"}, 655 656 {"CIC1 MUX", "DMIC", "DEC1 MUX"}, 657 {"CIC1 MUX", "AMIC", "DEC1 MUX"}, 658 {"CIC2 MUX", "DMIC", "DEC2 MUX"}, 659 {"CIC2 MUX", "AMIC", "DEC2 MUX"}, 660 661 /* Decimator Inputs */ 662 {"DEC1 MUX", "DMIC1", "DMIC1"}, 663 {"DEC1 MUX", "DMIC2", "DMIC2"}, 664 {"DEC1 MUX", "ADC1", "ADC1"}, 665 {"DEC1 MUX", "ADC2", "ADC2"}, 666 {"DEC1 MUX", "ADC3", "ADC3"}, 667 {"DEC1 MUX", NULL, "CDC_CONN"}, 668 669 {"DEC2 MUX", "DMIC1", "DMIC1"}, 670 {"DEC2 MUX", "DMIC2", "DMIC2"}, 671 {"DEC2 MUX", "ADC1", "ADC1"}, 672 {"DEC2 MUX", "ADC2", "ADC2"}, 673 {"DEC2 MUX", "ADC3", "ADC3"}, 674 {"DEC2 MUX", NULL, "CDC_CONN"}, 675 676 {"DMIC1", NULL, "DMIC_CLK"}, 677 {"DMIC2", NULL, "DMIC_CLK"}, 678 679 {"I2S TX1", NULL, "CIC1 MUX"}, 680 {"I2S TX2", NULL, "CIC2 MUX"}, 681 682 {"I2S TX1", NULL, "TX_I2S_CLK"}, 683 {"I2S TX2", NULL, "TX_I2S_CLK"}, 684 685 {"TX_I2S_CLK", NULL, "MCLK"}, 686 {"TX_I2S_CLK", NULL, "PDM_CLK"}, 687 688 {"ADC1", NULL, "LPASS_PDM_TX"}, 689 {"ADC2", NULL, "LPASS_PDM_TX"}, 690 {"ADC3", NULL, "LPASS_PDM_TX"}, 691 692 {"I2S RX1", NULL, "RX_I2S_CLK"}, 693 {"I2S RX2", NULL, "RX_I2S_CLK"}, 694 {"I2S RX3", NULL, "RX_I2S_CLK"}, 695 696 {"RX_I2S_CLK", NULL, "PDM_CLK"}, 697 {"RX_I2S_CLK", NULL, "MCLK"}, 698 {"RX_I2S_CLK", NULL, "CDC_CONN"}, 699 700 /* RX1 PATH.. */ 701 {"PDM_RX1", NULL, "RX1 INT"}, 702 {"RX1 INT", NULL, "RX1 MIX1"}, 703 704 {"RX1 MIX1", NULL, "RX1 MIX1 INP1"}, 705 {"RX1 MIX1", NULL, "RX1 MIX1 INP2"}, 706 {"RX1 MIX1", NULL, "RX1 MIX1 INP3"}, 707 708 {"RX1 MIX1 INP1", "RX1", "I2S RX1"}, 709 {"RX1 MIX1 INP1", "RX2", "I2S RX2"}, 710 {"RX1 MIX1 INP1", "RX3", "I2S RX3"}, 711 712 {"RX1 MIX1 INP2", "RX1", "I2S RX1"}, 713 {"RX1 MIX1 INP2", "RX2", "I2S RX2"}, 714 {"RX1 MIX1 INP2", "RX3", "I2S RX3"}, 715 716 {"RX1 MIX1 INP3", "RX1", "I2S RX1"}, 717 {"RX1 MIX1 INP3", "RX2", "I2S RX2"}, 718 {"RX1 MIX1 INP3", "RX3", "I2S RX3"}, 719 720 /* RX2 PATH */ 721 {"PDM_RX2", NULL, "RX2 INT"}, 722 {"RX2 INT", NULL, "RX2 MIX1"}, 723 724 {"RX2 MIX1", NULL, "RX2 MIX1 INP1"}, 725 {"RX2 MIX1", NULL, "RX2 MIX1 INP2"}, 726 {"RX2 MIX1", NULL, "RX2 MIX1 INP3"}, 727 728 {"RX2 MIX1 INP1", "RX1", "I2S RX1"}, 729 {"RX2 MIX1 INP1", "RX2", "I2S RX2"}, 730 {"RX2 MIX1 INP1", "RX3", "I2S RX3"}, 731 732 {"RX2 MIX1 INP2", "RX1", "I2S RX1"}, 733 {"RX2 MIX1 INP2", "RX2", "I2S RX2"}, 734 {"RX2 MIX1 INP2", "RX3", "I2S RX3"}, 735 736 {"RX2 MIX1 INP3", "RX1", "I2S RX1"}, 737 {"RX2 MIX1 INP3", "RX2", "I2S RX2"}, 738 {"RX2 MIX1 INP3", "RX3", "I2S RX3"}, 739 740 /* RX3 PATH */ 741 {"PDM_RX3", NULL, "RX3 INT"}, 742 {"RX3 INT", NULL, "RX3 MIX1"}, 743 744 {"RX3 MIX1", NULL, "RX3 MIX1 INP1"}, 745 {"RX3 MIX1", NULL, "RX3 MIX1 INP2"}, 746 {"RX3 MIX1", NULL, "RX3 MIX1 INP3"}, 747 748 {"RX3 MIX1 INP1", "RX1", "I2S RX1"}, 749 {"RX3 MIX1 INP1", "RX2", "I2S RX2"}, 750 {"RX3 MIX1 INP1", "RX3", "I2S RX3"}, 751 752 {"RX3 MIX1 INP2", "RX1", "I2S RX1"}, 753 {"RX3 MIX1 INP2", "RX2", "I2S RX2"}, 754 {"RX3 MIX1 INP2", "RX3", "I2S RX3"}, 755 756 {"RX3 MIX1 INP3", "RX1", "I2S RX1"}, 757 {"RX3 MIX1 INP3", "RX2", "I2S RX2"}, 758 {"RX3 MIX1 INP3", "RX3", "I2S RX3"}, 759 760 }; 761 762 static int msm8916_wcd_digital_startup(struct snd_pcm_substream *substream, 763 struct snd_soc_dai *dai) 764 { 765 struct snd_soc_component *component = dai->component; 766 struct msm8916_wcd_digital_priv *msm8916_wcd; 767 unsigned long mclk_rate; 768 769 msm8916_wcd = snd_soc_component_get_drvdata(component); 770 snd_soc_component_update_bits(component, LPASS_CDC_CLK_MCLK_CTL, 771 MCLK_CTL_MCLK_EN_MASK, 772 MCLK_CTL_MCLK_EN_ENABLE); 773 snd_soc_component_update_bits(component, LPASS_CDC_CLK_PDM_CTL, 774 LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 775 LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_FB); 776 777 mclk_rate = clk_get_rate(msm8916_wcd->mclk); 778 switch (mclk_rate) { 779 case 12288000: 780 snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL, 781 TOP_CTL_DIG_MCLK_FREQ_MASK, 782 TOP_CTL_DIG_MCLK_FREQ_F_12_288MHZ); 783 break; 784 case 9600000: 785 snd_soc_component_update_bits(component, LPASS_CDC_TOP_CTL, 786 TOP_CTL_DIG_MCLK_FREQ_MASK, 787 TOP_CTL_DIG_MCLK_FREQ_F_9_6MHZ); 788 break; 789 default: 790 dev_err(component->dev, "Invalid mclk rate %ld\n", mclk_rate); 791 break; 792 } 793 return 0; 794 } 795 796 static void msm8916_wcd_digital_shutdown(struct snd_pcm_substream *substream, 797 struct snd_soc_dai *dai) 798 { 799 snd_soc_component_update_bits(dai->component, LPASS_CDC_CLK_PDM_CTL, 800 LPASS_CDC_CLK_PDM_CTL_PDM_CLK_SEL_MASK, 0); 801 } 802 803 static const struct snd_soc_dai_ops msm8916_wcd_digital_dai_ops = { 804 .startup = msm8916_wcd_digital_startup, 805 .shutdown = msm8916_wcd_digital_shutdown, 806 .hw_params = msm8916_wcd_digital_hw_params, 807 }; 808 809 static struct snd_soc_dai_driver msm8916_wcd_digital_dai[] = { 810 [0] = { 811 .name = "msm8916_wcd_digital_i2s_rx1", 812 .id = 0, 813 .playback = { 814 .stream_name = "AIF1 Playback", 815 .rates = MSM8916_WCD_DIGITAL_RATES, 816 .formats = MSM8916_WCD_DIGITAL_FORMATS, 817 .channels_min = 1, 818 .channels_max = 3, 819 }, 820 .ops = &msm8916_wcd_digital_dai_ops, 821 }, 822 [1] = { 823 .name = "msm8916_wcd_digital_i2s_tx1", 824 .id = 1, 825 .capture = { 826 .stream_name = "AIF1 Capture", 827 .rates = MSM8916_WCD_DIGITAL_RATES, 828 .formats = MSM8916_WCD_DIGITAL_FORMATS, 829 .channels_min = 1, 830 .channels_max = 4, 831 }, 832 .ops = &msm8916_wcd_digital_dai_ops, 833 }, 834 }; 835 836 static const struct snd_soc_component_driver msm8916_wcd_digital = { 837 .probe = msm8916_wcd_digital_component_probe, 838 .set_sysclk = msm8916_wcd_digital_component_set_sysclk, 839 .controls = msm8916_wcd_digital_snd_controls, 840 .num_controls = ARRAY_SIZE(msm8916_wcd_digital_snd_controls), 841 .dapm_widgets = msm8916_wcd_digital_dapm_widgets, 842 .num_dapm_widgets = ARRAY_SIZE(msm8916_wcd_digital_dapm_widgets), 843 .dapm_routes = msm8916_wcd_digital_audio_map, 844 .num_dapm_routes = ARRAY_SIZE(msm8916_wcd_digital_audio_map), 845 .idle_bias_on = 1, 846 .use_pmdown_time = 1, 847 .endianness = 1, 848 .non_legacy_dai_naming = 1, 849 }; 850 851 static const struct regmap_config msm8916_codec_regmap_config = { 852 .reg_bits = 32, 853 .reg_stride = 4, 854 .val_bits = 32, 855 .max_register = LPASS_CDC_TX2_DMIC_CTL, 856 .cache_type = REGCACHE_FLAT, 857 }; 858 859 static int msm8916_wcd_digital_probe(struct platform_device *pdev) 860 { 861 struct msm8916_wcd_digital_priv *priv; 862 struct device *dev = &pdev->dev; 863 void __iomem *base; 864 struct resource *mem_res; 865 struct regmap *digital_map; 866 int ret; 867 868 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 869 if (!priv) 870 return -ENOMEM; 871 872 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 873 base = devm_ioremap_resource(&pdev->dev, mem_res); 874 if (IS_ERR(base)) 875 return PTR_ERR(base); 876 877 digital_map = 878 devm_regmap_init_mmio(&pdev->dev, base, 879 &msm8916_codec_regmap_config); 880 if (IS_ERR(digital_map)) 881 return PTR_ERR(digital_map); 882 883 ret = msm8916_wcd_digital_get_clks(pdev, priv); 884 if (ret < 0) 885 return ret; 886 887 ret = clk_prepare_enable(priv->ahbclk); 888 if (ret < 0) { 889 dev_err(dev, "failed to enable ahbclk %d\n", ret); 890 return ret; 891 } 892 893 ret = clk_prepare_enable(priv->mclk); 894 if (ret < 0) { 895 dev_err(dev, "failed to enable mclk %d\n", ret); 896 return ret; 897 } 898 899 dev_set_drvdata(dev, priv); 900 901 return devm_snd_soc_register_component(dev, &msm8916_wcd_digital, 902 msm8916_wcd_digital_dai, 903 ARRAY_SIZE(msm8916_wcd_digital_dai)); 904 } 905 906 static int msm8916_wcd_digital_remove(struct platform_device *pdev) 907 { 908 struct msm8916_wcd_digital_priv *priv = dev_get_drvdata(&pdev->dev); 909 910 clk_disable_unprepare(priv->mclk); 911 clk_disable_unprepare(priv->ahbclk); 912 913 return 0; 914 } 915 916 static const struct of_device_id msm8916_wcd_digital_match_table[] = { 917 { .compatible = "qcom,msm8916-wcd-digital-codec" }, 918 { } 919 }; 920 921 MODULE_DEVICE_TABLE(of, msm8916_wcd_digital_match_table); 922 923 static struct platform_driver msm8916_wcd_digital_driver = { 924 .driver = { 925 .name = "msm8916-wcd-digital-codec", 926 .of_match_table = msm8916_wcd_digital_match_table, 927 }, 928 .probe = msm8916_wcd_digital_probe, 929 .remove = msm8916_wcd_digital_remove, 930 }; 931 932 module_platform_driver(msm8916_wcd_digital_driver); 933 934 MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>"); 935 MODULE_DESCRIPTION("MSM8916 WCD Digital Codec driver"); 936 MODULE_LICENSE("GPL v2"); 937