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