1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. 3 // Copyright (c) 2017-2018, Linaro Limited 4 5 #include <linux/module.h> 6 #include <linux/init.h> 7 #include <linux/platform_device.h> 8 #include <linux/device.h> 9 #include <linux/wait.h> 10 #include <linux/bitops.h> 11 #include <linux/regulator/consumer.h> 12 #include <linux/clk.h> 13 #include <linux/delay.h> 14 #include <linux/kernel.h> 15 #include <linux/slimbus.h> 16 #include <sound/soc.h> 17 #include <sound/pcm_params.h> 18 #include <sound/soc-dapm.h> 19 #include <linux/of_gpio.h> 20 #include <linux/of.h> 21 #include <linux/of_irq.h> 22 #include <sound/tlv.h> 23 #include <sound/info.h> 24 #include "wcd9335.h" 25 #include "wcd-clsh-v2.h" 26 27 #include <dt-bindings/sound/qcom,wcd9335.h> 28 29 #define WCD9335_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 30 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 31 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) 32 /* Fractional Rates */ 33 #define WCD9335_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100) 34 #define WCD9335_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \ 35 SNDRV_PCM_FMTBIT_S24_LE) 36 37 /* slave port water mark level 38 * (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes) 39 */ 40 #define SLAVE_PORT_WATER_MARK_6BYTES 0 41 #define SLAVE_PORT_WATER_MARK_9BYTES 1 42 #define SLAVE_PORT_WATER_MARK_12BYTES 2 43 #define SLAVE_PORT_WATER_MARK_15BYTES 3 44 #define SLAVE_PORT_WATER_MARK_SHIFT 1 45 #define SLAVE_PORT_ENABLE 1 46 #define SLAVE_PORT_DISABLE 0 47 #define WCD9335_SLIM_WATER_MARK_VAL \ 48 ((SLAVE_PORT_WATER_MARK_12BYTES << SLAVE_PORT_WATER_MARK_SHIFT) | \ 49 (SLAVE_PORT_ENABLE)) 50 51 #define WCD9335_SLIM_NUM_PORT_REG 3 52 #define WCD9335_SLIM_PGD_PORT_INT_TX_EN0 (WCD9335_SLIM_PGD_PORT_INT_EN0 + 2) 53 54 #define WCD9335_MCLK_CLK_12P288MHZ 12288000 55 #define WCD9335_MCLK_CLK_9P6MHZ 9600000 56 57 #define WCD9335_SLIM_CLOSE_TIMEOUT 1000 58 #define WCD9335_SLIM_IRQ_OVERFLOW (1 << 0) 59 #define WCD9335_SLIM_IRQ_UNDERFLOW (1 << 1) 60 #define WCD9335_SLIM_IRQ_PORT_CLOSED (1 << 2) 61 62 #define WCD9335_NUM_INTERPOLATORS 9 63 #define WCD9335_RX_START 16 64 #define WCD9335_SLIM_CH_START 128 65 #define WCD9335_MAX_MICBIAS 4 66 #define WCD9335_MAX_VALID_ADC_MUX 13 67 #define WCD9335_INVALID_ADC_MUX 9 68 69 #define TX_HPF_CUT_OFF_FREQ_MASK 0x60 70 #define CF_MIN_3DB_4HZ 0x0 71 #define CF_MIN_3DB_75HZ 0x1 72 #define CF_MIN_3DB_150HZ 0x2 73 #define WCD9335_DMIC_CLK_DIV_2 0x0 74 #define WCD9335_DMIC_CLK_DIV_3 0x1 75 #define WCD9335_DMIC_CLK_DIV_4 0x2 76 #define WCD9335_DMIC_CLK_DIV_6 0x3 77 #define WCD9335_DMIC_CLK_DIV_8 0x4 78 #define WCD9335_DMIC_CLK_DIV_16 0x5 79 #define WCD9335_DMIC_CLK_DRIVE_DEFAULT 0x02 80 #define WCD9335_AMIC_PWR_LEVEL_LP 0 81 #define WCD9335_AMIC_PWR_LEVEL_DEFAULT 1 82 #define WCD9335_AMIC_PWR_LEVEL_HP 2 83 #define WCD9335_AMIC_PWR_LVL_MASK 0x60 84 #define WCD9335_AMIC_PWR_LVL_SHIFT 0x5 85 86 #define WCD9335_DEC_PWR_LVL_MASK 0x06 87 #define WCD9335_DEC_PWR_LVL_LP 0x02 88 #define WCD9335_DEC_PWR_LVL_HP 0x04 89 #define WCD9335_DEC_PWR_LVL_DF 0x00 90 91 #define WCD9335_SLIM_RX_CH(p) \ 92 {.port = p + WCD9335_RX_START, .shift = p,} 93 94 #define WCD9335_SLIM_TX_CH(p) \ 95 {.port = p, .shift = p,} 96 97 /* vout step value */ 98 #define WCD9335_CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25) 99 100 #define WCD9335_INTERPOLATOR_PATH(id) \ 101 {"RX INT" #id "_1 MIX1 INP0", "RX0", "SLIM RX0"}, \ 102 {"RX INT" #id "_1 MIX1 INP0", "RX1", "SLIM RX1"}, \ 103 {"RX INT" #id "_1 MIX1 INP0", "RX2", "SLIM RX2"}, \ 104 {"RX INT" #id "_1 MIX1 INP0", "RX3", "SLIM RX3"}, \ 105 {"RX INT" #id "_1 MIX1 INP0", "RX4", "SLIM RX4"}, \ 106 {"RX INT" #id "_1 MIX1 INP0", "RX5", "SLIM RX5"}, \ 107 {"RX INT" #id "_1 MIX1 INP0", "RX6", "SLIM RX6"}, \ 108 {"RX INT" #id "_1 MIX1 INP0", "RX7", "SLIM RX7"}, \ 109 {"RX INT" #id "_1 MIX1 INP1", "RX0", "SLIM RX0"}, \ 110 {"RX INT" #id "_1 MIX1 INP1", "RX1", "SLIM RX1"}, \ 111 {"RX INT" #id "_1 MIX1 INP1", "RX2", "SLIM RX2"}, \ 112 {"RX INT" #id "_1 MIX1 INP1", "RX3", "SLIM RX3"}, \ 113 {"RX INT" #id "_1 MIX1 INP1", "RX4", "SLIM RX4"}, \ 114 {"RX INT" #id "_1 MIX1 INP1", "RX5", "SLIM RX5"}, \ 115 {"RX INT" #id "_1 MIX1 INP1", "RX6", "SLIM RX6"}, \ 116 {"RX INT" #id "_1 MIX1 INP1", "RX7", "SLIM RX7"}, \ 117 {"RX INT" #id "_1 MIX1 INP2", "RX0", "SLIM RX0"}, \ 118 {"RX INT" #id "_1 MIX1 INP2", "RX1", "SLIM RX1"}, \ 119 {"RX INT" #id "_1 MIX1 INP2", "RX2", "SLIM RX2"}, \ 120 {"RX INT" #id "_1 MIX1 INP2", "RX3", "SLIM RX3"}, \ 121 {"RX INT" #id "_1 MIX1 INP2", "RX4", "SLIM RX4"}, \ 122 {"RX INT" #id "_1 MIX1 INP2", "RX5", "SLIM RX5"}, \ 123 {"RX INT" #id "_1 MIX1 INP2", "RX6", "SLIM RX6"}, \ 124 {"RX INT" #id "_1 MIX1 INP2", "RX7", "SLIM RX7"}, \ 125 {"RX INT" #id "_2 MUX", "RX0", "SLIM RX0"}, \ 126 {"RX INT" #id "_2 MUX", "RX1", "SLIM RX1"}, \ 127 {"RX INT" #id "_2 MUX", "RX2", "SLIM RX2"}, \ 128 {"RX INT" #id "_2 MUX", "RX3", "SLIM RX3"}, \ 129 {"RX INT" #id "_2 MUX", "RX4", "SLIM RX4"}, \ 130 {"RX INT" #id "_2 MUX", "RX5", "SLIM RX5"}, \ 131 {"RX INT" #id "_2 MUX", "RX6", "SLIM RX6"}, \ 132 {"RX INT" #id "_2 MUX", "RX7", "SLIM RX7"}, \ 133 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP0"}, \ 134 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP1"}, \ 135 {"RX INT" #id "_1 MIX1", NULL, "RX INT" #id "_1 MIX1 INP2"}, \ 136 {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_2 MUX"}, \ 137 {"RX INT" #id " SEC MIX", NULL, "RX INT" #id "_1 MIX1"}, \ 138 {"RX INT" #id " MIX2", NULL, "RX INT" #id " SEC MIX"}, \ 139 {"RX INT" #id " INTERP", NULL, "RX INT" #id " MIX2"} 140 141 #define WCD9335_ADC_MUX_PATH(id) \ 142 {"AIF1_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \ 143 {"AIF2_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \ 144 {"AIF3_CAP Mixer", "SLIM TX" #id, "SLIM TX" #id " MUX"}, \ 145 {"SLIM TX" #id " MUX", "DEC" #id, "ADC MUX" #id}, \ 146 {"ADC MUX" #id, "DMIC", "DMIC MUX" #id}, \ 147 {"ADC MUX" #id, "AMIC", "AMIC MUX" #id}, \ 148 {"DMIC MUX" #id, "DMIC0", "DMIC0"}, \ 149 {"DMIC MUX" #id, "DMIC1", "DMIC1"}, \ 150 {"DMIC MUX" #id, "DMIC2", "DMIC2"}, \ 151 {"DMIC MUX" #id, "DMIC3", "DMIC3"}, \ 152 {"DMIC MUX" #id, "DMIC4", "DMIC4"}, \ 153 {"DMIC MUX" #id, "DMIC5", "DMIC5"}, \ 154 {"AMIC MUX" #id, "ADC1", "ADC1"}, \ 155 {"AMIC MUX" #id, "ADC2", "ADC2"}, \ 156 {"AMIC MUX" #id, "ADC3", "ADC3"}, \ 157 {"AMIC MUX" #id, "ADC4", "ADC4"}, \ 158 {"AMIC MUX" #id, "ADC5", "ADC5"}, \ 159 {"AMIC MUX" #id, "ADC6", "ADC6"} 160 161 enum { 162 WCD9335_RX0 = 0, 163 WCD9335_RX1, 164 WCD9335_RX2, 165 WCD9335_RX3, 166 WCD9335_RX4, 167 WCD9335_RX5, 168 WCD9335_RX6, 169 WCD9335_RX7, 170 WCD9335_RX8, 171 WCD9335_RX9, 172 WCD9335_RX10, 173 WCD9335_RX11, 174 WCD9335_RX12, 175 WCD9335_RX_MAX, 176 }; 177 178 enum { 179 WCD9335_TX0 = 0, 180 WCD9335_TX1, 181 WCD9335_TX2, 182 WCD9335_TX3, 183 WCD9335_TX4, 184 WCD9335_TX5, 185 WCD9335_TX6, 186 WCD9335_TX7, 187 WCD9335_TX8, 188 WCD9335_TX9, 189 WCD9335_TX10, 190 WCD9335_TX11, 191 WCD9335_TX12, 192 WCD9335_TX13, 193 WCD9335_TX14, 194 WCD9335_TX15, 195 WCD9335_TX_MAX, 196 }; 197 198 enum { 199 SIDO_SOURCE_INTERNAL = 0, 200 SIDO_SOURCE_RCO_BG, 201 }; 202 203 enum wcd9335_sido_voltage { 204 SIDO_VOLTAGE_SVS_MV = 950, 205 SIDO_VOLTAGE_NOMINAL_MV = 1100, 206 }; 207 208 enum { 209 COMPANDER_1, /* HPH_L */ 210 COMPANDER_2, /* HPH_R */ 211 COMPANDER_3, /* LO1_DIFF */ 212 COMPANDER_4, /* LO2_DIFF */ 213 COMPANDER_5, /* LO3_SE */ 214 COMPANDER_6, /* LO4_SE */ 215 COMPANDER_7, /* SWR SPK CH1 */ 216 COMPANDER_8, /* SWR SPK CH2 */ 217 COMPANDER_MAX, 218 }; 219 220 enum { 221 INTn_2_INP_SEL_ZERO = 0, 222 INTn_2_INP_SEL_RX0, 223 INTn_2_INP_SEL_RX1, 224 INTn_2_INP_SEL_RX2, 225 INTn_2_INP_SEL_RX3, 226 INTn_2_INP_SEL_RX4, 227 INTn_2_INP_SEL_RX5, 228 INTn_2_INP_SEL_RX6, 229 INTn_2_INP_SEL_RX7, 230 INTn_2_INP_SEL_PROXIMITY, 231 }; 232 233 enum { 234 INTn_1_MIX_INP_SEL_ZERO = 0, 235 INTn_1_MIX_INP_SEL_DEC0, 236 INTn_1_MIX_INP_SEL_DEC1, 237 INTn_1_MIX_INP_SEL_IIR0, 238 INTn_1_MIX_INP_SEL_IIR1, 239 INTn_1_MIX_INP_SEL_RX0, 240 INTn_1_MIX_INP_SEL_RX1, 241 INTn_1_MIX_INP_SEL_RX2, 242 INTn_1_MIX_INP_SEL_RX3, 243 INTn_1_MIX_INP_SEL_RX4, 244 INTn_1_MIX_INP_SEL_RX5, 245 INTn_1_MIX_INP_SEL_RX6, 246 INTn_1_MIX_INP_SEL_RX7, 247 248 }; 249 250 enum { 251 INTERP_EAR = 0, 252 INTERP_HPHL, 253 INTERP_HPHR, 254 INTERP_LO1, 255 INTERP_LO2, 256 INTERP_LO3, 257 INTERP_LO4, 258 INTERP_SPKR1, 259 INTERP_SPKR2, 260 }; 261 262 enum wcd_clock_type { 263 WCD_CLK_OFF, 264 WCD_CLK_RCO, 265 WCD_CLK_MCLK, 266 }; 267 268 enum { 269 MIC_BIAS_1 = 1, 270 MIC_BIAS_2, 271 MIC_BIAS_3, 272 MIC_BIAS_4 273 }; 274 275 enum { 276 MICB_PULLUP_ENABLE, 277 MICB_PULLUP_DISABLE, 278 MICB_ENABLE, 279 MICB_DISABLE, 280 }; 281 282 struct wcd9335_slim_ch { 283 u32 ch_num; 284 u16 port; 285 u16 shift; 286 struct list_head list; 287 }; 288 289 struct wcd_slim_codec_dai_data { 290 struct list_head slim_ch_list; 291 struct slim_stream_config sconfig; 292 struct slim_stream_runtime *sruntime; 293 }; 294 295 struct wcd9335_codec { 296 struct device *dev; 297 struct clk *mclk; 298 struct clk *native_clk; 299 u32 mclk_rate; 300 301 struct slim_device *slim; 302 struct slim_device *slim_ifc_dev; 303 struct regmap *regmap; 304 struct regmap *if_regmap; 305 struct regmap_irq_chip_data *irq_data; 306 307 struct wcd9335_slim_ch rx_chs[WCD9335_RX_MAX]; 308 struct wcd9335_slim_ch tx_chs[WCD9335_TX_MAX]; 309 u32 num_rx_port; 310 u32 num_tx_port; 311 312 int sido_input_src; 313 enum wcd9335_sido_voltage sido_voltage; 314 315 struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS]; 316 struct snd_soc_component *component; 317 318 int master_bias_users; 319 int clk_mclk_users; 320 int clk_rco_users; 321 int sido_ccl_cnt; 322 enum wcd_clock_type clk_type; 323 324 struct wcd_clsh_ctrl *clsh_ctrl; 325 u32 hph_mode; 326 int prim_int_users[WCD9335_NUM_INTERPOLATORS]; 327 328 int comp_enabled[COMPANDER_MAX]; 329 330 int intr1; 331 int reset_gpio; 332 struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; 333 334 unsigned int rx_port_value[WCD9335_RX_MAX]; 335 unsigned int tx_port_value[WCD9335_TX_MAX]; 336 int hph_l_gain; 337 int hph_r_gain; 338 u32 rx_bias_count; 339 340 /*TX*/ 341 int micb_ref[WCD9335_MAX_MICBIAS]; 342 int pullup_ref[WCD9335_MAX_MICBIAS]; 343 344 int dmic_0_1_clk_cnt; 345 int dmic_2_3_clk_cnt; 346 int dmic_4_5_clk_cnt; 347 }; 348 349 struct wcd9335_irq { 350 int irq; 351 irqreturn_t (*handler)(int irq, void *data); 352 char *name; 353 }; 354 355 static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = { 356 WCD9335_SLIM_TX_CH(0), 357 WCD9335_SLIM_TX_CH(1), 358 WCD9335_SLIM_TX_CH(2), 359 WCD9335_SLIM_TX_CH(3), 360 WCD9335_SLIM_TX_CH(4), 361 WCD9335_SLIM_TX_CH(5), 362 WCD9335_SLIM_TX_CH(6), 363 WCD9335_SLIM_TX_CH(7), 364 WCD9335_SLIM_TX_CH(8), 365 WCD9335_SLIM_TX_CH(9), 366 WCD9335_SLIM_TX_CH(10), 367 WCD9335_SLIM_TX_CH(11), 368 WCD9335_SLIM_TX_CH(12), 369 WCD9335_SLIM_TX_CH(13), 370 WCD9335_SLIM_TX_CH(14), 371 WCD9335_SLIM_TX_CH(15), 372 }; 373 374 static const struct wcd9335_slim_ch wcd9335_rx_chs[WCD9335_RX_MAX] = { 375 WCD9335_SLIM_RX_CH(0), /* 16 */ 376 WCD9335_SLIM_RX_CH(1), /* 17 */ 377 WCD9335_SLIM_RX_CH(2), 378 WCD9335_SLIM_RX_CH(3), 379 WCD9335_SLIM_RX_CH(4), 380 WCD9335_SLIM_RX_CH(5), 381 WCD9335_SLIM_RX_CH(6), 382 WCD9335_SLIM_RX_CH(7), 383 WCD9335_SLIM_RX_CH(8), 384 WCD9335_SLIM_RX_CH(9), 385 WCD9335_SLIM_RX_CH(10), 386 WCD9335_SLIM_RX_CH(11), 387 WCD9335_SLIM_RX_CH(12), 388 }; 389 390 struct interp_sample_rate { 391 int rate; 392 int rate_val; 393 }; 394 395 static const struct interp_sample_rate int_mix_rate_val[] = { 396 {48000, 0x4}, /* 48K */ 397 {96000, 0x5}, /* 96K */ 398 {192000, 0x6}, /* 192K */ 399 }; 400 401 static const struct interp_sample_rate int_prim_rate_val[] = { 402 {8000, 0x0}, /* 8K */ 403 {16000, 0x1}, /* 16K */ 404 {24000, -EINVAL},/* 24K */ 405 {32000, 0x3}, /* 32K */ 406 {48000, 0x4}, /* 48K */ 407 {96000, 0x5}, /* 96K */ 408 {192000, 0x6}, /* 192K */ 409 {384000, 0x7}, /* 384K */ 410 {44100, 0x8}, /* 44.1K */ 411 }; 412 413 struct wcd9335_reg_mask_val { 414 u16 reg; 415 u8 mask; 416 u8 val; 417 }; 418 419 static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = { 420 /* Rbuckfly/R_EAR(32) */ 421 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00}, 422 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60}, 423 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00}, 424 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, 425 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, 426 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, 427 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, 428 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C}, 429 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00}, 430 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40}, 431 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03}, 432 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02}, 433 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01}, 434 {WCD9335_EAR_CMBUFF, 0x08, 0x00}, 435 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 436 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 437 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 438 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 439 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80}, 440 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80}, 441 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01}, 442 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01}, 443 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01}, 444 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01}, 445 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01}, 446 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01}, 447 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01}, 448 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01}, 449 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01}, 450 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01}, 451 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01}, 452 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01}, 453 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01}, 454 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01}, 455 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01}, 456 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01}, 457 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01}, 458 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01}, 459 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, 460 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, 461 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08}, 462 {WCD9335_RCO_CTRL_2, 0x0F, 0x08}, 463 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10}, 464 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20}, 465 {WCD9335_HPH_OCP_CTL, 0xFF, 0x5A}, 466 {WCD9335_HPH_L_TEST, 0x01, 0x01}, 467 {WCD9335_HPH_R_TEST, 0x01, 0x01}, 468 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12}, 469 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08}, 470 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18}, 471 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12}, 472 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08}, 473 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18}, 474 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45}, 475 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4}, 476 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08}, 477 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02}, 478 }; 479 480 /* Cutoff frequency for high pass filter */ 481 static const char * const cf_text[] = { 482 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" 483 }; 484 485 static const char * const rx_cf_text[] = { 486 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", 487 "CF_NEG_3DB_0P48HZ" 488 }; 489 490 static const char * const rx_int0_7_mix_mux_text[] = { 491 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", 492 "RX6", "RX7", "PROXIMITY" 493 }; 494 495 static const char * const rx_int_mix_mux_text[] = { 496 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", 497 "RX6", "RX7" 498 }; 499 500 static const char * const rx_prim_mix_text[] = { 501 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", 502 "RX3", "RX4", "RX5", "RX6", "RX7" 503 }; 504 505 static const char * const rx_int_dem_inp_mux_text[] = { 506 "NORMAL_DSM_OUT", "CLSH_DSM_OUT", 507 }; 508 509 static const char * const rx_int0_interp_mux_text[] = { 510 "ZERO", "RX INT0 MIX2", 511 }; 512 513 static const char * const rx_int1_interp_mux_text[] = { 514 "ZERO", "RX INT1 MIX2", 515 }; 516 517 static const char * const rx_int2_interp_mux_text[] = { 518 "ZERO", "RX INT2 MIX2", 519 }; 520 521 static const char * const rx_int3_interp_mux_text[] = { 522 "ZERO", "RX INT3 MIX2", 523 }; 524 525 static const char * const rx_int4_interp_mux_text[] = { 526 "ZERO", "RX INT4 MIX2", 527 }; 528 529 static const char * const rx_int5_interp_mux_text[] = { 530 "ZERO", "RX INT5 MIX2", 531 }; 532 533 static const char * const rx_int6_interp_mux_text[] = { 534 "ZERO", "RX INT6 MIX2", 535 }; 536 537 static const char * const rx_int7_interp_mux_text[] = { 538 "ZERO", "RX INT7 MIX2", 539 }; 540 541 static const char * const rx_int8_interp_mux_text[] = { 542 "ZERO", "RX INT8 SEC MIX" 543 }; 544 545 static const char * const rx_hph_mode_mux_text[] = { 546 "Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB", 547 "Class-H Hi-Fi Low Power" 548 }; 549 550 static const char *const slim_rx_mux_text[] = { 551 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", 552 }; 553 554 static const char * const adc_mux_text[] = { 555 "DMIC", "AMIC", "ANC_FB_TUNE1", "ANC_FB_TUNE2" 556 }; 557 558 static const char * const dmic_mux_text[] = { 559 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", 560 "SMIC0", "SMIC1", "SMIC2", "SMIC3" 561 }; 562 563 static const char * const dmic_mux_alt_text[] = { 564 "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5", 565 }; 566 567 static const char * const amic_mux_text[] = { 568 "ZERO", "ADC1", "ADC2", "ADC3", "ADC4", "ADC5", "ADC6" 569 }; 570 571 static const char * const sb_tx0_mux_text[] = { 572 "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192" 573 }; 574 575 static const char * const sb_tx1_mux_text[] = { 576 "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192" 577 }; 578 579 static const char * const sb_tx2_mux_text[] = { 580 "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192" 581 }; 582 583 static const char * const sb_tx3_mux_text[] = { 584 "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192" 585 }; 586 587 static const char * const sb_tx4_mux_text[] = { 588 "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192" 589 }; 590 591 static const char * const sb_tx5_mux_text[] = { 592 "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192" 593 }; 594 595 static const char * const sb_tx6_mux_text[] = { 596 "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192" 597 }; 598 599 static const char * const sb_tx7_mux_text[] = { 600 "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192" 601 }; 602 603 static const char * const sb_tx8_mux_text[] = { 604 "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192" 605 }; 606 607 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); 608 static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); 609 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); 610 static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0); 611 612 static const struct soc_enum cf_dec0_enum = 613 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text); 614 615 static const struct soc_enum cf_dec1_enum = 616 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text); 617 618 static const struct soc_enum cf_dec2_enum = 619 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text); 620 621 static const struct soc_enum cf_dec3_enum = 622 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text); 623 624 static const struct soc_enum cf_dec4_enum = 625 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text); 626 627 static const struct soc_enum cf_dec5_enum = 628 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text); 629 630 static const struct soc_enum cf_dec6_enum = 631 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text); 632 633 static const struct soc_enum cf_dec7_enum = 634 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text); 635 636 static const struct soc_enum cf_dec8_enum = 637 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text); 638 639 static const struct soc_enum cf_int0_1_enum = 640 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text); 641 642 static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2, 643 rx_cf_text); 644 645 static const struct soc_enum cf_int1_1_enum = 646 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text); 647 648 static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2, 649 rx_cf_text); 650 651 static const struct soc_enum cf_int2_1_enum = 652 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text); 653 654 static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2, 655 rx_cf_text); 656 657 static const struct soc_enum cf_int3_1_enum = 658 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text); 659 660 static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2, 661 rx_cf_text); 662 663 static const struct soc_enum cf_int4_1_enum = 664 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text); 665 666 static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2, 667 rx_cf_text); 668 669 static const struct soc_enum cf_int5_1_enum = 670 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text); 671 672 static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2, 673 rx_cf_text); 674 675 static const struct soc_enum cf_int6_1_enum = 676 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text); 677 678 static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2, 679 rx_cf_text); 680 681 static const struct soc_enum cf_int7_1_enum = 682 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text); 683 684 static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2, 685 rx_cf_text); 686 687 static const struct soc_enum cf_int8_1_enum = 688 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text); 689 690 static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2, 691 rx_cf_text); 692 693 static const struct soc_enum rx_hph_mode_mux_enum = 694 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), 695 rx_hph_mode_mux_text); 696 697 static const struct soc_enum slim_rx_mux_enum = 698 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text); 699 700 static const struct soc_enum rx_int0_2_mux_chain_enum = 701 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10, 702 rx_int0_7_mix_mux_text); 703 704 static const struct soc_enum rx_int1_2_mux_chain_enum = 705 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9, 706 rx_int_mix_mux_text); 707 708 static const struct soc_enum rx_int2_2_mux_chain_enum = 709 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9, 710 rx_int_mix_mux_text); 711 712 static const struct soc_enum rx_int3_2_mux_chain_enum = 713 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9, 714 rx_int_mix_mux_text); 715 716 static const struct soc_enum rx_int4_2_mux_chain_enum = 717 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9, 718 rx_int_mix_mux_text); 719 720 static const struct soc_enum rx_int5_2_mux_chain_enum = 721 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9, 722 rx_int_mix_mux_text); 723 724 static const struct soc_enum rx_int6_2_mux_chain_enum = 725 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9, 726 rx_int_mix_mux_text); 727 728 static const struct soc_enum rx_int7_2_mux_chain_enum = 729 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10, 730 rx_int0_7_mix_mux_text); 731 732 static const struct soc_enum rx_int8_2_mux_chain_enum = 733 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9, 734 rx_int_mix_mux_text); 735 736 static const struct soc_enum rx_int0_1_mix_inp0_chain_enum = 737 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13, 738 rx_prim_mix_text); 739 740 static const struct soc_enum rx_int0_1_mix_inp1_chain_enum = 741 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13, 742 rx_prim_mix_text); 743 744 static const struct soc_enum rx_int0_1_mix_inp2_chain_enum = 745 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13, 746 rx_prim_mix_text); 747 748 static const struct soc_enum rx_int1_1_mix_inp0_chain_enum = 749 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13, 750 rx_prim_mix_text); 751 752 static const struct soc_enum rx_int1_1_mix_inp1_chain_enum = 753 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13, 754 rx_prim_mix_text); 755 756 static const struct soc_enum rx_int1_1_mix_inp2_chain_enum = 757 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13, 758 rx_prim_mix_text); 759 760 static const struct soc_enum rx_int2_1_mix_inp0_chain_enum = 761 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13, 762 rx_prim_mix_text); 763 764 static const struct soc_enum rx_int2_1_mix_inp1_chain_enum = 765 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13, 766 rx_prim_mix_text); 767 768 static const struct soc_enum rx_int2_1_mix_inp2_chain_enum = 769 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13, 770 rx_prim_mix_text); 771 772 static const struct soc_enum rx_int3_1_mix_inp0_chain_enum = 773 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13, 774 rx_prim_mix_text); 775 776 static const struct soc_enum rx_int3_1_mix_inp1_chain_enum = 777 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13, 778 rx_prim_mix_text); 779 780 static const struct soc_enum rx_int3_1_mix_inp2_chain_enum = 781 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13, 782 rx_prim_mix_text); 783 784 static const struct soc_enum rx_int4_1_mix_inp0_chain_enum = 785 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13, 786 rx_prim_mix_text); 787 788 static const struct soc_enum rx_int4_1_mix_inp1_chain_enum = 789 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13, 790 rx_prim_mix_text); 791 792 static const struct soc_enum rx_int4_1_mix_inp2_chain_enum = 793 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13, 794 rx_prim_mix_text); 795 796 static const struct soc_enum rx_int5_1_mix_inp0_chain_enum = 797 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13, 798 rx_prim_mix_text); 799 800 static const struct soc_enum rx_int5_1_mix_inp1_chain_enum = 801 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13, 802 rx_prim_mix_text); 803 804 static const struct soc_enum rx_int5_1_mix_inp2_chain_enum = 805 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13, 806 rx_prim_mix_text); 807 808 static const struct soc_enum rx_int6_1_mix_inp0_chain_enum = 809 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13, 810 rx_prim_mix_text); 811 812 static const struct soc_enum rx_int6_1_mix_inp1_chain_enum = 813 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13, 814 rx_prim_mix_text); 815 816 static const struct soc_enum rx_int6_1_mix_inp2_chain_enum = 817 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13, 818 rx_prim_mix_text); 819 820 static const struct soc_enum rx_int7_1_mix_inp0_chain_enum = 821 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13, 822 rx_prim_mix_text); 823 824 static const struct soc_enum rx_int7_1_mix_inp1_chain_enum = 825 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13, 826 rx_prim_mix_text); 827 828 static const struct soc_enum rx_int7_1_mix_inp2_chain_enum = 829 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13, 830 rx_prim_mix_text); 831 832 static const struct soc_enum rx_int8_1_mix_inp0_chain_enum = 833 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13, 834 rx_prim_mix_text); 835 836 static const struct soc_enum rx_int8_1_mix_inp1_chain_enum = 837 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13, 838 rx_prim_mix_text); 839 840 static const struct soc_enum rx_int8_1_mix_inp2_chain_enum = 841 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13, 842 rx_prim_mix_text); 843 844 static const struct soc_enum rx_int0_dem_inp_mux_enum = 845 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0, 846 ARRAY_SIZE(rx_int_dem_inp_mux_text), 847 rx_int_dem_inp_mux_text); 848 849 static const struct soc_enum rx_int1_dem_inp_mux_enum = 850 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0, 851 ARRAY_SIZE(rx_int_dem_inp_mux_text), 852 rx_int_dem_inp_mux_text); 853 854 static const struct soc_enum rx_int2_dem_inp_mux_enum = 855 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0, 856 ARRAY_SIZE(rx_int_dem_inp_mux_text), 857 rx_int_dem_inp_mux_text); 858 859 static const struct soc_enum rx_int0_interp_mux_enum = 860 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2, 861 rx_int0_interp_mux_text); 862 863 static const struct soc_enum rx_int1_interp_mux_enum = 864 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2, 865 rx_int1_interp_mux_text); 866 867 static const struct soc_enum rx_int2_interp_mux_enum = 868 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2, 869 rx_int2_interp_mux_text); 870 871 static const struct soc_enum rx_int3_interp_mux_enum = 872 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2, 873 rx_int3_interp_mux_text); 874 875 static const struct soc_enum rx_int4_interp_mux_enum = 876 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2, 877 rx_int4_interp_mux_text); 878 879 static const struct soc_enum rx_int5_interp_mux_enum = 880 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2, 881 rx_int5_interp_mux_text); 882 883 static const struct soc_enum rx_int6_interp_mux_enum = 884 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2, 885 rx_int6_interp_mux_text); 886 887 static const struct soc_enum rx_int7_interp_mux_enum = 888 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2, 889 rx_int7_interp_mux_text); 890 891 static const struct soc_enum rx_int8_interp_mux_enum = 892 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2, 893 rx_int8_interp_mux_text); 894 895 static const struct soc_enum tx_adc_mux0_chain_enum = 896 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0, 4, 897 adc_mux_text); 898 899 static const struct soc_enum tx_adc_mux1_chain_enum = 900 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0, 4, 901 adc_mux_text); 902 903 static const struct soc_enum tx_adc_mux2_chain_enum = 904 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0, 4, 905 adc_mux_text); 906 907 static const struct soc_enum tx_adc_mux3_chain_enum = 908 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0, 4, 909 adc_mux_text); 910 911 static const struct soc_enum tx_adc_mux4_chain_enum = 912 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 6, 4, 913 adc_mux_text); 914 915 static const struct soc_enum tx_adc_mux5_chain_enum = 916 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 6, 4, 917 adc_mux_text); 918 919 static const struct soc_enum tx_adc_mux6_chain_enum = 920 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 6, 4, 921 adc_mux_text); 922 923 static const struct soc_enum tx_adc_mux7_chain_enum = 924 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 6, 4, 925 adc_mux_text); 926 927 static const struct soc_enum tx_adc_mux8_chain_enum = 928 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 6, 4, 929 adc_mux_text); 930 931 static const struct soc_enum tx_dmic_mux0_enum = 932 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3, 11, 933 dmic_mux_text); 934 935 static const struct soc_enum tx_dmic_mux1_enum = 936 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3, 11, 937 dmic_mux_text); 938 939 static const struct soc_enum tx_dmic_mux2_enum = 940 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3, 11, 941 dmic_mux_text); 942 943 static const struct soc_enum tx_dmic_mux3_enum = 944 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3, 11, 945 dmic_mux_text); 946 947 static const struct soc_enum tx_dmic_mux4_enum = 948 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3, 7, 949 dmic_mux_alt_text); 950 951 static const struct soc_enum tx_dmic_mux5_enum = 952 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3, 7, 953 dmic_mux_alt_text); 954 955 static const struct soc_enum tx_dmic_mux6_enum = 956 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3, 7, 957 dmic_mux_alt_text); 958 959 static const struct soc_enum tx_dmic_mux7_enum = 960 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3, 7, 961 dmic_mux_alt_text); 962 963 static const struct soc_enum tx_dmic_mux8_enum = 964 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3, 7, 965 dmic_mux_alt_text); 966 967 static const struct soc_enum tx_amic_mux0_enum = 968 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, 7, 969 amic_mux_text); 970 971 static const struct soc_enum tx_amic_mux1_enum = 972 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, 7, 973 amic_mux_text); 974 975 static const struct soc_enum tx_amic_mux2_enum = 976 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, 7, 977 amic_mux_text); 978 979 static const struct soc_enum tx_amic_mux3_enum = 980 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0, 7, 981 amic_mux_text); 982 983 static const struct soc_enum tx_amic_mux4_enum = 984 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0, 7, 985 amic_mux_text); 986 987 static const struct soc_enum tx_amic_mux5_enum = 988 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0, 7, 989 amic_mux_text); 990 991 static const struct soc_enum tx_amic_mux6_enum = 992 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0, 7, 993 amic_mux_text); 994 995 static const struct soc_enum tx_amic_mux7_enum = 996 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0, 7, 997 amic_mux_text); 998 999 static const struct soc_enum tx_amic_mux8_enum = 1000 SOC_ENUM_SINGLE(WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0, 7, 1001 amic_mux_text); 1002 1003 static const struct soc_enum sb_tx0_mux_enum = 1004 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 0, 4, 1005 sb_tx0_mux_text); 1006 1007 static const struct soc_enum sb_tx1_mux_enum = 1008 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 2, 4, 1009 sb_tx1_mux_text); 1010 1011 static const struct soc_enum sb_tx2_mux_enum = 1012 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 4, 4, 1013 sb_tx2_mux_text); 1014 1015 static const struct soc_enum sb_tx3_mux_enum = 1016 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0, 6, 4, 1017 sb_tx3_mux_text); 1018 1019 static const struct soc_enum sb_tx4_mux_enum = 1020 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 0, 4, 1021 sb_tx4_mux_text); 1022 1023 static const struct soc_enum sb_tx5_mux_enum = 1024 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 2, 4, 1025 sb_tx5_mux_text); 1026 1027 static const struct soc_enum sb_tx6_mux_enum = 1028 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 4, 4, 1029 sb_tx6_mux_text); 1030 1031 static const struct soc_enum sb_tx7_mux_enum = 1032 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1, 6, 4, 1033 sb_tx7_mux_text); 1034 1035 static const struct soc_enum sb_tx8_mux_enum = 1036 SOC_ENUM_SINGLE(WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2, 0, 4, 1037 sb_tx8_mux_text); 1038 1039 static const struct snd_kcontrol_new rx_int0_2_mux = 1040 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum); 1041 1042 static const struct snd_kcontrol_new rx_int1_2_mux = 1043 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum); 1044 1045 static const struct snd_kcontrol_new rx_int2_2_mux = 1046 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum); 1047 1048 static const struct snd_kcontrol_new rx_int3_2_mux = 1049 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum); 1050 1051 static const struct snd_kcontrol_new rx_int4_2_mux = 1052 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum); 1053 1054 static const struct snd_kcontrol_new rx_int5_2_mux = 1055 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum); 1056 1057 static const struct snd_kcontrol_new rx_int6_2_mux = 1058 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum); 1059 1060 static const struct snd_kcontrol_new rx_int7_2_mux = 1061 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum); 1062 1063 static const struct snd_kcontrol_new rx_int8_2_mux = 1064 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum); 1065 1066 static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = 1067 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum); 1068 1069 static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = 1070 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum); 1071 1072 static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = 1073 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum); 1074 1075 static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = 1076 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum); 1077 1078 static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = 1079 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum); 1080 1081 static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = 1082 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum); 1083 1084 static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = 1085 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum); 1086 1087 static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = 1088 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum); 1089 1090 static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = 1091 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum); 1092 1093 static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux = 1094 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum); 1095 1096 static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux = 1097 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum); 1098 1099 static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux = 1100 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum); 1101 1102 static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux = 1103 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum); 1104 1105 static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux = 1106 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum); 1107 1108 static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux = 1109 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum); 1110 1111 static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux = 1112 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum); 1113 1114 static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux = 1115 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum); 1116 1117 static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux = 1118 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum); 1119 1120 static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux = 1121 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum); 1122 1123 static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux = 1124 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum); 1125 1126 static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux = 1127 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum); 1128 1129 static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux = 1130 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum); 1131 1132 static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux = 1133 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum); 1134 1135 static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux = 1136 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum); 1137 1138 static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux = 1139 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum); 1140 1141 static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux = 1142 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum); 1143 1144 static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux = 1145 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum); 1146 1147 static const struct snd_kcontrol_new rx_int0_interp_mux = 1148 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum); 1149 1150 static const struct snd_kcontrol_new rx_int1_interp_mux = 1151 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum); 1152 1153 static const struct snd_kcontrol_new rx_int2_interp_mux = 1154 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum); 1155 1156 static const struct snd_kcontrol_new rx_int3_interp_mux = 1157 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum); 1158 1159 static const struct snd_kcontrol_new rx_int4_interp_mux = 1160 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum); 1161 1162 static const struct snd_kcontrol_new rx_int5_interp_mux = 1163 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum); 1164 1165 static const struct snd_kcontrol_new rx_int6_interp_mux = 1166 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum); 1167 1168 static const struct snd_kcontrol_new rx_int7_interp_mux = 1169 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum); 1170 1171 static const struct snd_kcontrol_new rx_int8_interp_mux = 1172 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum); 1173 1174 static const struct snd_kcontrol_new tx_dmic_mux0 = 1175 SOC_DAPM_ENUM("DMIC MUX0 Mux", tx_dmic_mux0_enum); 1176 1177 static const struct snd_kcontrol_new tx_dmic_mux1 = 1178 SOC_DAPM_ENUM("DMIC MUX1 Mux", tx_dmic_mux1_enum); 1179 1180 static const struct snd_kcontrol_new tx_dmic_mux2 = 1181 SOC_DAPM_ENUM("DMIC MUX2 Mux", tx_dmic_mux2_enum); 1182 1183 static const struct snd_kcontrol_new tx_dmic_mux3 = 1184 SOC_DAPM_ENUM("DMIC MUX3 Mux", tx_dmic_mux3_enum); 1185 1186 static const struct snd_kcontrol_new tx_dmic_mux4 = 1187 SOC_DAPM_ENUM("DMIC MUX4 Mux", tx_dmic_mux4_enum); 1188 1189 static const struct snd_kcontrol_new tx_dmic_mux5 = 1190 SOC_DAPM_ENUM("DMIC MUX5 Mux", tx_dmic_mux5_enum); 1191 1192 static const struct snd_kcontrol_new tx_dmic_mux6 = 1193 SOC_DAPM_ENUM("DMIC MUX6 Mux", tx_dmic_mux6_enum); 1194 1195 static const struct snd_kcontrol_new tx_dmic_mux7 = 1196 SOC_DAPM_ENUM("DMIC MUX7 Mux", tx_dmic_mux7_enum); 1197 1198 static const struct snd_kcontrol_new tx_dmic_mux8 = 1199 SOC_DAPM_ENUM("DMIC MUX8 Mux", tx_dmic_mux8_enum); 1200 1201 static const struct snd_kcontrol_new tx_amic_mux0 = 1202 SOC_DAPM_ENUM("AMIC MUX0 Mux", tx_amic_mux0_enum); 1203 1204 static const struct snd_kcontrol_new tx_amic_mux1 = 1205 SOC_DAPM_ENUM("AMIC MUX1 Mux", tx_amic_mux1_enum); 1206 1207 static const struct snd_kcontrol_new tx_amic_mux2 = 1208 SOC_DAPM_ENUM("AMIC MUX2 Mux", tx_amic_mux2_enum); 1209 1210 static const struct snd_kcontrol_new tx_amic_mux3 = 1211 SOC_DAPM_ENUM("AMIC MUX3 Mux", tx_amic_mux3_enum); 1212 1213 static const struct snd_kcontrol_new tx_amic_mux4 = 1214 SOC_DAPM_ENUM("AMIC MUX4 Mux", tx_amic_mux4_enum); 1215 1216 static const struct snd_kcontrol_new tx_amic_mux5 = 1217 SOC_DAPM_ENUM("AMIC MUX5 Mux", tx_amic_mux5_enum); 1218 1219 static const struct snd_kcontrol_new tx_amic_mux6 = 1220 SOC_DAPM_ENUM("AMIC MUX6 Mux", tx_amic_mux6_enum); 1221 1222 static const struct snd_kcontrol_new tx_amic_mux7 = 1223 SOC_DAPM_ENUM("AMIC MUX7 Mux", tx_amic_mux7_enum); 1224 1225 static const struct snd_kcontrol_new tx_amic_mux8 = 1226 SOC_DAPM_ENUM("AMIC MUX8 Mux", tx_amic_mux8_enum); 1227 1228 static const struct snd_kcontrol_new sb_tx0_mux = 1229 SOC_DAPM_ENUM("SLIM TX0 MUX Mux", sb_tx0_mux_enum); 1230 1231 static const struct snd_kcontrol_new sb_tx1_mux = 1232 SOC_DAPM_ENUM("SLIM TX1 MUX Mux", sb_tx1_mux_enum); 1233 1234 static const struct snd_kcontrol_new sb_tx2_mux = 1235 SOC_DAPM_ENUM("SLIM TX2 MUX Mux", sb_tx2_mux_enum); 1236 1237 static const struct snd_kcontrol_new sb_tx3_mux = 1238 SOC_DAPM_ENUM("SLIM TX3 MUX Mux", sb_tx3_mux_enum); 1239 1240 static const struct snd_kcontrol_new sb_tx4_mux = 1241 SOC_DAPM_ENUM("SLIM TX4 MUX Mux", sb_tx4_mux_enum); 1242 1243 static const struct snd_kcontrol_new sb_tx5_mux = 1244 SOC_DAPM_ENUM("SLIM TX5 MUX Mux", sb_tx5_mux_enum); 1245 1246 static const struct snd_kcontrol_new sb_tx6_mux = 1247 SOC_DAPM_ENUM("SLIM TX6 MUX Mux", sb_tx6_mux_enum); 1248 1249 static const struct snd_kcontrol_new sb_tx7_mux = 1250 SOC_DAPM_ENUM("SLIM TX7 MUX Mux", sb_tx7_mux_enum); 1251 1252 static const struct snd_kcontrol_new sb_tx8_mux = 1253 SOC_DAPM_ENUM("SLIM TX8 MUX Mux", sb_tx8_mux_enum); 1254 1255 static int slim_rx_mux_get(struct snd_kcontrol *kc, 1256 struct snd_ctl_elem_value *ucontrol) 1257 { 1258 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); 1259 struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); 1260 u32 port_id = w->shift; 1261 1262 ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id]; 1263 1264 return 0; 1265 } 1266 1267 static int slim_rx_mux_put(struct snd_kcontrol *kc, 1268 struct snd_ctl_elem_value *ucontrol) 1269 { 1270 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); 1271 struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); 1272 struct soc_enum *e = (struct soc_enum *)kc->private_value; 1273 struct snd_soc_dapm_update *update = NULL; 1274 u32 port_id = w->shift; 1275 1276 if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) 1277 return 0; 1278 1279 wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; 1280 1281 /* Remove channel from any list it's in before adding it to a new one */ 1282 list_del_init(&wcd->rx_chs[port_id].list); 1283 1284 switch (wcd->rx_port_value[port_id]) { 1285 case 0: 1286 /* Channel already removed from lists. Nothing to do here */ 1287 break; 1288 case 1: 1289 list_add_tail(&wcd->rx_chs[port_id].list, 1290 &wcd->dai[AIF1_PB].slim_ch_list); 1291 break; 1292 case 2: 1293 list_add_tail(&wcd->rx_chs[port_id].list, 1294 &wcd->dai[AIF2_PB].slim_ch_list); 1295 break; 1296 case 3: 1297 list_add_tail(&wcd->rx_chs[port_id].list, 1298 &wcd->dai[AIF3_PB].slim_ch_list); 1299 break; 1300 case 4: 1301 list_add_tail(&wcd->rx_chs[port_id].list, 1302 &wcd->dai[AIF4_PB].slim_ch_list); 1303 break; 1304 default: 1305 dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value[port_id]); 1306 goto err; 1307 } 1308 1309 snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id], 1310 e, update); 1311 1312 return 0; 1313 err: 1314 return -EINVAL; 1315 } 1316 1317 static int slim_tx_mixer_get(struct snd_kcontrol *kc, 1318 struct snd_ctl_elem_value *ucontrol) 1319 { 1320 1321 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); 1322 struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev); 1323 struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); 1324 struct soc_mixer_control *mixer = 1325 (struct soc_mixer_control *)kc->private_value; 1326 int dai_id = widget->shift; 1327 int port_id = mixer->shift; 1328 1329 ucontrol->value.integer.value[0] = wcd->tx_port_value[port_id] == dai_id; 1330 1331 return 0; 1332 } 1333 1334 static int slim_tx_mixer_put(struct snd_kcontrol *kc, 1335 struct snd_ctl_elem_value *ucontrol) 1336 { 1337 1338 struct snd_soc_dapm_widget *widget = snd_soc_dapm_kcontrol_widget(kc); 1339 struct wcd9335_codec *wcd = dev_get_drvdata(widget->dapm->dev); 1340 struct snd_soc_dapm_update *update = NULL; 1341 struct soc_mixer_control *mixer = 1342 (struct soc_mixer_control *)kc->private_value; 1343 int enable = ucontrol->value.integer.value[0]; 1344 int dai_id = widget->shift; 1345 int port_id = mixer->shift; 1346 1347 switch (dai_id) { 1348 case AIF1_CAP: 1349 case AIF2_CAP: 1350 case AIF3_CAP: 1351 /* only add to the list if value not set */ 1352 if (enable && wcd->tx_port_value[port_id] != dai_id) { 1353 wcd->tx_port_value[port_id] = dai_id; 1354 list_add_tail(&wcd->tx_chs[port_id].list, 1355 &wcd->dai[dai_id].slim_ch_list); 1356 } else if (!enable && wcd->tx_port_value[port_id] == dai_id) { 1357 wcd->tx_port_value[port_id] = -1; 1358 list_del_init(&wcd->tx_chs[port_id].list); 1359 } 1360 break; 1361 default: 1362 dev_err(wcd->dev, "Unknown AIF %d\n", dai_id); 1363 return -EINVAL; 1364 } 1365 1366 snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update); 1367 1368 return 0; 1369 } 1370 1371 static const struct snd_kcontrol_new slim_rx_mux[WCD9335_RX_MAX] = { 1372 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum, 1373 slim_rx_mux_get, slim_rx_mux_put), 1374 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum, 1375 slim_rx_mux_get, slim_rx_mux_put), 1376 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum, 1377 slim_rx_mux_get, slim_rx_mux_put), 1378 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum, 1379 slim_rx_mux_get, slim_rx_mux_put), 1380 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum, 1381 slim_rx_mux_get, slim_rx_mux_put), 1382 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum, 1383 slim_rx_mux_get, slim_rx_mux_put), 1384 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum, 1385 slim_rx_mux_get, slim_rx_mux_put), 1386 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum, 1387 slim_rx_mux_get, slim_rx_mux_put), 1388 }; 1389 1390 static const struct snd_kcontrol_new aif1_cap_mixer[] = { 1391 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0, 1392 slim_tx_mixer_get, slim_tx_mixer_put), 1393 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0, 1394 slim_tx_mixer_get, slim_tx_mixer_put), 1395 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0, 1396 slim_tx_mixer_get, slim_tx_mixer_put), 1397 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0, 1398 slim_tx_mixer_get, slim_tx_mixer_put), 1399 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0, 1400 slim_tx_mixer_get, slim_tx_mixer_put), 1401 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0, 1402 slim_tx_mixer_get, slim_tx_mixer_put), 1403 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0, 1404 slim_tx_mixer_get, slim_tx_mixer_put), 1405 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0, 1406 slim_tx_mixer_get, slim_tx_mixer_put), 1407 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0, 1408 slim_tx_mixer_get, slim_tx_mixer_put), 1409 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9335_TX9, 1, 0, 1410 slim_tx_mixer_get, slim_tx_mixer_put), 1411 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9335_TX10, 1, 0, 1412 slim_tx_mixer_get, slim_tx_mixer_put), 1413 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9335_TX11, 1, 0, 1414 slim_tx_mixer_get, slim_tx_mixer_put), 1415 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9335_TX13, 1, 0, 1416 slim_tx_mixer_get, slim_tx_mixer_put), 1417 }; 1418 1419 static const struct snd_kcontrol_new aif2_cap_mixer[] = { 1420 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0, 1421 slim_tx_mixer_get, slim_tx_mixer_put), 1422 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0, 1423 slim_tx_mixer_get, slim_tx_mixer_put), 1424 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0, 1425 slim_tx_mixer_get, slim_tx_mixer_put), 1426 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0, 1427 slim_tx_mixer_get, slim_tx_mixer_put), 1428 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0, 1429 slim_tx_mixer_get, slim_tx_mixer_put), 1430 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0, 1431 slim_tx_mixer_get, slim_tx_mixer_put), 1432 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0, 1433 slim_tx_mixer_get, slim_tx_mixer_put), 1434 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0, 1435 slim_tx_mixer_get, slim_tx_mixer_put), 1436 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0, 1437 slim_tx_mixer_get, slim_tx_mixer_put), 1438 SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9335_TX9, 1, 0, 1439 slim_tx_mixer_get, slim_tx_mixer_put), 1440 SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9335_TX10, 1, 0, 1441 slim_tx_mixer_get, slim_tx_mixer_put), 1442 SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9335_TX11, 1, 0, 1443 slim_tx_mixer_get, slim_tx_mixer_put), 1444 SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9335_TX13, 1, 0, 1445 slim_tx_mixer_get, slim_tx_mixer_put), 1446 }; 1447 1448 static const struct snd_kcontrol_new aif3_cap_mixer[] = { 1449 SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9335_TX0, 1, 0, 1450 slim_tx_mixer_get, slim_tx_mixer_put), 1451 SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9335_TX1, 1, 0, 1452 slim_tx_mixer_get, slim_tx_mixer_put), 1453 SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9335_TX2, 1, 0, 1454 slim_tx_mixer_get, slim_tx_mixer_put), 1455 SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9335_TX3, 1, 0, 1456 slim_tx_mixer_get, slim_tx_mixer_put), 1457 SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9335_TX4, 1, 0, 1458 slim_tx_mixer_get, slim_tx_mixer_put), 1459 SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9335_TX5, 1, 0, 1460 slim_tx_mixer_get, slim_tx_mixer_put), 1461 SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9335_TX6, 1, 0, 1462 slim_tx_mixer_get, slim_tx_mixer_put), 1463 SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9335_TX7, 1, 0, 1464 slim_tx_mixer_get, slim_tx_mixer_put), 1465 SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9335_TX8, 1, 0, 1466 slim_tx_mixer_get, slim_tx_mixer_put), 1467 }; 1468 1469 static int wcd9335_put_dec_enum(struct snd_kcontrol *kc, 1470 struct snd_ctl_elem_value *ucontrol) 1471 { 1472 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); 1473 struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); 1474 struct soc_enum *e = (struct soc_enum *)kc->private_value; 1475 unsigned int val, reg, sel; 1476 1477 val = ucontrol->value.enumerated.item[0]; 1478 1479 switch (e->reg) { 1480 case WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1: 1481 reg = WCD9335_CDC_TX0_TX_PATH_CFG0; 1482 break; 1483 case WCD9335_CDC_TX_INP_MUX_ADC_MUX1_CFG1: 1484 reg = WCD9335_CDC_TX1_TX_PATH_CFG0; 1485 break; 1486 case WCD9335_CDC_TX_INP_MUX_ADC_MUX2_CFG1: 1487 reg = WCD9335_CDC_TX2_TX_PATH_CFG0; 1488 break; 1489 case WCD9335_CDC_TX_INP_MUX_ADC_MUX3_CFG1: 1490 reg = WCD9335_CDC_TX3_TX_PATH_CFG0; 1491 break; 1492 case WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0: 1493 reg = WCD9335_CDC_TX4_TX_PATH_CFG0; 1494 break; 1495 case WCD9335_CDC_TX_INP_MUX_ADC_MUX5_CFG0: 1496 reg = WCD9335_CDC_TX5_TX_PATH_CFG0; 1497 break; 1498 case WCD9335_CDC_TX_INP_MUX_ADC_MUX6_CFG0: 1499 reg = WCD9335_CDC_TX6_TX_PATH_CFG0; 1500 break; 1501 case WCD9335_CDC_TX_INP_MUX_ADC_MUX7_CFG0: 1502 reg = WCD9335_CDC_TX7_TX_PATH_CFG0; 1503 break; 1504 case WCD9335_CDC_TX_INP_MUX_ADC_MUX8_CFG0: 1505 reg = WCD9335_CDC_TX8_TX_PATH_CFG0; 1506 break; 1507 default: 1508 return -EINVAL; 1509 } 1510 1511 /* AMIC: 0, DMIC: 1 */ 1512 sel = val ? WCD9335_CDC_TX_ADC_AMIC_SEL : WCD9335_CDC_TX_ADC_DMIC_SEL; 1513 snd_soc_component_update_bits(component, reg, 1514 WCD9335_CDC_TX_ADC_AMIC_DMIC_SEL_MASK, 1515 sel); 1516 1517 return snd_soc_dapm_put_enum_double(kc, ucontrol); 1518 } 1519 1520 static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc, 1521 struct snd_ctl_elem_value *ucontrol) 1522 { 1523 struct soc_enum *e = (struct soc_enum *)kc->private_value; 1524 struct snd_soc_component *component; 1525 int reg, val; 1526 1527 component = snd_soc_dapm_kcontrol_component(kc); 1528 val = ucontrol->value.enumerated.item[0]; 1529 1530 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0) 1531 reg = WCD9335_CDC_RX0_RX_PATH_CFG0; 1532 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0) 1533 reg = WCD9335_CDC_RX1_RX_PATH_CFG0; 1534 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0) 1535 reg = WCD9335_CDC_RX2_RX_PATH_CFG0; 1536 else 1537 return -EINVAL; 1538 1539 /* Set Look Ahead Delay */ 1540 snd_soc_component_update_bits(component, reg, 1541 WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN_MASK, 1542 val ? WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN : 0); 1543 /* Set DEM INP Select */ 1544 return snd_soc_dapm_put_enum_double(kc, ucontrol); 1545 } 1546 1547 static const struct snd_kcontrol_new rx_int0_dem_inp_mux = 1548 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum, 1549 snd_soc_dapm_get_enum_double, 1550 wcd9335_int_dem_inp_mux_put); 1551 1552 static const struct snd_kcontrol_new rx_int1_dem_inp_mux = 1553 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum, 1554 snd_soc_dapm_get_enum_double, 1555 wcd9335_int_dem_inp_mux_put); 1556 1557 static const struct snd_kcontrol_new rx_int2_dem_inp_mux = 1558 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum, 1559 snd_soc_dapm_get_enum_double, 1560 wcd9335_int_dem_inp_mux_put); 1561 1562 static const struct snd_kcontrol_new tx_adc_mux0 = 1563 SOC_DAPM_ENUM_EXT("ADC MUX0 Mux", tx_adc_mux0_chain_enum, 1564 snd_soc_dapm_get_enum_double, 1565 wcd9335_put_dec_enum); 1566 1567 static const struct snd_kcontrol_new tx_adc_mux1 = 1568 SOC_DAPM_ENUM_EXT("ADC MUX1 Mux", tx_adc_mux1_chain_enum, 1569 snd_soc_dapm_get_enum_double, 1570 wcd9335_put_dec_enum); 1571 1572 static const struct snd_kcontrol_new tx_adc_mux2 = 1573 SOC_DAPM_ENUM_EXT("ADC MUX2 Mux", tx_adc_mux2_chain_enum, 1574 snd_soc_dapm_get_enum_double, 1575 wcd9335_put_dec_enum); 1576 1577 static const struct snd_kcontrol_new tx_adc_mux3 = 1578 SOC_DAPM_ENUM_EXT("ADC MUX3 Mux", tx_adc_mux3_chain_enum, 1579 snd_soc_dapm_get_enum_double, 1580 wcd9335_put_dec_enum); 1581 1582 static const struct snd_kcontrol_new tx_adc_mux4 = 1583 SOC_DAPM_ENUM_EXT("ADC MUX4 Mux", tx_adc_mux4_chain_enum, 1584 snd_soc_dapm_get_enum_double, 1585 wcd9335_put_dec_enum); 1586 1587 static const struct snd_kcontrol_new tx_adc_mux5 = 1588 SOC_DAPM_ENUM_EXT("ADC MUX5 Mux", tx_adc_mux5_chain_enum, 1589 snd_soc_dapm_get_enum_double, 1590 wcd9335_put_dec_enum); 1591 1592 static const struct snd_kcontrol_new tx_adc_mux6 = 1593 SOC_DAPM_ENUM_EXT("ADC MUX6 Mux", tx_adc_mux6_chain_enum, 1594 snd_soc_dapm_get_enum_double, 1595 wcd9335_put_dec_enum); 1596 1597 static const struct snd_kcontrol_new tx_adc_mux7 = 1598 SOC_DAPM_ENUM_EXT("ADC MUX7 Mux", tx_adc_mux7_chain_enum, 1599 snd_soc_dapm_get_enum_double, 1600 wcd9335_put_dec_enum); 1601 1602 static const struct snd_kcontrol_new tx_adc_mux8 = 1603 SOC_DAPM_ENUM_EXT("ADC MUX8 Mux", tx_adc_mux8_chain_enum, 1604 snd_soc_dapm_get_enum_double, 1605 wcd9335_put_dec_enum); 1606 1607 static int wcd9335_set_mix_interpolator_rate(struct snd_soc_dai *dai, 1608 int rate_val, 1609 u32 rate) 1610 { 1611 struct snd_soc_component *component = dai->component; 1612 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1613 struct wcd9335_slim_ch *ch; 1614 int val, j; 1615 1616 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { 1617 for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) { 1618 val = snd_soc_component_read(component, 1619 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)) & 1620 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1621 1622 if (val == (ch->shift + INTn_2_INP_SEL_RX0)) 1623 snd_soc_component_update_bits(component, 1624 WCD9335_CDC_RX_PATH_MIX_CTL(j), 1625 WCD9335_CDC_MIX_PCM_RATE_MASK, 1626 rate_val); 1627 } 1628 } 1629 1630 return 0; 1631 } 1632 1633 static int wcd9335_set_prim_interpolator_rate(struct snd_soc_dai *dai, 1634 u8 rate_val, 1635 u32 rate) 1636 { 1637 struct snd_soc_component *comp = dai->component; 1638 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 1639 struct wcd9335_slim_ch *ch; 1640 u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel; 1641 int inp, j; 1642 1643 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { 1644 inp = ch->shift + INTn_1_MIX_INP_SEL_RX0; 1645 /* 1646 * Loop through all interpolator MUX inputs and find out 1647 * to which interpolator input, the slim rx port 1648 * is connected 1649 */ 1650 for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) { 1651 cfg0 = snd_soc_component_read(comp, 1652 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG0(j)); 1653 cfg1 = snd_soc_component_read(comp, 1654 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)); 1655 1656 inp0_sel = cfg0 & 1657 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1658 inp1_sel = (cfg0 >> 4) & 1659 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1660 inp2_sel = (cfg1 >> 4) & 1661 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1662 1663 if ((inp0_sel == inp) || (inp1_sel == inp) || 1664 (inp2_sel == inp)) { 1665 /* rate is in Hz */ 1666 if ((j == 0) && (rate == 44100)) 1667 dev_info(wcd->dev, 1668 "Cannot set 44.1KHz on INT0\n"); 1669 else 1670 snd_soc_component_update_bits(comp, 1671 WCD9335_CDC_RX_PATH_CTL(j), 1672 WCD9335_CDC_MIX_PCM_RATE_MASK, 1673 rate_val); 1674 } 1675 } 1676 } 1677 1678 return 0; 1679 } 1680 1681 static int wcd9335_set_interpolator_rate(struct snd_soc_dai *dai, u32 rate) 1682 { 1683 int i; 1684 1685 /* set mixing path rate */ 1686 for (i = 0; i < ARRAY_SIZE(int_mix_rate_val); i++) { 1687 if (rate == int_mix_rate_val[i].rate) { 1688 wcd9335_set_mix_interpolator_rate(dai, 1689 int_mix_rate_val[i].rate_val, rate); 1690 break; 1691 } 1692 } 1693 1694 /* set primary path sample rate */ 1695 for (i = 0; i < ARRAY_SIZE(int_prim_rate_val); i++) { 1696 if (rate == int_prim_rate_val[i].rate) { 1697 wcd9335_set_prim_interpolator_rate(dai, 1698 int_prim_rate_val[i].rate_val, rate); 1699 break; 1700 } 1701 } 1702 1703 return 0; 1704 } 1705 1706 static int wcd9335_slim_set_hw_params(struct wcd9335_codec *wcd, 1707 struct wcd_slim_codec_dai_data *dai_data, 1708 int direction) 1709 { 1710 struct list_head *slim_ch_list = &dai_data->slim_ch_list; 1711 struct slim_stream_config *cfg = &dai_data->sconfig; 1712 struct wcd9335_slim_ch *ch; 1713 u16 payload = 0; 1714 int ret, i; 1715 1716 cfg->ch_count = 0; 1717 cfg->direction = direction; 1718 cfg->port_mask = 0; 1719 1720 /* Configure slave interface device */ 1721 list_for_each_entry(ch, slim_ch_list, list) { 1722 cfg->ch_count++; 1723 payload |= 1 << ch->shift; 1724 cfg->port_mask |= BIT(ch->port); 1725 } 1726 1727 cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL); 1728 if (!cfg->chs) 1729 return -ENOMEM; 1730 1731 i = 0; 1732 list_for_each_entry(ch, slim_ch_list, list) { 1733 cfg->chs[i++] = ch->ch_num; 1734 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 1735 /* write to interface device */ 1736 ret = regmap_write(wcd->if_regmap, 1737 WCD9335_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port), 1738 payload); 1739 1740 if (ret < 0) 1741 goto err; 1742 1743 /* configure the slave port for water mark and enable*/ 1744 ret = regmap_write(wcd->if_regmap, 1745 WCD9335_SLIM_PGD_RX_PORT_CFG(ch->port), 1746 WCD9335_SLIM_WATER_MARK_VAL); 1747 if (ret < 0) 1748 goto err; 1749 } else { 1750 ret = regmap_write(wcd->if_regmap, 1751 WCD9335_SLIM_PGD_TX_PORT_MULTI_CHNL_0(ch->port), 1752 payload & 0x00FF); 1753 if (ret < 0) 1754 goto err; 1755 1756 /* ports 8,9 */ 1757 ret = regmap_write(wcd->if_regmap, 1758 WCD9335_SLIM_PGD_TX_PORT_MULTI_CHNL_1(ch->port), 1759 (payload & 0xFF00)>>8); 1760 if (ret < 0) 1761 goto err; 1762 1763 /* configure the slave port for water mark and enable*/ 1764 ret = regmap_write(wcd->if_regmap, 1765 WCD9335_SLIM_PGD_TX_PORT_CFG(ch->port), 1766 WCD9335_SLIM_WATER_MARK_VAL); 1767 1768 if (ret < 0) 1769 goto err; 1770 } 1771 } 1772 1773 dai_data->sruntime = slim_stream_allocate(wcd->slim, "WCD9335-SLIM"); 1774 1775 return 0; 1776 1777 err: 1778 dev_err(wcd->dev, "Error Setting slim hw params\n"); 1779 kfree(cfg->chs); 1780 cfg->chs = NULL; 1781 1782 return ret; 1783 } 1784 1785 static int wcd9335_set_decimator_rate(struct snd_soc_dai *dai, 1786 u8 rate_val, u32 rate) 1787 { 1788 struct snd_soc_component *comp = dai->component; 1789 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp); 1790 u8 shift = 0, shift_val = 0, tx_mux_sel; 1791 struct wcd9335_slim_ch *ch; 1792 int tx_port, tx_port_reg; 1793 int decimator = -1; 1794 1795 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { 1796 tx_port = ch->port; 1797 if ((tx_port == 12) || (tx_port >= 14)) { 1798 dev_err(wcd->dev, "Invalid SLIM TX%u port DAI ID:%d\n", 1799 tx_port, dai->id); 1800 return -EINVAL; 1801 } 1802 /* Find the SB TX MUX input - which decimator is connected */ 1803 if (tx_port < 4) { 1804 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG0; 1805 shift = (tx_port << 1); 1806 shift_val = 0x03; 1807 } else if (tx_port < 8) { 1808 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG1; 1809 shift = ((tx_port - 4) << 1); 1810 shift_val = 0x03; 1811 } else if (tx_port < 11) { 1812 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG2; 1813 shift = ((tx_port - 8) << 1); 1814 shift_val = 0x03; 1815 } else if (tx_port == 11) { 1816 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3; 1817 shift = 0; 1818 shift_val = 0x0F; 1819 } else /* (tx_port == 13) */ { 1820 tx_port_reg = WCD9335_CDC_IF_ROUTER_TX_MUX_CFG3; 1821 shift = 4; 1822 shift_val = 0x03; 1823 } 1824 1825 tx_mux_sel = snd_soc_component_read(comp, tx_port_reg) & 1826 (shift_val << shift); 1827 1828 tx_mux_sel = tx_mux_sel >> shift; 1829 if (tx_port <= 8) { 1830 if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3)) 1831 decimator = tx_port; 1832 } else if (tx_port <= 10) { 1833 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) 1834 decimator = ((tx_port == 9) ? 7 : 6); 1835 } else if (tx_port == 11) { 1836 if ((tx_mux_sel >= 1) && (tx_mux_sel < 7)) 1837 decimator = tx_mux_sel - 1; 1838 } else if (tx_port == 13) { 1839 if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2)) 1840 decimator = 5; 1841 } 1842 1843 if (decimator >= 0) { 1844 snd_soc_component_update_bits(comp, 1845 WCD9335_CDC_TX_PATH_CTL(decimator), 1846 WCD9335_CDC_TX_PATH_CTL_PCM_RATE_MASK, 1847 rate_val); 1848 } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) { 1849 /* Check if the TX Mux input is RX MIX TXn */ 1850 dev_err(wcd->dev, "RX_MIX_TX%u going to SLIM TX%u\n", 1851 tx_port, tx_port); 1852 } else { 1853 dev_err(wcd->dev, "ERROR: Invalid decimator: %d\n", 1854 decimator); 1855 return -EINVAL; 1856 } 1857 } 1858 1859 return 0; 1860 } 1861 1862 static int wcd9335_hw_params(struct snd_pcm_substream *substream, 1863 struct snd_pcm_hw_params *params, 1864 struct snd_soc_dai *dai) 1865 { 1866 struct wcd9335_codec *wcd; 1867 int ret, tx_fs_rate = 0; 1868 1869 wcd = snd_soc_component_get_drvdata(dai->component); 1870 1871 switch (substream->stream) { 1872 case SNDRV_PCM_STREAM_PLAYBACK: 1873 ret = wcd9335_set_interpolator_rate(dai, params_rate(params)); 1874 if (ret) { 1875 dev_err(wcd->dev, "cannot set sample rate: %u\n", 1876 params_rate(params)); 1877 return ret; 1878 } 1879 switch (params_width(params)) { 1880 case 16 ... 24: 1881 wcd->dai[dai->id].sconfig.bps = params_width(params); 1882 break; 1883 default: 1884 dev_err(wcd->dev, "%s: Invalid format 0x%x\n", 1885 __func__, params_width(params)); 1886 return -EINVAL; 1887 } 1888 break; 1889 1890 case SNDRV_PCM_STREAM_CAPTURE: 1891 switch (params_rate(params)) { 1892 case 8000: 1893 tx_fs_rate = 0; 1894 break; 1895 case 16000: 1896 tx_fs_rate = 1; 1897 break; 1898 case 32000: 1899 tx_fs_rate = 3; 1900 break; 1901 case 48000: 1902 tx_fs_rate = 4; 1903 break; 1904 case 96000: 1905 tx_fs_rate = 5; 1906 break; 1907 case 192000: 1908 tx_fs_rate = 6; 1909 break; 1910 case 384000: 1911 tx_fs_rate = 7; 1912 break; 1913 default: 1914 dev_err(wcd->dev, "%s: Invalid TX sample rate: %d\n", 1915 __func__, params_rate(params)); 1916 return -EINVAL; 1917 1918 } 1919 1920 ret = wcd9335_set_decimator_rate(dai, tx_fs_rate, 1921 params_rate(params)); 1922 if (ret < 0) { 1923 dev_err(wcd->dev, "Cannot set TX Decimator rate\n"); 1924 return ret; 1925 } 1926 switch (params_width(params)) { 1927 case 16 ... 32: 1928 wcd->dai[dai->id].sconfig.bps = params_width(params); 1929 break; 1930 default: 1931 dev_err(wcd->dev, "%s: Invalid format 0x%x\n", 1932 __func__, params_width(params)); 1933 return -EINVAL; 1934 } 1935 break; 1936 default: 1937 dev_err(wcd->dev, "Invalid stream type %d\n", 1938 substream->stream); 1939 return -EINVAL; 1940 } 1941 1942 wcd->dai[dai->id].sconfig.rate = params_rate(params); 1943 wcd9335_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream); 1944 1945 return 0; 1946 } 1947 1948 static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd, 1949 struct snd_soc_dai *dai) 1950 { 1951 struct wcd_slim_codec_dai_data *dai_data; 1952 struct wcd9335_codec *wcd; 1953 struct slim_stream_config *cfg; 1954 1955 wcd = snd_soc_component_get_drvdata(dai->component); 1956 1957 dai_data = &wcd->dai[dai->id]; 1958 1959 switch (cmd) { 1960 case SNDRV_PCM_TRIGGER_START: 1961 case SNDRV_PCM_TRIGGER_RESUME: 1962 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1963 cfg = &dai_data->sconfig; 1964 slim_stream_prepare(dai_data->sruntime, cfg); 1965 slim_stream_enable(dai_data->sruntime); 1966 break; 1967 case SNDRV_PCM_TRIGGER_STOP: 1968 case SNDRV_PCM_TRIGGER_SUSPEND: 1969 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1970 slim_stream_disable(dai_data->sruntime); 1971 slim_stream_unprepare(dai_data->sruntime); 1972 break; 1973 default: 1974 break; 1975 } 1976 1977 return 0; 1978 } 1979 1980 static int wcd9335_set_channel_map(struct snd_soc_dai *dai, 1981 unsigned int tx_num, 1982 const unsigned int *tx_slot, 1983 unsigned int rx_num, 1984 const unsigned int *rx_slot) 1985 { 1986 struct wcd9335_codec *wcd; 1987 int i; 1988 1989 wcd = snd_soc_component_get_drvdata(dai->component); 1990 1991 if (!tx_slot || !rx_slot) { 1992 dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n", 1993 tx_slot, rx_slot); 1994 return -EINVAL; 1995 } 1996 1997 wcd->num_rx_port = rx_num; 1998 for (i = 0; i < rx_num; i++) { 1999 wcd->rx_chs[i].ch_num = rx_slot[i]; 2000 INIT_LIST_HEAD(&wcd->rx_chs[i].list); 2001 } 2002 2003 wcd->num_tx_port = tx_num; 2004 for (i = 0; i < tx_num; i++) { 2005 wcd->tx_chs[i].ch_num = tx_slot[i]; 2006 INIT_LIST_HEAD(&wcd->tx_chs[i].list); 2007 } 2008 2009 return 0; 2010 } 2011 2012 static int wcd9335_get_channel_map(const struct snd_soc_dai *dai, 2013 unsigned int *tx_num, unsigned int *tx_slot, 2014 unsigned int *rx_num, unsigned int *rx_slot) 2015 { 2016 struct wcd9335_slim_ch *ch; 2017 struct wcd9335_codec *wcd; 2018 int i = 0; 2019 2020 wcd = snd_soc_component_get_drvdata(dai->component); 2021 2022 switch (dai->id) { 2023 case AIF1_PB: 2024 case AIF2_PB: 2025 case AIF3_PB: 2026 case AIF4_PB: 2027 if (!rx_slot || !rx_num) { 2028 dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n", 2029 rx_slot, rx_num); 2030 return -EINVAL; 2031 } 2032 2033 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) 2034 rx_slot[i++] = ch->ch_num; 2035 2036 *rx_num = i; 2037 break; 2038 case AIF1_CAP: 2039 case AIF2_CAP: 2040 case AIF3_CAP: 2041 if (!tx_slot || !tx_num) { 2042 dev_err(wcd->dev, "Invalid tx_slot %p or tx_num %p\n", 2043 tx_slot, tx_num); 2044 return -EINVAL; 2045 } 2046 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) 2047 tx_slot[i++] = ch->ch_num; 2048 2049 *tx_num = i; 2050 break; 2051 default: 2052 dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id); 2053 break; 2054 } 2055 2056 return 0; 2057 } 2058 2059 static const struct snd_soc_dai_ops wcd9335_dai_ops = { 2060 .hw_params = wcd9335_hw_params, 2061 .trigger = wcd9335_trigger, 2062 .set_channel_map = wcd9335_set_channel_map, 2063 .get_channel_map = wcd9335_get_channel_map, 2064 }; 2065 2066 static struct snd_soc_dai_driver wcd9335_slim_dais[] = { 2067 [0] = { 2068 .name = "wcd9335_rx1", 2069 .id = AIF1_PB, 2070 .playback = { 2071 .stream_name = "AIF1 Playback", 2072 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | 2073 SNDRV_PCM_RATE_384000, 2074 .formats = WCD9335_FORMATS_S16_S24_LE, 2075 .rate_max = 384000, 2076 .rate_min = 8000, 2077 .channels_min = 1, 2078 .channels_max = 2, 2079 }, 2080 .ops = &wcd9335_dai_ops, 2081 }, 2082 [1] = { 2083 .name = "wcd9335_tx1", 2084 .id = AIF1_CAP, 2085 .capture = { 2086 .stream_name = "AIF1 Capture", 2087 .rates = WCD9335_RATES_MASK, 2088 .formats = SNDRV_PCM_FMTBIT_S16_LE, 2089 .rate_min = 8000, 2090 .rate_max = 192000, 2091 .channels_min = 1, 2092 .channels_max = 4, 2093 }, 2094 .ops = &wcd9335_dai_ops, 2095 }, 2096 [2] = { 2097 .name = "wcd9335_rx2", 2098 .id = AIF2_PB, 2099 .playback = { 2100 .stream_name = "AIF2 Playback", 2101 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | 2102 SNDRV_PCM_RATE_384000, 2103 .formats = WCD9335_FORMATS_S16_S24_LE, 2104 .rate_min = 8000, 2105 .rate_max = 384000, 2106 .channels_min = 1, 2107 .channels_max = 2, 2108 }, 2109 .ops = &wcd9335_dai_ops, 2110 }, 2111 [3] = { 2112 .name = "wcd9335_tx2", 2113 .id = AIF2_CAP, 2114 .capture = { 2115 .stream_name = "AIF2 Capture", 2116 .rates = WCD9335_RATES_MASK, 2117 .formats = SNDRV_PCM_FMTBIT_S16_LE, 2118 .rate_min = 8000, 2119 .rate_max = 192000, 2120 .channels_min = 1, 2121 .channels_max = 4, 2122 }, 2123 .ops = &wcd9335_dai_ops, 2124 }, 2125 [4] = { 2126 .name = "wcd9335_rx3", 2127 .id = AIF3_PB, 2128 .playback = { 2129 .stream_name = "AIF3 Playback", 2130 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | 2131 SNDRV_PCM_RATE_384000, 2132 .formats = WCD9335_FORMATS_S16_S24_LE, 2133 .rate_min = 8000, 2134 .rate_max = 384000, 2135 .channels_min = 1, 2136 .channels_max = 2, 2137 }, 2138 .ops = &wcd9335_dai_ops, 2139 }, 2140 [5] = { 2141 .name = "wcd9335_tx3", 2142 .id = AIF3_CAP, 2143 .capture = { 2144 .stream_name = "AIF3 Capture", 2145 .rates = WCD9335_RATES_MASK, 2146 .formats = SNDRV_PCM_FMTBIT_S16_LE, 2147 .rate_min = 8000, 2148 .rate_max = 192000, 2149 .channels_min = 1, 2150 .channels_max = 4, 2151 }, 2152 .ops = &wcd9335_dai_ops, 2153 }, 2154 [6] = { 2155 .name = "wcd9335_rx4", 2156 .id = AIF4_PB, 2157 .playback = { 2158 .stream_name = "AIF4 Playback", 2159 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK | 2160 SNDRV_PCM_RATE_384000, 2161 .formats = WCD9335_FORMATS_S16_S24_LE, 2162 .rate_min = 8000, 2163 .rate_max = 384000, 2164 .channels_min = 1, 2165 .channels_max = 2, 2166 }, 2167 .ops = &wcd9335_dai_ops, 2168 }, 2169 }; 2170 2171 static int wcd9335_get_compander(struct snd_kcontrol *kc, 2172 struct snd_ctl_elem_value *ucontrol) 2173 { 2174 2175 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 2176 int comp = ((struct soc_mixer_control *)kc->private_value)->shift; 2177 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 2178 2179 ucontrol->value.integer.value[0] = wcd->comp_enabled[comp]; 2180 return 0; 2181 } 2182 2183 static int wcd9335_set_compander(struct snd_kcontrol *kc, 2184 struct snd_ctl_elem_value *ucontrol) 2185 { 2186 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 2187 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 2188 int comp = ((struct soc_mixer_control *) kc->private_value)->shift; 2189 int value = ucontrol->value.integer.value[0]; 2190 int sel; 2191 2192 wcd->comp_enabled[comp] = value; 2193 sel = value ? WCD9335_HPH_GAIN_SRC_SEL_COMPANDER : 2194 WCD9335_HPH_GAIN_SRC_SEL_REGISTER; 2195 2196 /* Any specific register configuration for compander */ 2197 switch (comp) { 2198 case COMPANDER_1: 2199 /* Set Gain Source Select based on compander enable/disable */ 2200 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 2201 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 2202 break; 2203 case COMPANDER_2: 2204 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 2205 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 2206 break; 2207 case COMPANDER_5: 2208 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN, 2209 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 2210 break; 2211 case COMPANDER_6: 2212 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN, 2213 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 2214 break; 2215 default: 2216 break; 2217 } 2218 2219 return 0; 2220 } 2221 2222 static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc, 2223 struct snd_ctl_elem_value *ucontrol) 2224 { 2225 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 2226 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 2227 2228 ucontrol->value.enumerated.item[0] = wcd->hph_mode; 2229 2230 return 0; 2231 } 2232 2233 static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, 2234 struct snd_ctl_elem_value *ucontrol) 2235 { 2236 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 2237 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 2238 u32 mode_val; 2239 2240 mode_val = ucontrol->value.enumerated.item[0]; 2241 2242 if (mode_val == 0) { 2243 dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n"); 2244 mode_val = CLS_H_HIFI; 2245 } 2246 wcd->hph_mode = mode_val; 2247 2248 return 0; 2249 } 2250 2251 static const struct snd_kcontrol_new wcd9335_snd_controls[] = { 2252 /* -84dB min - 40dB max */ 2253 SOC_SINGLE_S8_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, 2254 -84, 40, digital_gain), 2255 SOC_SINGLE_S8_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, 2256 -84, 40, digital_gain), 2257 SOC_SINGLE_S8_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, 2258 -84, 40, digital_gain), 2259 SOC_SINGLE_S8_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, 2260 -84, 40, digital_gain), 2261 SOC_SINGLE_S8_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, 2262 -84, 40, digital_gain), 2263 SOC_SINGLE_S8_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, 2264 -84, 40, digital_gain), 2265 SOC_SINGLE_S8_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, 2266 -84, 40, digital_gain), 2267 SOC_SINGLE_S8_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, 2268 -84, 40, digital_gain), 2269 SOC_SINGLE_S8_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, 2270 -84, 40, digital_gain), 2271 SOC_SINGLE_S8_TLV("RX0 Mix Digital Volume", WCD9335_CDC_RX0_RX_VOL_MIX_CTL, 2272 -84, 40, digital_gain), 2273 SOC_SINGLE_S8_TLV("RX1 Mix Digital Volume", WCD9335_CDC_RX1_RX_VOL_MIX_CTL, 2274 -84, 40, digital_gain), 2275 SOC_SINGLE_S8_TLV("RX2 Mix Digital Volume", WCD9335_CDC_RX2_RX_VOL_MIX_CTL, 2276 -84, 40, digital_gain), 2277 SOC_SINGLE_S8_TLV("RX3 Mix Digital Volume", WCD9335_CDC_RX3_RX_VOL_MIX_CTL, 2278 -84, 40, digital_gain), 2279 SOC_SINGLE_S8_TLV("RX4 Mix Digital Volume", WCD9335_CDC_RX4_RX_VOL_MIX_CTL, 2280 -84, 40, digital_gain), 2281 SOC_SINGLE_S8_TLV("RX5 Mix Digital Volume", WCD9335_CDC_RX5_RX_VOL_MIX_CTL, 2282 -84, 40, digital_gain), 2283 SOC_SINGLE_S8_TLV("RX6 Mix Digital Volume", WCD9335_CDC_RX6_RX_VOL_MIX_CTL, 2284 -84, 40, digital_gain), 2285 SOC_SINGLE_S8_TLV("RX7 Mix Digital Volume", WCD9335_CDC_RX7_RX_VOL_MIX_CTL, 2286 -84, 40, digital_gain), 2287 SOC_SINGLE_S8_TLV("RX8 Mix Digital Volume", WCD9335_CDC_RX8_RX_VOL_MIX_CTL, 2288 -84, 40, digital_gain), 2289 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), 2290 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), 2291 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), 2292 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum), 2293 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum), 2294 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum), 2295 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum), 2296 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum), 2297 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum), 2298 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum), 2299 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum), 2300 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum), 2301 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum), 2302 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum), 2303 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), 2304 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), 2305 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), 2306 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), 2307 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, 2308 wcd9335_get_compander, wcd9335_set_compander), 2309 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, 2310 wcd9335_get_compander, wcd9335_set_compander), 2311 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0, 2312 wcd9335_get_compander, wcd9335_set_compander), 2313 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0, 2314 wcd9335_get_compander, wcd9335_set_compander), 2315 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0, 2316 wcd9335_get_compander, wcd9335_set_compander), 2317 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0, 2318 wcd9335_get_compander, wcd9335_set_compander), 2319 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, 2320 wcd9335_get_compander, wcd9335_set_compander), 2321 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, 2322 wcd9335_get_compander, wcd9335_set_compander), 2323 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, 2324 wcd9335_rx_hph_mode_get, wcd9335_rx_hph_mode_put), 2325 2326 /* Gain Controls */ 2327 SOC_SINGLE_TLV("EAR PA Volume", WCD9335_ANA_EAR, 4, 4, 1, 2328 ear_pa_gain), 2329 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1, 2330 line_gain), 2331 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1, 2332 line_gain), 2333 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER, 2334 3, 16, 1, line_gain), 2335 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER, 2336 3, 16, 1, line_gain), 2337 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1, 2338 line_gain), 2339 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1, 2340 line_gain), 2341 2342 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0, 2343 analog_gain), 2344 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0, 2345 analog_gain), 2346 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0, 2347 analog_gain), 2348 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0, 2349 analog_gain), 2350 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0, 2351 analog_gain), 2352 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0, 2353 analog_gain), 2354 2355 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), 2356 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), 2357 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), 2358 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), 2359 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), 2360 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), 2361 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), 2362 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), 2363 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), 2364 }; 2365 2366 static const struct snd_soc_dapm_route wcd9335_audio_map[] = { 2367 {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"}, 2368 {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"}, 2369 {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"}, 2370 {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"}, 2371 {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"}, 2372 {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"}, 2373 {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"}, 2374 {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"}, 2375 2376 {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"}, 2377 {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"}, 2378 {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"}, 2379 {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"}, 2380 {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"}, 2381 {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"}, 2382 {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"}, 2383 {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"}, 2384 2385 {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"}, 2386 {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"}, 2387 {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"}, 2388 {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"}, 2389 {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"}, 2390 {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"}, 2391 {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"}, 2392 {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"}, 2393 2394 {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"}, 2395 {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"}, 2396 {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"}, 2397 {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"}, 2398 {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"}, 2399 {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"}, 2400 {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"}, 2401 {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"}, 2402 2403 {"SLIM RX0", NULL, "SLIM RX0 MUX"}, 2404 {"SLIM RX1", NULL, "SLIM RX1 MUX"}, 2405 {"SLIM RX2", NULL, "SLIM RX2 MUX"}, 2406 {"SLIM RX3", NULL, "SLIM RX3 MUX"}, 2407 {"SLIM RX4", NULL, "SLIM RX4 MUX"}, 2408 {"SLIM RX5", NULL, "SLIM RX5 MUX"}, 2409 {"SLIM RX6", NULL, "SLIM RX6 MUX"}, 2410 {"SLIM RX7", NULL, "SLIM RX7 MUX"}, 2411 2412 WCD9335_INTERPOLATOR_PATH(0), 2413 WCD9335_INTERPOLATOR_PATH(1), 2414 WCD9335_INTERPOLATOR_PATH(2), 2415 WCD9335_INTERPOLATOR_PATH(3), 2416 WCD9335_INTERPOLATOR_PATH(4), 2417 WCD9335_INTERPOLATOR_PATH(5), 2418 WCD9335_INTERPOLATOR_PATH(6), 2419 WCD9335_INTERPOLATOR_PATH(7), 2420 WCD9335_INTERPOLATOR_PATH(8), 2421 2422 /* EAR PA */ 2423 {"RX INT0 DEM MUX", "CLSH_DSM_OUT", "RX INT0 INTERP"}, 2424 {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"}, 2425 {"RX INT0 DAC", NULL, "RX_BIAS"}, 2426 {"EAR PA", NULL, "RX INT0 DAC"}, 2427 {"EAR", NULL, "EAR PA"}, 2428 2429 /* HPHL */ 2430 {"RX INT1 DEM MUX", "CLSH_DSM_OUT", "RX INT1 INTERP"}, 2431 {"RX INT1 DAC", NULL, "RX INT1 DEM MUX"}, 2432 {"RX INT1 DAC", NULL, "RX_BIAS"}, 2433 {"HPHL PA", NULL, "RX INT1 DAC"}, 2434 {"HPHL", NULL, "HPHL PA"}, 2435 2436 /* HPHR */ 2437 {"RX INT2 DEM MUX", "CLSH_DSM_OUT", "RX INT2 INTERP"}, 2438 {"RX INT2 DAC", NULL, "RX INT2 DEM MUX"}, 2439 {"RX INT2 DAC", NULL, "RX_BIAS"}, 2440 {"HPHR PA", NULL, "RX INT2 DAC"}, 2441 {"HPHR", NULL, "HPHR PA"}, 2442 2443 /* LINEOUT1 */ 2444 {"RX INT3 DAC", NULL, "RX INT3 INTERP"}, 2445 {"RX INT3 DAC", NULL, "RX_BIAS"}, 2446 {"LINEOUT1 PA", NULL, "RX INT3 DAC"}, 2447 {"LINEOUT1", NULL, "LINEOUT1 PA"}, 2448 2449 /* LINEOUT2 */ 2450 {"RX INT4 DAC", NULL, "RX INT4 INTERP"}, 2451 {"RX INT4 DAC", NULL, "RX_BIAS"}, 2452 {"LINEOUT2 PA", NULL, "RX INT4 DAC"}, 2453 {"LINEOUT2", NULL, "LINEOUT2 PA"}, 2454 2455 /* LINEOUT3 */ 2456 {"RX INT5 DAC", NULL, "RX INT5 INTERP"}, 2457 {"RX INT5 DAC", NULL, "RX_BIAS"}, 2458 {"LINEOUT3 PA", NULL, "RX INT5 DAC"}, 2459 {"LINEOUT3", NULL, "LINEOUT3 PA"}, 2460 2461 /* LINEOUT4 */ 2462 {"RX INT6 DAC", NULL, "RX INT6 INTERP"}, 2463 {"RX INT6 DAC", NULL, "RX_BIAS"}, 2464 {"LINEOUT4 PA", NULL, "RX INT6 DAC"}, 2465 {"LINEOUT4", NULL, "LINEOUT4 PA"}, 2466 2467 /* SLIMBUS Connections */ 2468 {"AIF1 CAP", NULL, "AIF1_CAP Mixer"}, 2469 {"AIF2 CAP", NULL, "AIF2_CAP Mixer"}, 2470 {"AIF3 CAP", NULL, "AIF3_CAP Mixer"}, 2471 2472 /* ADC Mux */ 2473 WCD9335_ADC_MUX_PATH(0), 2474 WCD9335_ADC_MUX_PATH(1), 2475 WCD9335_ADC_MUX_PATH(2), 2476 WCD9335_ADC_MUX_PATH(3), 2477 WCD9335_ADC_MUX_PATH(4), 2478 WCD9335_ADC_MUX_PATH(5), 2479 WCD9335_ADC_MUX_PATH(6), 2480 WCD9335_ADC_MUX_PATH(7), 2481 WCD9335_ADC_MUX_PATH(8), 2482 2483 /* ADC Connections */ 2484 {"ADC1", NULL, "AMIC1"}, 2485 {"ADC2", NULL, "AMIC2"}, 2486 {"ADC3", NULL, "AMIC3"}, 2487 {"ADC4", NULL, "AMIC4"}, 2488 {"ADC5", NULL, "AMIC5"}, 2489 {"ADC6", NULL, "AMIC6"}, 2490 }; 2491 2492 static int wcd9335_micbias_control(struct snd_soc_component *component, 2493 int micb_num, int req, bool is_dapm) 2494 { 2495 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(component); 2496 int micb_index = micb_num - 1; 2497 u16 micb_reg; 2498 2499 if ((micb_index < 0) || (micb_index > WCD9335_MAX_MICBIAS - 1)) { 2500 dev_err(wcd->dev, "Invalid micbias index, micb_ind:%d\n", 2501 micb_index); 2502 return -EINVAL; 2503 } 2504 2505 switch (micb_num) { 2506 case MIC_BIAS_1: 2507 micb_reg = WCD9335_ANA_MICB1; 2508 break; 2509 case MIC_BIAS_2: 2510 micb_reg = WCD9335_ANA_MICB2; 2511 break; 2512 case MIC_BIAS_3: 2513 micb_reg = WCD9335_ANA_MICB3; 2514 break; 2515 case MIC_BIAS_4: 2516 micb_reg = WCD9335_ANA_MICB4; 2517 break; 2518 default: 2519 dev_err(component->dev, "%s: Invalid micbias number: %d\n", 2520 __func__, micb_num); 2521 return -EINVAL; 2522 } 2523 2524 switch (req) { 2525 case MICB_PULLUP_ENABLE: 2526 wcd->pullup_ref[micb_index]++; 2527 if ((wcd->pullup_ref[micb_index] == 1) && 2528 (wcd->micb_ref[micb_index] == 0)) 2529 snd_soc_component_update_bits(component, micb_reg, 2530 0xC0, 0x80); 2531 break; 2532 case MICB_PULLUP_DISABLE: 2533 wcd->pullup_ref[micb_index]--; 2534 if ((wcd->pullup_ref[micb_index] == 0) && 2535 (wcd->micb_ref[micb_index] == 0)) 2536 snd_soc_component_update_bits(component, micb_reg, 2537 0xC0, 0x00); 2538 break; 2539 case MICB_ENABLE: 2540 wcd->micb_ref[micb_index]++; 2541 if (wcd->micb_ref[micb_index] == 1) 2542 snd_soc_component_update_bits(component, micb_reg, 2543 0xC0, 0x40); 2544 break; 2545 case MICB_DISABLE: 2546 wcd->micb_ref[micb_index]--; 2547 if ((wcd->micb_ref[micb_index] == 0) && 2548 (wcd->pullup_ref[micb_index] > 0)) 2549 snd_soc_component_update_bits(component, micb_reg, 2550 0xC0, 0x80); 2551 else if ((wcd->micb_ref[micb_index] == 0) && 2552 (wcd->pullup_ref[micb_index] == 0)) { 2553 snd_soc_component_update_bits(component, micb_reg, 2554 0xC0, 0x00); 2555 } 2556 break; 2557 } 2558 2559 return 0; 2560 } 2561 2562 static int __wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget *w, 2563 int event) 2564 { 2565 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2566 int micb_num; 2567 2568 if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1"))) 2569 micb_num = MIC_BIAS_1; 2570 else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2"))) 2571 micb_num = MIC_BIAS_2; 2572 else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3"))) 2573 micb_num = MIC_BIAS_3; 2574 else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4"))) 2575 micb_num = MIC_BIAS_4; 2576 else 2577 return -EINVAL; 2578 2579 switch (event) { 2580 case SND_SOC_DAPM_PRE_PMU: 2581 /* 2582 * MIC BIAS can also be requested by MBHC, 2583 * so use ref count to handle micbias pullup 2584 * and enable requests 2585 */ 2586 wcd9335_micbias_control(comp, micb_num, MICB_ENABLE, true); 2587 break; 2588 case SND_SOC_DAPM_POST_PMU: 2589 /* wait for cnp time */ 2590 usleep_range(1000, 1100); 2591 break; 2592 case SND_SOC_DAPM_POST_PMD: 2593 wcd9335_micbias_control(comp, micb_num, MICB_DISABLE, true); 2594 break; 2595 } 2596 2597 return 0; 2598 } 2599 2600 static int wcd9335_codec_enable_micbias(struct snd_soc_dapm_widget *w, 2601 struct snd_kcontrol *kc, int event) 2602 { 2603 return __wcd9335_codec_enable_micbias(w, event); 2604 } 2605 2606 static void wcd9335_codec_set_tx_hold(struct snd_soc_component *comp, 2607 u16 amic_reg, bool set) 2608 { 2609 u8 mask = 0x20; 2610 u8 val; 2611 2612 if (amic_reg == WCD9335_ANA_AMIC1 || amic_reg == WCD9335_ANA_AMIC3 || 2613 amic_reg == WCD9335_ANA_AMIC5) 2614 mask = 0x40; 2615 2616 val = set ? mask : 0x00; 2617 2618 switch (amic_reg) { 2619 case WCD9335_ANA_AMIC1: 2620 case WCD9335_ANA_AMIC2: 2621 snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC2, mask, 2622 val); 2623 break; 2624 case WCD9335_ANA_AMIC3: 2625 case WCD9335_ANA_AMIC4: 2626 snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC4, mask, 2627 val); 2628 break; 2629 case WCD9335_ANA_AMIC5: 2630 case WCD9335_ANA_AMIC6: 2631 snd_soc_component_update_bits(comp, WCD9335_ANA_AMIC6, mask, 2632 val); 2633 break; 2634 default: 2635 dev_err(comp->dev, "%s: invalid amic: %d\n", 2636 __func__, amic_reg); 2637 break; 2638 } 2639 } 2640 2641 static int wcd9335_codec_enable_adc(struct snd_soc_dapm_widget *w, 2642 struct snd_kcontrol *kc, int event) 2643 { 2644 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2645 2646 switch (event) { 2647 case SND_SOC_DAPM_PRE_PMU: 2648 wcd9335_codec_set_tx_hold(comp, w->reg, true); 2649 break; 2650 default: 2651 break; 2652 } 2653 2654 return 0; 2655 } 2656 2657 static int wcd9335_codec_find_amic_input(struct snd_soc_component *comp, 2658 int adc_mux_n) 2659 { 2660 int mux_sel, reg, mreg; 2661 2662 if (adc_mux_n < 0 || adc_mux_n > WCD9335_MAX_VALID_ADC_MUX || 2663 adc_mux_n == WCD9335_INVALID_ADC_MUX) 2664 return 0; 2665 2666 /* Check whether adc mux input is AMIC or DMIC */ 2667 if (adc_mux_n < 4) { 2668 reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG1 + 2 * adc_mux_n; 2669 mreg = WCD9335_CDC_TX_INP_MUX_ADC_MUX0_CFG0 + 2 * adc_mux_n; 2670 mux_sel = snd_soc_component_read(comp, reg) & 0x3; 2671 } else { 2672 reg = WCD9335_CDC_TX_INP_MUX_ADC_MUX4_CFG0 + adc_mux_n - 4; 2673 mreg = reg; 2674 mux_sel = snd_soc_component_read(comp, reg) >> 6; 2675 } 2676 2677 if (mux_sel != WCD9335_CDC_TX_INP_MUX_SEL_AMIC) 2678 return 0; 2679 2680 return snd_soc_component_read(comp, mreg) & 0x07; 2681 } 2682 2683 static u16 wcd9335_codec_get_amic_pwlvl_reg(struct snd_soc_component *comp, 2684 int amic) 2685 { 2686 u16 pwr_level_reg = 0; 2687 2688 switch (amic) { 2689 case 1: 2690 case 2: 2691 pwr_level_reg = WCD9335_ANA_AMIC1; 2692 break; 2693 2694 case 3: 2695 case 4: 2696 pwr_level_reg = WCD9335_ANA_AMIC3; 2697 break; 2698 2699 case 5: 2700 case 6: 2701 pwr_level_reg = WCD9335_ANA_AMIC5; 2702 break; 2703 default: 2704 dev_err(comp->dev, "invalid amic: %d\n", amic); 2705 break; 2706 } 2707 2708 return pwr_level_reg; 2709 } 2710 2711 static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w, 2712 struct snd_kcontrol *kc, int event) 2713 { 2714 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2715 unsigned int decimator; 2716 char *dec_adc_mux_name = NULL; 2717 char *widget_name = NULL; 2718 char *wname; 2719 int ret = 0, amic_n; 2720 u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg; 2721 u16 tx_gain_ctl_reg; 2722 char *dec; 2723 u8 hpf_coff_freq; 2724 2725 widget_name = kmemdup_nul(w->name, 15, GFP_KERNEL); 2726 if (!widget_name) 2727 return -ENOMEM; 2728 2729 wname = widget_name; 2730 dec_adc_mux_name = strsep(&widget_name, " "); 2731 if (!dec_adc_mux_name) { 2732 dev_err(comp->dev, "%s: Invalid decimator = %s\n", 2733 __func__, w->name); 2734 ret = -EINVAL; 2735 goto out; 2736 } 2737 dec_adc_mux_name = widget_name; 2738 2739 dec = strpbrk(dec_adc_mux_name, "012345678"); 2740 if (!dec) { 2741 dev_err(comp->dev, "%s: decimator index not found\n", 2742 __func__); 2743 ret = -EINVAL; 2744 goto out; 2745 } 2746 2747 ret = kstrtouint(dec, 10, &decimator); 2748 if (ret < 0) { 2749 dev_err(comp->dev, "%s: Invalid decimator = %s\n", 2750 __func__, wname); 2751 ret = -EINVAL; 2752 goto out; 2753 } 2754 2755 tx_vol_ctl_reg = WCD9335_CDC_TX0_TX_PATH_CTL + 16 * decimator; 2756 hpf_gate_reg = WCD9335_CDC_TX0_TX_PATH_SEC2 + 16 * decimator; 2757 dec_cfg_reg = WCD9335_CDC_TX0_TX_PATH_CFG0 + 16 * decimator; 2758 tx_gain_ctl_reg = WCD9335_CDC_TX0_TX_VOL_CTL + 16 * decimator; 2759 2760 switch (event) { 2761 case SND_SOC_DAPM_PRE_PMU: 2762 amic_n = wcd9335_codec_find_amic_input(comp, decimator); 2763 if (amic_n) 2764 pwr_level_reg = wcd9335_codec_get_amic_pwlvl_reg(comp, 2765 amic_n); 2766 2767 if (pwr_level_reg) { 2768 switch ((snd_soc_component_read(comp, pwr_level_reg) & 2769 WCD9335_AMIC_PWR_LVL_MASK) >> 2770 WCD9335_AMIC_PWR_LVL_SHIFT) { 2771 case WCD9335_AMIC_PWR_LEVEL_LP: 2772 snd_soc_component_update_bits(comp, dec_cfg_reg, 2773 WCD9335_DEC_PWR_LVL_MASK, 2774 WCD9335_DEC_PWR_LVL_LP); 2775 break; 2776 2777 case WCD9335_AMIC_PWR_LEVEL_HP: 2778 snd_soc_component_update_bits(comp, dec_cfg_reg, 2779 WCD9335_DEC_PWR_LVL_MASK, 2780 WCD9335_DEC_PWR_LVL_HP); 2781 break; 2782 case WCD9335_AMIC_PWR_LEVEL_DEFAULT: 2783 default: 2784 snd_soc_component_update_bits(comp, dec_cfg_reg, 2785 WCD9335_DEC_PWR_LVL_MASK, 2786 WCD9335_DEC_PWR_LVL_DF); 2787 break; 2788 } 2789 } 2790 hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) & 2791 TX_HPF_CUT_OFF_FREQ_MASK) >> 5; 2792 2793 if (hpf_coff_freq != CF_MIN_3DB_150HZ) 2794 snd_soc_component_update_bits(comp, dec_cfg_reg, 2795 TX_HPF_CUT_OFF_FREQ_MASK, 2796 CF_MIN_3DB_150HZ << 5); 2797 /* Enable TX PGA Mute */ 2798 snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 2799 0x10, 0x10); 2800 /* Enable APC */ 2801 snd_soc_component_update_bits(comp, dec_cfg_reg, 0x08, 0x08); 2802 break; 2803 case SND_SOC_DAPM_POST_PMU: 2804 snd_soc_component_update_bits(comp, hpf_gate_reg, 0x01, 0x00); 2805 2806 if (decimator == 0) { 2807 snd_soc_component_write(comp, 2808 WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); 2809 snd_soc_component_write(comp, 2810 WCD9335_MBHC_ZDET_RAMP_CTL, 0xA3); 2811 snd_soc_component_write(comp, 2812 WCD9335_MBHC_ZDET_RAMP_CTL, 0x83); 2813 snd_soc_component_write(comp, 2814 WCD9335_MBHC_ZDET_RAMP_CTL, 0x03); 2815 } 2816 2817 snd_soc_component_update_bits(comp, hpf_gate_reg, 2818 0x01, 0x01); 2819 snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 2820 0x10, 0x00); 2821 snd_soc_component_write(comp, tx_gain_ctl_reg, 2822 snd_soc_component_read(comp, tx_gain_ctl_reg)); 2823 break; 2824 case SND_SOC_DAPM_PRE_PMD: 2825 hpf_coff_freq = (snd_soc_component_read(comp, dec_cfg_reg) & 2826 TX_HPF_CUT_OFF_FREQ_MASK) >> 5; 2827 snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x10); 2828 snd_soc_component_update_bits(comp, dec_cfg_reg, 0x08, 0x00); 2829 if (hpf_coff_freq != CF_MIN_3DB_150HZ) { 2830 snd_soc_component_update_bits(comp, dec_cfg_reg, 2831 TX_HPF_CUT_OFF_FREQ_MASK, 2832 hpf_coff_freq << 5); 2833 } 2834 break; 2835 case SND_SOC_DAPM_POST_PMD: 2836 snd_soc_component_update_bits(comp, tx_vol_ctl_reg, 0x10, 0x00); 2837 break; 2838 } 2839 out: 2840 kfree(wname); 2841 return ret; 2842 } 2843 2844 static u8 wcd9335_get_dmic_clk_val(struct snd_soc_component *component, 2845 u32 mclk_rate) 2846 { 2847 u8 dmic_ctl_val; 2848 2849 if (mclk_rate == WCD9335_MCLK_CLK_9P6MHZ) 2850 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_2; 2851 else 2852 dmic_ctl_val = WCD9335_DMIC_CLK_DIV_3; 2853 2854 return dmic_ctl_val; 2855 } 2856 2857 static int wcd9335_codec_enable_dmic(struct snd_soc_dapm_widget *w, 2858 struct snd_kcontrol *kc, int event) 2859 { 2860 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2861 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp); 2862 u8 dmic_clk_en = 0x01; 2863 u16 dmic_clk_reg; 2864 s32 *dmic_clk_cnt; 2865 u8 dmic_rate_val, dmic_rate_shift = 1; 2866 unsigned int dmic; 2867 int ret; 2868 char *wname; 2869 2870 wname = strpbrk(w->name, "012345"); 2871 if (!wname) { 2872 dev_err(comp->dev, "%s: widget not found\n", __func__); 2873 return -EINVAL; 2874 } 2875 2876 ret = kstrtouint(wname, 10, &dmic); 2877 if (ret < 0) { 2878 dev_err(comp->dev, "%s: Invalid DMIC line on the codec\n", 2879 __func__); 2880 return -EINVAL; 2881 } 2882 2883 switch (dmic) { 2884 case 0: 2885 case 1: 2886 dmic_clk_cnt = &(wcd->dmic_0_1_clk_cnt); 2887 dmic_clk_reg = WCD9335_CPE_SS_DMIC0_CTL; 2888 break; 2889 case 2: 2890 case 3: 2891 dmic_clk_cnt = &(wcd->dmic_2_3_clk_cnt); 2892 dmic_clk_reg = WCD9335_CPE_SS_DMIC1_CTL; 2893 break; 2894 case 4: 2895 case 5: 2896 dmic_clk_cnt = &(wcd->dmic_4_5_clk_cnt); 2897 dmic_clk_reg = WCD9335_CPE_SS_DMIC2_CTL; 2898 break; 2899 default: 2900 dev_err(comp->dev, "%s: Invalid DMIC Selection\n", 2901 __func__); 2902 return -EINVAL; 2903 } 2904 2905 switch (event) { 2906 case SND_SOC_DAPM_PRE_PMU: 2907 dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate); 2908 (*dmic_clk_cnt)++; 2909 if (*dmic_clk_cnt == 1) { 2910 snd_soc_component_update_bits(comp, dmic_clk_reg, 2911 0x07 << dmic_rate_shift, 2912 dmic_rate_val << dmic_rate_shift); 2913 snd_soc_component_update_bits(comp, dmic_clk_reg, 2914 dmic_clk_en, dmic_clk_en); 2915 } 2916 2917 break; 2918 case SND_SOC_DAPM_POST_PMD: 2919 dmic_rate_val = wcd9335_get_dmic_clk_val(comp, wcd->mclk_rate); 2920 (*dmic_clk_cnt)--; 2921 if (*dmic_clk_cnt == 0) { 2922 snd_soc_component_update_bits(comp, dmic_clk_reg, 2923 dmic_clk_en, 0); 2924 snd_soc_component_update_bits(comp, dmic_clk_reg, 2925 0x07 << dmic_rate_shift, 2926 dmic_rate_val << dmic_rate_shift); 2927 } 2928 break; 2929 } 2930 2931 return 0; 2932 } 2933 2934 static void wcd9335_codec_enable_int_port(struct wcd_slim_codec_dai_data *dai, 2935 struct snd_soc_component *component) 2936 { 2937 int port_num = 0; 2938 unsigned short reg = 0; 2939 unsigned int val = 0; 2940 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 2941 struct wcd9335_slim_ch *ch; 2942 2943 list_for_each_entry(ch, &dai->slim_ch_list, list) { 2944 if (ch->port >= WCD9335_RX_START) { 2945 port_num = ch->port - WCD9335_RX_START; 2946 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + (port_num / 8); 2947 } else { 2948 port_num = ch->port; 2949 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); 2950 } 2951 2952 regmap_read(wcd->if_regmap, reg, &val); 2953 if (!(val & BIT(port_num % 8))) 2954 regmap_write(wcd->if_regmap, reg, 2955 val | BIT(port_num % 8)); 2956 } 2957 } 2958 2959 static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w, 2960 struct snd_kcontrol *kc, 2961 int event) 2962 { 2963 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2964 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp); 2965 struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift]; 2966 2967 switch (event) { 2968 case SND_SOC_DAPM_POST_PMU: 2969 wcd9335_codec_enable_int_port(dai, comp); 2970 break; 2971 case SND_SOC_DAPM_POST_PMD: 2972 kfree(dai->sconfig.chs); 2973 2974 break; 2975 } 2976 2977 return 0; 2978 } 2979 2980 static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w, 2981 struct snd_kcontrol *kc, int event) 2982 { 2983 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2984 u16 gain_reg; 2985 int val = 0; 2986 2987 switch (w->reg) { 2988 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: 2989 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL; 2990 break; 2991 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL: 2992 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL; 2993 break; 2994 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL: 2995 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL; 2996 break; 2997 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL: 2998 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL; 2999 break; 3000 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL: 3001 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL; 3002 break; 3003 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL: 3004 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL; 3005 break; 3006 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL: 3007 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL; 3008 break; 3009 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL: 3010 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL; 3011 break; 3012 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL: 3013 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL; 3014 break; 3015 default: 3016 dev_err(comp->dev, "%s: No gain register avail for %s\n", 3017 __func__, w->name); 3018 return 0; 3019 } 3020 3021 switch (event) { 3022 case SND_SOC_DAPM_POST_PMU: 3023 val = snd_soc_component_read(comp, gain_reg); 3024 snd_soc_component_write(comp, gain_reg, val); 3025 break; 3026 case SND_SOC_DAPM_POST_PMD: 3027 break; 3028 } 3029 3030 return 0; 3031 } 3032 3033 static u16 wcd9335_interp_get_primary_reg(u16 reg, u16 *ind) 3034 { 3035 u16 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL; 3036 3037 switch (reg) { 3038 case WCD9335_CDC_RX0_RX_PATH_CTL: 3039 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: 3040 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL; 3041 *ind = 0; 3042 break; 3043 case WCD9335_CDC_RX1_RX_PATH_CTL: 3044 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL: 3045 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL; 3046 *ind = 1; 3047 break; 3048 case WCD9335_CDC_RX2_RX_PATH_CTL: 3049 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL: 3050 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL; 3051 *ind = 2; 3052 break; 3053 case WCD9335_CDC_RX3_RX_PATH_CTL: 3054 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL: 3055 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL; 3056 *ind = 3; 3057 break; 3058 case WCD9335_CDC_RX4_RX_PATH_CTL: 3059 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL: 3060 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL; 3061 *ind = 4; 3062 break; 3063 case WCD9335_CDC_RX5_RX_PATH_CTL: 3064 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL: 3065 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL; 3066 *ind = 5; 3067 break; 3068 case WCD9335_CDC_RX6_RX_PATH_CTL: 3069 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL: 3070 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL; 3071 *ind = 6; 3072 break; 3073 case WCD9335_CDC_RX7_RX_PATH_CTL: 3074 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL: 3075 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL; 3076 *ind = 7; 3077 break; 3078 case WCD9335_CDC_RX8_RX_PATH_CTL: 3079 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL: 3080 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL; 3081 *ind = 8; 3082 break; 3083 } 3084 3085 return prim_int_reg; 3086 } 3087 3088 static void wcd9335_codec_hd2_control(struct snd_soc_component *component, 3089 u16 prim_int_reg, int event) 3090 { 3091 u16 hd2_scale_reg; 3092 u16 hd2_enable_reg = 0; 3093 3094 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) { 3095 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3; 3096 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0; 3097 } 3098 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) { 3099 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3; 3100 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0; 3101 } 3102 3103 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { 3104 snd_soc_component_update_bits(component, hd2_scale_reg, 3105 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK, 3106 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P2500); 3107 snd_soc_component_update_bits(component, hd2_scale_reg, 3108 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK, 3109 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_2); 3110 snd_soc_component_update_bits(component, hd2_enable_reg, 3111 WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK, 3112 WCD9335_CDC_RX_PATH_CFG_HD2_ENABLE); 3113 } 3114 3115 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { 3116 snd_soc_component_update_bits(component, hd2_enable_reg, 3117 WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK, 3118 WCD9335_CDC_RX_PATH_CFG_HD2_DISABLE); 3119 snd_soc_component_update_bits(component, hd2_scale_reg, 3120 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK, 3121 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_1); 3122 snd_soc_component_update_bits(component, hd2_scale_reg, 3123 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK, 3124 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000); 3125 } 3126 } 3127 3128 static int wcd9335_codec_enable_prim_interpolator( 3129 struct snd_soc_component *comp, 3130 u16 reg, int event) 3131 { 3132 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3133 u16 ind = 0; 3134 int prim_int_reg = wcd9335_interp_get_primary_reg(reg, &ind); 3135 3136 switch (event) { 3137 case SND_SOC_DAPM_PRE_PMU: 3138 wcd->prim_int_users[ind]++; 3139 if (wcd->prim_int_users[ind] == 1) { 3140 snd_soc_component_update_bits(comp, prim_int_reg, 3141 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3142 WCD9335_CDC_RX_PGA_MUTE_ENABLE); 3143 wcd9335_codec_hd2_control(comp, prim_int_reg, event); 3144 snd_soc_component_update_bits(comp, prim_int_reg, 3145 WCD9335_CDC_RX_CLK_EN_MASK, 3146 WCD9335_CDC_RX_CLK_ENABLE); 3147 } 3148 3149 if ((reg != prim_int_reg) && 3150 ((snd_soc_component_read(comp, prim_int_reg)) & 3151 WCD9335_CDC_RX_PGA_MUTE_EN_MASK)) 3152 snd_soc_component_update_bits(comp, reg, 3153 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3154 WCD9335_CDC_RX_PGA_MUTE_ENABLE); 3155 break; 3156 case SND_SOC_DAPM_POST_PMD: 3157 wcd->prim_int_users[ind]--; 3158 if (wcd->prim_int_users[ind] == 0) { 3159 snd_soc_component_update_bits(comp, prim_int_reg, 3160 WCD9335_CDC_RX_CLK_EN_MASK, 3161 WCD9335_CDC_RX_CLK_DISABLE); 3162 snd_soc_component_update_bits(comp, prim_int_reg, 3163 WCD9335_CDC_RX_RESET_MASK, 3164 WCD9335_CDC_RX_RESET_ENABLE); 3165 snd_soc_component_update_bits(comp, prim_int_reg, 3166 WCD9335_CDC_RX_RESET_MASK, 3167 WCD9335_CDC_RX_RESET_DISABLE); 3168 wcd9335_codec_hd2_control(comp, prim_int_reg, event); 3169 } 3170 break; 3171 } 3172 3173 return 0; 3174 } 3175 3176 static int wcd9335_config_compander(struct snd_soc_component *component, 3177 int interp_n, int event) 3178 { 3179 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 3180 int comp; 3181 u16 comp_ctl0_reg, rx_path_cfg0_reg; 3182 3183 /* EAR does not have compander */ 3184 if (!interp_n) 3185 return 0; 3186 3187 comp = interp_n - 1; 3188 if (!wcd->comp_enabled[comp]) 3189 return 0; 3190 3191 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL(comp); 3192 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG(comp); 3193 3194 if (SND_SOC_DAPM_EVENT_ON(event)) { 3195 /* Enable Compander Clock */ 3196 snd_soc_component_update_bits(component, comp_ctl0_reg, 3197 WCD9335_CDC_COMPANDER_CLK_EN_MASK, 3198 WCD9335_CDC_COMPANDER_CLK_ENABLE); 3199 /* Reset comander */ 3200 snd_soc_component_update_bits(component, comp_ctl0_reg, 3201 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 3202 WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE); 3203 snd_soc_component_update_bits(component, comp_ctl0_reg, 3204 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 3205 WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE); 3206 /* Enables DRE in this path */ 3207 snd_soc_component_update_bits(component, rx_path_cfg0_reg, 3208 WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK, 3209 WCD9335_CDC_RX_PATH_CFG_CMP_ENABLE); 3210 } 3211 3212 if (SND_SOC_DAPM_EVENT_OFF(event)) { 3213 snd_soc_component_update_bits(component, comp_ctl0_reg, 3214 WCD9335_CDC_COMPANDER_HALT_MASK, 3215 WCD9335_CDC_COMPANDER_HALT); 3216 snd_soc_component_update_bits(component, rx_path_cfg0_reg, 3217 WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK, 3218 WCD9335_CDC_RX_PATH_CFG_CMP_DISABLE); 3219 3220 snd_soc_component_update_bits(component, comp_ctl0_reg, 3221 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 3222 WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE); 3223 snd_soc_component_update_bits(component, comp_ctl0_reg, 3224 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 3225 WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE); 3226 snd_soc_component_update_bits(component, comp_ctl0_reg, 3227 WCD9335_CDC_COMPANDER_CLK_EN_MASK, 3228 WCD9335_CDC_COMPANDER_CLK_DISABLE); 3229 snd_soc_component_update_bits(component, comp_ctl0_reg, 3230 WCD9335_CDC_COMPANDER_HALT_MASK, 3231 WCD9335_CDC_COMPANDER_NOHALT); 3232 } 3233 3234 return 0; 3235 } 3236 3237 static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w, 3238 struct snd_kcontrol *kc, int event) 3239 { 3240 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3241 u16 gain_reg; 3242 u16 reg; 3243 int val; 3244 3245 if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT0 INTERP"))) { 3246 reg = WCD9335_CDC_RX0_RX_PATH_CTL; 3247 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL; 3248 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT1 INTERP"))) { 3249 reg = WCD9335_CDC_RX1_RX_PATH_CTL; 3250 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL; 3251 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT2 INTERP"))) { 3252 reg = WCD9335_CDC_RX2_RX_PATH_CTL; 3253 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL; 3254 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT3 INTERP"))) { 3255 reg = WCD9335_CDC_RX3_RX_PATH_CTL; 3256 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL; 3257 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT4 INTERP"))) { 3258 reg = WCD9335_CDC_RX4_RX_PATH_CTL; 3259 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL; 3260 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT5 INTERP"))) { 3261 reg = WCD9335_CDC_RX5_RX_PATH_CTL; 3262 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL; 3263 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT6 INTERP"))) { 3264 reg = WCD9335_CDC_RX6_RX_PATH_CTL; 3265 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL; 3266 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT7 INTERP"))) { 3267 reg = WCD9335_CDC_RX7_RX_PATH_CTL; 3268 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL; 3269 } else if (!(snd_soc_dapm_widget_name_cmp(w, "RX INT8 INTERP"))) { 3270 reg = WCD9335_CDC_RX8_RX_PATH_CTL; 3271 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL; 3272 } else { 3273 dev_err(comp->dev, "%s: Interpolator reg not found\n", 3274 __func__); 3275 return -EINVAL; 3276 } 3277 3278 switch (event) { 3279 case SND_SOC_DAPM_PRE_PMU: 3280 /* Reset if needed */ 3281 wcd9335_codec_enable_prim_interpolator(comp, reg, event); 3282 break; 3283 case SND_SOC_DAPM_POST_PMU: 3284 wcd9335_config_compander(comp, w->shift, event); 3285 val = snd_soc_component_read(comp, gain_reg); 3286 snd_soc_component_write(comp, gain_reg, val); 3287 break; 3288 case SND_SOC_DAPM_POST_PMD: 3289 wcd9335_config_compander(comp, w->shift, event); 3290 wcd9335_codec_enable_prim_interpolator(comp, reg, event); 3291 break; 3292 } 3293 3294 return 0; 3295 } 3296 3297 static void wcd9335_codec_hph_mode_gain_opt(struct snd_soc_component *component, 3298 u8 gain) 3299 { 3300 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 3301 u8 hph_l_en, hph_r_en; 3302 u8 l_val, r_val; 3303 u8 hph_pa_status; 3304 bool is_hphl_pa, is_hphr_pa; 3305 3306 hph_pa_status = snd_soc_component_read(component, WCD9335_ANA_HPH); 3307 is_hphl_pa = hph_pa_status >> 7; 3308 is_hphr_pa = (hph_pa_status & 0x40) >> 6; 3309 3310 hph_l_en = snd_soc_component_read(component, WCD9335_HPH_L_EN); 3311 hph_r_en = snd_soc_component_read(component, WCD9335_HPH_R_EN); 3312 3313 l_val = (hph_l_en & 0xC0) | 0x20 | gain; 3314 r_val = (hph_r_en & 0xC0) | 0x20 | gain; 3315 3316 /* 3317 * Set HPH_L & HPH_R gain source selection to REGISTER 3318 * for better click and pop only if corresponding PAs are 3319 * not enabled. Also cache the values of the HPHL/R 3320 * PA gains to be applied after PAs are enabled 3321 */ 3322 if ((l_val != hph_l_en) && !is_hphl_pa) { 3323 snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val); 3324 wcd->hph_l_gain = hph_l_en & 0x1F; 3325 } 3326 3327 if ((r_val != hph_r_en) && !is_hphr_pa) { 3328 snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val); 3329 wcd->hph_r_gain = hph_r_en & 0x1F; 3330 } 3331 } 3332 3333 static void wcd9335_codec_hph_lohifi_config(struct snd_soc_component *comp, 3334 int event) 3335 { 3336 if (SND_SOC_DAPM_EVENT_ON(event)) { 3337 snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA, 3338 WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK, 3339 0x06); 3340 snd_soc_component_update_bits(comp, 3341 WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 3342 0xF0, 0x40); 3343 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 3344 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 3345 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000); 3346 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3347 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 3348 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE); 3349 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1, 3350 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 3351 0x0C); 3352 wcd9335_codec_hph_mode_gain_opt(comp, 0x11); 3353 } 3354 3355 if (SND_SOC_DAPM_EVENT_OFF(event)) { 3356 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3357 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 3358 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE); 3359 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 3360 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 3361 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500); 3362 snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 3363 0x8A); 3364 snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA, 3365 WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK, 3366 0x0A); 3367 } 3368 } 3369 3370 static void wcd9335_codec_hph_lp_config(struct snd_soc_component *comp, 3371 int event) 3372 { 3373 if (SND_SOC_DAPM_EVENT_ON(event)) { 3374 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1, 3375 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 3376 0x0C); 3377 wcd9335_codec_hph_mode_gain_opt(comp, 0x10); 3378 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 3379 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 3380 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000); 3381 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3382 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 3383 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE); 3384 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3385 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK, 3386 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_ENABLE); 3387 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3388 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK, 3389 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENABLE); 3390 snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL, 3391 WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_MASK, 3392 WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_V_N1P60); 3393 snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL, 3394 WCD9335_HPH_RDAC_1P65_LD_OUTCTL_MASK, 3395 WCD9335_HPH_RDAC_1P65_LD_OUTCTL_V_N1P60); 3396 snd_soc_component_update_bits(comp, 3397 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01); 3398 snd_soc_component_update_bits(comp, 3399 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10); 3400 } 3401 3402 if (SND_SOC_DAPM_EVENT_OFF(event)) { 3403 snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDAC_LDO, 3404 0x88); 3405 snd_soc_component_write(comp, WCD9335_HPH_RDAC_LDO_CTL, 3406 0x33); 3407 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3408 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK, 3409 WCD9335_HPH_PA_CTL2_HPH_PSRR_DISABLE); 3410 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3411 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK, 3412 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_DISABLE); 3413 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3414 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 3415 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE); 3416 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 3417 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 3418 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500); 3419 snd_soc_component_update_bits(comp, WCD9335_HPH_R_EN, 3420 WCD9335_HPH_CONST_SEL_L_MASK, 3421 WCD9335_HPH_CONST_SEL_L_HQ_PATH); 3422 snd_soc_component_update_bits(comp, WCD9335_HPH_L_EN, 3423 WCD9335_HPH_CONST_SEL_L_MASK, 3424 WCD9335_HPH_CONST_SEL_L_HQ_PATH); 3425 } 3426 } 3427 3428 static void wcd9335_codec_hph_hifi_config(struct snd_soc_component *comp, 3429 int event) 3430 { 3431 if (SND_SOC_DAPM_EVENT_ON(event)) { 3432 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 3433 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 3434 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000); 3435 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3436 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 3437 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE); 3438 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1, 3439 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 3440 0x0C); 3441 wcd9335_codec_hph_mode_gain_opt(comp, 0x11); 3442 } 3443 3444 if (SND_SOC_DAPM_EVENT_OFF(event)) { 3445 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 3446 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 3447 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE); 3448 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 3449 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 3450 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500); 3451 } 3452 } 3453 3454 static void wcd9335_codec_hph_mode_config(struct snd_soc_component *component, 3455 int event, int mode) 3456 { 3457 switch (mode) { 3458 case CLS_H_LP: 3459 wcd9335_codec_hph_lp_config(component, event); 3460 break; 3461 case CLS_H_LOHIFI: 3462 wcd9335_codec_hph_lohifi_config(component, event); 3463 break; 3464 case CLS_H_HIFI: 3465 wcd9335_codec_hph_hifi_config(component, event); 3466 break; 3467 } 3468 } 3469 3470 static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 3471 struct snd_kcontrol *kc, 3472 int event) 3473 { 3474 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3475 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3476 int hph_mode = wcd->hph_mode; 3477 u8 dem_inp; 3478 3479 switch (event) { 3480 case SND_SOC_DAPM_PRE_PMU: 3481 /* Read DEM INP Select */ 3482 dem_inp = snd_soc_component_read(comp, 3483 WCD9335_CDC_RX1_RX_PATH_SEC0) & 0x03; 3484 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || 3485 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { 3486 dev_err(comp->dev, "Incorrect DEM Input\n"); 3487 return -EINVAL; 3488 } 3489 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, 3490 WCD_CLSH_STATE_HPHL, 3491 ((hph_mode == CLS_H_LOHIFI) ? 3492 CLS_H_HIFI : hph_mode)); 3493 3494 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 3495 3496 break; 3497 case SND_SOC_DAPM_POST_PMU: 3498 usleep_range(1000, 1100); 3499 break; 3500 case SND_SOC_DAPM_PRE_PMD: 3501 break; 3502 case SND_SOC_DAPM_POST_PMD: 3503 /* 1000us required as per HW requirement */ 3504 usleep_range(1000, 1100); 3505 3506 if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) & 3507 WCD_CLSH_STATE_HPHR)) 3508 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 3509 3510 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 3511 WCD_CLSH_STATE_HPHL, 3512 ((hph_mode == CLS_H_LOHIFI) ? 3513 CLS_H_HIFI : hph_mode)); 3514 break; 3515 } 3516 3517 return 0; 3518 } 3519 3520 static int wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, 3521 struct snd_kcontrol *kc, int event) 3522 { 3523 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3524 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3525 3526 switch (event) { 3527 case SND_SOC_DAPM_PRE_PMU: 3528 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, 3529 WCD_CLSH_STATE_LO, CLS_AB); 3530 break; 3531 case SND_SOC_DAPM_POST_PMD: 3532 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 3533 WCD_CLSH_STATE_LO, CLS_AB); 3534 break; 3535 } 3536 3537 return 0; 3538 } 3539 3540 static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w, 3541 struct snd_kcontrol *kc, int event) 3542 { 3543 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3544 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3545 3546 switch (event) { 3547 case SND_SOC_DAPM_PRE_PMU: 3548 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, 3549 WCD_CLSH_STATE_EAR, CLS_H_NORMAL); 3550 3551 break; 3552 case SND_SOC_DAPM_POST_PMD: 3553 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 3554 WCD_CLSH_STATE_EAR, CLS_H_NORMAL); 3555 break; 3556 } 3557 3558 return 0; 3559 } 3560 3561 static void wcd9335_codec_hph_post_pa_config(struct wcd9335_codec *wcd, 3562 int mode, int event) 3563 { 3564 u8 scale_val = 0; 3565 3566 switch (event) { 3567 case SND_SOC_DAPM_POST_PMU: 3568 switch (mode) { 3569 case CLS_H_HIFI: 3570 scale_val = 0x3; 3571 break; 3572 case CLS_H_LOHIFI: 3573 scale_val = 0x1; 3574 break; 3575 } 3576 break; 3577 case SND_SOC_DAPM_PRE_PMD: 3578 scale_val = 0x6; 3579 break; 3580 } 3581 3582 if (scale_val) 3583 snd_soc_component_update_bits(wcd->component, 3584 WCD9335_HPH_PA_CTL1, 3585 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 3586 scale_val << 1); 3587 if (SND_SOC_DAPM_EVENT_ON(event)) { 3588 if (wcd->comp_enabled[COMPANDER_1] || 3589 wcd->comp_enabled[COMPANDER_2]) { 3590 /* GAIN Source Selection */ 3591 snd_soc_component_update_bits(wcd->component, 3592 WCD9335_HPH_L_EN, 3593 WCD9335_HPH_GAIN_SRC_SEL_MASK, 3594 WCD9335_HPH_GAIN_SRC_SEL_COMPANDER); 3595 snd_soc_component_update_bits(wcd->component, 3596 WCD9335_HPH_R_EN, 3597 WCD9335_HPH_GAIN_SRC_SEL_MASK, 3598 WCD9335_HPH_GAIN_SRC_SEL_COMPANDER); 3599 snd_soc_component_update_bits(wcd->component, 3600 WCD9335_HPH_AUTO_CHOP, 3601 WCD9335_HPH_AUTO_CHOP_MASK, 3602 WCD9335_HPH_AUTO_CHOP_FORCE_ENABLE); 3603 } 3604 snd_soc_component_update_bits(wcd->component, 3605 WCD9335_HPH_L_EN, 3606 WCD9335_HPH_PA_GAIN_MASK, 3607 wcd->hph_l_gain); 3608 snd_soc_component_update_bits(wcd->component, 3609 WCD9335_HPH_R_EN, 3610 WCD9335_HPH_PA_GAIN_MASK, 3611 wcd->hph_r_gain); 3612 } 3613 3614 if (SND_SOC_DAPM_EVENT_OFF(event)) 3615 snd_soc_component_update_bits(wcd->component, 3616 WCD9335_HPH_AUTO_CHOP, 3617 WCD9335_HPH_AUTO_CHOP_MASK, 3618 WCD9335_HPH_AUTO_CHOP_ENABLE_BY_CMPDR_GAIN); 3619 } 3620 3621 static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 3622 struct snd_kcontrol *kc, 3623 int event) 3624 { 3625 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3626 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3627 int hph_mode = wcd->hph_mode; 3628 u8 dem_inp; 3629 3630 switch (event) { 3631 case SND_SOC_DAPM_PRE_PMU: 3632 3633 /* Read DEM INP Select */ 3634 dem_inp = snd_soc_component_read(comp, 3635 WCD9335_CDC_RX2_RX_PATH_SEC0) & 3636 WCD9335_CDC_RX_PATH_DEM_INP_SEL_MASK; 3637 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || 3638 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { 3639 dev_err(comp->dev, "DEM Input not set correctly, hph_mode: %d\n", 3640 hph_mode); 3641 return -EINVAL; 3642 } 3643 3644 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, 3645 WCD_CLSH_EVENT_PRE_DAC, 3646 WCD_CLSH_STATE_HPHR, 3647 ((hph_mode == CLS_H_LOHIFI) ? 3648 CLS_H_HIFI : hph_mode)); 3649 3650 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 3651 3652 break; 3653 case SND_SOC_DAPM_POST_PMD: 3654 /* 1000us required as per HW requirement */ 3655 usleep_range(1000, 1100); 3656 3657 if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) & 3658 WCD_CLSH_STATE_HPHL)) 3659 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 3660 3661 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 3662 WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ? 3663 CLS_H_HIFI : hph_mode)); 3664 break; 3665 } 3666 3667 return 0; 3668 } 3669 3670 static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 3671 struct snd_kcontrol *kc, 3672 int event) 3673 { 3674 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3675 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3676 int hph_mode = wcd->hph_mode; 3677 3678 switch (event) { 3679 case SND_SOC_DAPM_PRE_PMU: 3680 break; 3681 case SND_SOC_DAPM_POST_PMU: 3682 /* 3683 * 7ms sleep is required after PA is enabled as per 3684 * HW requirement 3685 */ 3686 usleep_range(7000, 7100); 3687 3688 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 3689 snd_soc_component_update_bits(comp, 3690 WCD9335_CDC_RX1_RX_PATH_CTL, 3691 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3692 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3693 3694 /* Remove mix path mute if it is enabled */ 3695 if ((snd_soc_component_read(comp, 3696 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & 3697 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 3698 snd_soc_component_update_bits(comp, 3699 WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 3700 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3701 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3702 3703 break; 3704 case SND_SOC_DAPM_PRE_PMD: 3705 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 3706 break; 3707 case SND_SOC_DAPM_POST_PMD: 3708 /* 5ms sleep is required after PA is disabled as per 3709 * HW requirement 3710 */ 3711 usleep_range(5000, 5500); 3712 break; 3713 } 3714 3715 return 0; 3716 } 3717 3718 static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, 3719 struct snd_kcontrol *kc, 3720 int event) 3721 { 3722 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3723 int vol_reg = 0, mix_vol_reg = 0; 3724 3725 if (w->reg == WCD9335_ANA_LO_1_2) { 3726 if (w->shift == 7) { 3727 vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL; 3728 mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL; 3729 } else if (w->shift == 6) { 3730 vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL; 3731 mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL; 3732 } 3733 } else if (w->reg == WCD9335_ANA_LO_3_4) { 3734 if (w->shift == 7) { 3735 vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL; 3736 mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL; 3737 } else if (w->shift == 6) { 3738 vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL; 3739 mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL; 3740 } 3741 } else { 3742 dev_err(comp->dev, "Error enabling lineout PA\n"); 3743 return -EINVAL; 3744 } 3745 3746 switch (event) { 3747 case SND_SOC_DAPM_POST_PMU: 3748 /* 5ms sleep is required after PA is enabled as per 3749 * HW requirement 3750 */ 3751 usleep_range(5000, 5500); 3752 snd_soc_component_update_bits(comp, vol_reg, 3753 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3754 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3755 3756 /* Remove mix path mute if it is enabled */ 3757 if ((snd_soc_component_read(comp, mix_vol_reg)) & 3758 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 3759 snd_soc_component_update_bits(comp, mix_vol_reg, 3760 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3761 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3762 break; 3763 case SND_SOC_DAPM_POST_PMD: 3764 /* 5ms sleep is required after PA is disabled as per 3765 * HW requirement 3766 */ 3767 usleep_range(5000, 5500); 3768 break; 3769 } 3770 3771 return 0; 3772 } 3773 3774 static void wcd9335_codec_init_flyback(struct snd_soc_component *component) 3775 { 3776 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 3777 WCD9335_HPH_CONST_SEL_L_MASK, 3778 WCD9335_HPH_CONST_SEL_L_BYPASS); 3779 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 3780 WCD9335_HPH_CONST_SEL_L_MASK, 3781 WCD9335_HPH_CONST_SEL_L_BYPASS); 3782 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF, 3783 WCD9335_RX_BIAS_FLYB_VPOS_5_UA_MASK, 3784 WCD9335_RX_BIAS_FLYB_I_0P0_UA); 3785 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF, 3786 WCD9335_RX_BIAS_FLYB_VNEG_5_UA_MASK, 3787 WCD9335_RX_BIAS_FLYB_I_0P0_UA); 3788 } 3789 3790 static int wcd9335_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, 3791 struct snd_kcontrol *kc, int event) 3792 { 3793 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3794 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3795 3796 switch (event) { 3797 case SND_SOC_DAPM_PRE_PMU: 3798 wcd->rx_bias_count++; 3799 if (wcd->rx_bias_count == 1) { 3800 wcd9335_codec_init_flyback(comp); 3801 snd_soc_component_update_bits(comp, 3802 WCD9335_ANA_RX_SUPPLIES, 3803 WCD9335_ANA_RX_BIAS_ENABLE_MASK, 3804 WCD9335_ANA_RX_BIAS_ENABLE); 3805 } 3806 break; 3807 case SND_SOC_DAPM_POST_PMD: 3808 wcd->rx_bias_count--; 3809 if (!wcd->rx_bias_count) 3810 snd_soc_component_update_bits(comp, 3811 WCD9335_ANA_RX_SUPPLIES, 3812 WCD9335_ANA_RX_BIAS_ENABLE_MASK, 3813 WCD9335_ANA_RX_BIAS_DISABLE); 3814 break; 3815 } 3816 3817 return 0; 3818 } 3819 3820 static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 3821 struct snd_kcontrol *kc, int event) 3822 { 3823 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3824 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3825 int hph_mode = wcd->hph_mode; 3826 3827 switch (event) { 3828 case SND_SOC_DAPM_PRE_PMU: 3829 break; 3830 case SND_SOC_DAPM_POST_PMU: 3831 /* 3832 * 7ms sleep is required after PA is enabled as per 3833 * HW requirement 3834 */ 3835 usleep_range(7000, 7100); 3836 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 3837 snd_soc_component_update_bits(comp, 3838 WCD9335_CDC_RX2_RX_PATH_CTL, 3839 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3840 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3841 /* Remove mix path mute if it is enabled */ 3842 if ((snd_soc_component_read(comp, 3843 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & 3844 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 3845 snd_soc_component_update_bits(comp, 3846 WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 3847 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3848 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3849 3850 break; 3851 3852 case SND_SOC_DAPM_PRE_PMD: 3853 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 3854 break; 3855 case SND_SOC_DAPM_POST_PMD: 3856 /* 5ms sleep is required after PA is disabled as per 3857 * HW requirement 3858 */ 3859 usleep_range(5000, 5500); 3860 break; 3861 } 3862 3863 return 0; 3864 } 3865 3866 static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, 3867 struct snd_kcontrol *kc, int event) 3868 { 3869 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 3870 3871 switch (event) { 3872 case SND_SOC_DAPM_POST_PMU: 3873 /* 5ms sleep is required after PA is enabled as per 3874 * HW requirement 3875 */ 3876 usleep_range(5000, 5500); 3877 snd_soc_component_update_bits(comp, 3878 WCD9335_CDC_RX0_RX_PATH_CTL, 3879 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3880 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3881 /* Remove mix path mute if it is enabled */ 3882 if ((snd_soc_component_read(comp, 3883 WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) & 3884 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 3885 snd_soc_component_update_bits(comp, 3886 WCD9335_CDC_RX0_RX_PATH_MIX_CTL, 3887 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 3888 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 3889 break; 3890 case SND_SOC_DAPM_POST_PMD: 3891 /* 5ms sleep is required after PA is disabled as per 3892 * HW requirement 3893 */ 3894 usleep_range(5000, 5500); 3895 3896 break; 3897 } 3898 3899 return 0; 3900 } 3901 3902 static irqreturn_t wcd9335_slimbus_irq(int irq, void *data) 3903 { 3904 struct wcd9335_codec *wcd = data; 3905 unsigned long status = 0; 3906 int i, j, port_id; 3907 unsigned int val, int_val = 0; 3908 irqreturn_t ret = IRQ_NONE; 3909 bool tx; 3910 unsigned short reg = 0; 3911 3912 for (i = WCD9335_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; 3913 i <= WCD9335_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { 3914 regmap_read(wcd->if_regmap, i, &val); 3915 status |= ((u32)val << (8 * j)); 3916 } 3917 3918 for_each_set_bit(j, &status, 32) { 3919 tx = (j >= 16); 3920 port_id = (tx ? j - 16 : j); 3921 regmap_read(wcd->if_regmap, 3922 WCD9335_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val); 3923 if (val) { 3924 if (!tx) 3925 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + 3926 (port_id / 8); 3927 else 3928 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + 3929 (port_id / 8); 3930 regmap_read( 3931 wcd->if_regmap, reg, &int_val); 3932 /* 3933 * Ignore interrupts for ports for which the 3934 * interrupts are not specifically enabled. 3935 */ 3936 if (!(int_val & (1 << (port_id % 8)))) 3937 continue; 3938 } 3939 3940 if (val & WCD9335_SLIM_IRQ_OVERFLOW) 3941 dev_err_ratelimited(wcd->dev, 3942 "%s: overflow error on %s port %d, value %x\n", 3943 __func__, (tx ? "TX" : "RX"), port_id, val); 3944 3945 if (val & WCD9335_SLIM_IRQ_UNDERFLOW) 3946 dev_err_ratelimited(wcd->dev, 3947 "%s: underflow error on %s port %d, value %x\n", 3948 __func__, (tx ? "TX" : "RX"), port_id, val); 3949 3950 if ((val & WCD9335_SLIM_IRQ_OVERFLOW) || 3951 (val & WCD9335_SLIM_IRQ_UNDERFLOW)) { 3952 if (!tx) 3953 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + 3954 (port_id / 8); 3955 else 3956 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + 3957 (port_id / 8); 3958 regmap_read( 3959 wcd->if_regmap, reg, &int_val); 3960 if (int_val & (1 << (port_id % 8))) { 3961 int_val = int_val ^ (1 << (port_id % 8)); 3962 regmap_write(wcd->if_regmap, 3963 reg, int_val); 3964 } 3965 } 3966 3967 regmap_write(wcd->if_regmap, 3968 WCD9335_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8), 3969 BIT(j % 8)); 3970 ret = IRQ_HANDLED; 3971 } 3972 3973 return ret; 3974 } 3975 3976 static const struct wcd9335_irq wcd9335_irqs[] = { 3977 { 3978 .irq = WCD9335_IRQ_SLIMBUS, 3979 .handler = wcd9335_slimbus_irq, 3980 .name = "SLIM Slave", 3981 }, 3982 }; 3983 3984 static int wcd9335_setup_irqs(struct wcd9335_codec *wcd) 3985 { 3986 int irq, ret, i; 3987 3988 for (i = 0; i < ARRAY_SIZE(wcd9335_irqs); i++) { 3989 irq = regmap_irq_get_virq(wcd->irq_data, wcd9335_irqs[i].irq); 3990 if (irq < 0) { 3991 dev_err(wcd->dev, "Failed to get %s\n", 3992 wcd9335_irqs[i].name); 3993 return irq; 3994 } 3995 3996 ret = devm_request_threaded_irq(wcd->dev, irq, NULL, 3997 wcd9335_irqs[i].handler, 3998 IRQF_TRIGGER_RISING | 3999 IRQF_ONESHOT, 4000 wcd9335_irqs[i].name, wcd); 4001 if (ret) { 4002 dev_err(wcd->dev, "Failed to request %s\n", 4003 wcd9335_irqs[i].name); 4004 return ret; 4005 } 4006 } 4007 4008 /* enable interrupts on all slave ports */ 4009 for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++) 4010 regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i, 4011 0xFF); 4012 4013 return ret; 4014 } 4015 4016 static void wcd9335_teardown_irqs(struct wcd9335_codec *wcd) 4017 { 4018 int i; 4019 4020 /* disable interrupts on all slave ports */ 4021 for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++) 4022 regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i, 4023 0x00); 4024 } 4025 4026 static void wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec *wcd, 4027 bool ccl_flag) 4028 { 4029 struct snd_soc_component *comp = wcd->component; 4030 4031 if (ccl_flag) { 4032 if (++wcd->sido_ccl_cnt == 1) 4033 snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10, 4034 WCD9335_SIDO_SIDO_CCL_DEF_VALUE); 4035 } else { 4036 if (wcd->sido_ccl_cnt == 0) { 4037 dev_err(wcd->dev, "sido_ccl already disabled\n"); 4038 return; 4039 } 4040 if (--wcd->sido_ccl_cnt == 0) 4041 snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10, 4042 WCD9335_SIDO_SIDO_CCL_10_ICHARG_PWR_SEL_C320FF); 4043 } 4044 } 4045 4046 static int wcd9335_enable_master_bias(struct wcd9335_codec *wcd) 4047 { 4048 wcd->master_bias_users++; 4049 if (wcd->master_bias_users == 1) { 4050 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 4051 WCD9335_ANA_BIAS_EN_MASK, 4052 WCD9335_ANA_BIAS_ENABLE); 4053 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 4054 WCD9335_ANA_BIAS_PRECHRG_EN_MASK, 4055 WCD9335_ANA_BIAS_PRECHRG_ENABLE); 4056 /* 4057 * 1ms delay is required after pre-charge is enabled 4058 * as per HW requirement 4059 */ 4060 usleep_range(1000, 1100); 4061 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 4062 WCD9335_ANA_BIAS_PRECHRG_EN_MASK, 4063 WCD9335_ANA_BIAS_PRECHRG_DISABLE); 4064 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 4065 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE, 4066 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL); 4067 } 4068 4069 return 0; 4070 } 4071 4072 static int wcd9335_enable_mclk(struct wcd9335_codec *wcd) 4073 { 4074 /* Enable mclk requires master bias to be enabled first */ 4075 if (wcd->master_bias_users <= 0) 4076 return -EINVAL; 4077 4078 if (((wcd->clk_mclk_users == 0) && (wcd->clk_type == WCD_CLK_MCLK)) || 4079 ((wcd->clk_mclk_users > 0) && (wcd->clk_type != WCD_CLK_MCLK))) { 4080 dev_err(wcd->dev, "Error enabling MCLK, clk_type: %d\n", 4081 wcd->clk_type); 4082 return -EINVAL; 4083 } 4084 4085 if (++wcd->clk_mclk_users == 1) { 4086 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 4087 WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK, 4088 WCD9335_ANA_CLK_EXT_CLKBUF_ENABLE); 4089 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 4090 WCD9335_ANA_CLK_MCLK_SRC_MASK, 4091 WCD9335_ANA_CLK_MCLK_SRC_EXTERNAL); 4092 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 4093 WCD9335_ANA_CLK_MCLK_EN_MASK, 4094 WCD9335_ANA_CLK_MCLK_ENABLE); 4095 regmap_update_bits(wcd->regmap, 4096 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 4097 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_EN_MASK, 4098 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_ENABLE); 4099 regmap_update_bits(wcd->regmap, 4100 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, 4101 WCD9335_CDC_CLK_RST_CTRL_MCLK_EN_MASK, 4102 WCD9335_CDC_CLK_RST_CTRL_MCLK_ENABLE); 4103 /* 4104 * 10us sleep is required after clock is enabled 4105 * as per HW requirement 4106 */ 4107 usleep_range(10, 15); 4108 } 4109 4110 wcd->clk_type = WCD_CLK_MCLK; 4111 4112 return 0; 4113 } 4114 4115 static int wcd9335_disable_mclk(struct wcd9335_codec *wcd) 4116 { 4117 if (wcd->clk_mclk_users <= 0) 4118 return -EINVAL; 4119 4120 if (--wcd->clk_mclk_users == 0) { 4121 if (wcd->clk_rco_users > 0) { 4122 /* MCLK to RCO switch */ 4123 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 4124 WCD9335_ANA_CLK_MCLK_SRC_MASK, 4125 WCD9335_ANA_CLK_MCLK_SRC_RCO); 4126 wcd->clk_type = WCD_CLK_RCO; 4127 } else { 4128 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 4129 WCD9335_ANA_CLK_MCLK_EN_MASK, 4130 WCD9335_ANA_CLK_MCLK_DISABLE); 4131 wcd->clk_type = WCD_CLK_OFF; 4132 } 4133 4134 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 4135 WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK, 4136 WCD9335_ANA_CLK_EXT_CLKBUF_DISABLE); 4137 } 4138 4139 return 0; 4140 } 4141 4142 static int wcd9335_disable_master_bias(struct wcd9335_codec *wcd) 4143 { 4144 if (wcd->master_bias_users <= 0) 4145 return -EINVAL; 4146 4147 wcd->master_bias_users--; 4148 if (wcd->master_bias_users == 0) { 4149 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 4150 WCD9335_ANA_BIAS_EN_MASK, 4151 WCD9335_ANA_BIAS_DISABLE); 4152 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 4153 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE, 4154 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL); 4155 } 4156 return 0; 4157 } 4158 4159 static int wcd9335_cdc_req_mclk_enable(struct wcd9335_codec *wcd, 4160 bool enable) 4161 { 4162 int ret = 0; 4163 4164 if (enable) { 4165 wcd9335_cdc_sido_ccl_enable(wcd, true); 4166 ret = clk_prepare_enable(wcd->mclk); 4167 if (ret) { 4168 dev_err(wcd->dev, "%s: ext clk enable failed\n", 4169 __func__); 4170 goto err; 4171 } 4172 /* get BG */ 4173 wcd9335_enable_master_bias(wcd); 4174 /* get MCLK */ 4175 wcd9335_enable_mclk(wcd); 4176 4177 } else { 4178 /* put MCLK */ 4179 wcd9335_disable_mclk(wcd); 4180 /* put BG */ 4181 wcd9335_disable_master_bias(wcd); 4182 clk_disable_unprepare(wcd->mclk); 4183 wcd9335_cdc_sido_ccl_enable(wcd, false); 4184 } 4185 err: 4186 return ret; 4187 } 4188 4189 static void wcd9335_codec_apply_sido_voltage(struct wcd9335_codec *wcd, 4190 enum wcd9335_sido_voltage req_mv) 4191 { 4192 struct snd_soc_component *comp = wcd->component; 4193 int vout_d_val; 4194 4195 if (req_mv == wcd->sido_voltage) 4196 return; 4197 4198 /* compute the vout_d step value */ 4199 vout_d_val = WCD9335_CALCULATE_VOUT_D(req_mv) & 4200 WCD9335_ANA_BUCK_VOUT_MASK; 4201 snd_soc_component_write(comp, WCD9335_ANA_BUCK_VOUT_D, vout_d_val); 4202 snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL, 4203 WCD9335_ANA_BUCK_CTL_RAMP_START_MASK, 4204 WCD9335_ANA_BUCK_CTL_RAMP_START_ENABLE); 4205 4206 /* 1 msec sleep required after SIDO Vout_D voltage change */ 4207 usleep_range(1000, 1100); 4208 wcd->sido_voltage = req_mv; 4209 snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL, 4210 WCD9335_ANA_BUCK_CTL_RAMP_START_MASK, 4211 WCD9335_ANA_BUCK_CTL_RAMP_START_DISABLE); 4212 } 4213 4214 static int wcd9335_codec_update_sido_voltage(struct wcd9335_codec *wcd, 4215 enum wcd9335_sido_voltage req_mv) 4216 { 4217 int ret = 0; 4218 4219 /* enable mclk before setting SIDO voltage */ 4220 ret = wcd9335_cdc_req_mclk_enable(wcd, true); 4221 if (ret) { 4222 dev_err(wcd->dev, "Ext clk enable failed\n"); 4223 goto err; 4224 } 4225 4226 wcd9335_codec_apply_sido_voltage(wcd, req_mv); 4227 wcd9335_cdc_req_mclk_enable(wcd, false); 4228 4229 err: 4230 return ret; 4231 } 4232 4233 static int _wcd9335_codec_enable_mclk(struct snd_soc_component *component, 4234 int enable) 4235 { 4236 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 4237 int ret; 4238 4239 if (enable) { 4240 ret = wcd9335_cdc_req_mclk_enable(wcd, true); 4241 if (ret) 4242 return ret; 4243 4244 wcd9335_codec_apply_sido_voltage(wcd, 4245 SIDO_VOLTAGE_NOMINAL_MV); 4246 } else { 4247 wcd9335_codec_update_sido_voltage(wcd, 4248 wcd->sido_voltage); 4249 wcd9335_cdc_req_mclk_enable(wcd, false); 4250 } 4251 4252 return 0; 4253 } 4254 4255 static int wcd9335_codec_enable_mclk(struct snd_soc_dapm_widget *w, 4256 struct snd_kcontrol *kc, int event) 4257 { 4258 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 4259 4260 switch (event) { 4261 case SND_SOC_DAPM_PRE_PMU: 4262 return _wcd9335_codec_enable_mclk(comp, true); 4263 case SND_SOC_DAPM_POST_PMD: 4264 return _wcd9335_codec_enable_mclk(comp, false); 4265 } 4266 4267 return 0; 4268 } 4269 4270 static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = { 4271 /* TODO SPK1 & SPK2 OUT*/ 4272 SND_SOC_DAPM_OUTPUT("EAR"), 4273 SND_SOC_DAPM_OUTPUT("HPHL"), 4274 SND_SOC_DAPM_OUTPUT("HPHR"), 4275 SND_SOC_DAPM_OUTPUT("LINEOUT1"), 4276 SND_SOC_DAPM_OUTPUT("LINEOUT2"), 4277 SND_SOC_DAPM_OUTPUT("LINEOUT3"), 4278 SND_SOC_DAPM_OUTPUT("LINEOUT4"), 4279 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, 4280 AIF1_PB, 0, wcd9335_codec_enable_slim, 4281 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4282 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, 4283 AIF2_PB, 0, wcd9335_codec_enable_slim, 4284 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4285 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, 4286 AIF3_PB, 0, wcd9335_codec_enable_slim, 4287 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4288 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, 4289 AIF4_PB, 0, wcd9335_codec_enable_slim, 4290 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4291 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, WCD9335_RX0, 0, 4292 &slim_rx_mux[WCD9335_RX0]), 4293 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, WCD9335_RX1, 0, 4294 &slim_rx_mux[WCD9335_RX1]), 4295 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, WCD9335_RX2, 0, 4296 &slim_rx_mux[WCD9335_RX2]), 4297 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, WCD9335_RX3, 0, 4298 &slim_rx_mux[WCD9335_RX3]), 4299 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, WCD9335_RX4, 0, 4300 &slim_rx_mux[WCD9335_RX4]), 4301 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, WCD9335_RX5, 0, 4302 &slim_rx_mux[WCD9335_RX5]), 4303 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, WCD9335_RX6, 0, 4304 &slim_rx_mux[WCD9335_RX6]), 4305 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, WCD9335_RX7, 0, 4306 &slim_rx_mux[WCD9335_RX7]), 4307 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), 4308 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4309 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4310 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), 4311 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), 4312 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), 4313 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), 4314 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), 4315 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL, 4316 5, 0, &rx_int0_2_mux, wcd9335_codec_enable_mix_path, 4317 SND_SOC_DAPM_POST_PMU), 4318 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 4319 5, 0, &rx_int1_2_mux, wcd9335_codec_enable_mix_path, 4320 SND_SOC_DAPM_POST_PMU), 4321 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 4322 5, 0, &rx_int2_2_mux, wcd9335_codec_enable_mix_path, 4323 SND_SOC_DAPM_POST_PMU), 4324 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL, 4325 5, 0, &rx_int3_2_mux, wcd9335_codec_enable_mix_path, 4326 SND_SOC_DAPM_POST_PMU), 4327 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL, 4328 5, 0, &rx_int4_2_mux, wcd9335_codec_enable_mix_path, 4329 SND_SOC_DAPM_POST_PMU), 4330 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL, 4331 5, 0, &rx_int5_2_mux, wcd9335_codec_enable_mix_path, 4332 SND_SOC_DAPM_POST_PMU), 4333 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL, 4334 5, 0, &rx_int6_2_mux, wcd9335_codec_enable_mix_path, 4335 SND_SOC_DAPM_POST_PMU), 4336 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL, 4337 5, 0, &rx_int7_2_mux, wcd9335_codec_enable_mix_path, 4338 SND_SOC_DAPM_POST_PMU), 4339 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL, 4340 5, 0, &rx_int8_2_mux, wcd9335_codec_enable_mix_path, 4341 SND_SOC_DAPM_POST_PMU), 4342 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4343 &rx_int0_1_mix_inp0_mux), 4344 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4345 &rx_int0_1_mix_inp1_mux), 4346 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4347 &rx_int0_1_mix_inp2_mux), 4348 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4349 &rx_int1_1_mix_inp0_mux), 4350 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4351 &rx_int1_1_mix_inp1_mux), 4352 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4353 &rx_int1_1_mix_inp2_mux), 4354 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4355 &rx_int2_1_mix_inp0_mux), 4356 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4357 &rx_int2_1_mix_inp1_mux), 4358 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4359 &rx_int2_1_mix_inp2_mux), 4360 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4361 &rx_int3_1_mix_inp0_mux), 4362 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4363 &rx_int3_1_mix_inp1_mux), 4364 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4365 &rx_int3_1_mix_inp2_mux), 4366 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4367 &rx_int4_1_mix_inp0_mux), 4368 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4369 &rx_int4_1_mix_inp1_mux), 4370 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4371 &rx_int4_1_mix_inp2_mux), 4372 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4373 &rx_int5_1_mix_inp0_mux), 4374 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4375 &rx_int5_1_mix_inp1_mux), 4376 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4377 &rx_int5_1_mix_inp2_mux), 4378 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4379 &rx_int6_1_mix_inp0_mux), 4380 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4381 &rx_int6_1_mix_inp1_mux), 4382 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4383 &rx_int6_1_mix_inp2_mux), 4384 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4385 &rx_int7_1_mix_inp0_mux), 4386 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4387 &rx_int7_1_mix_inp1_mux), 4388 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4389 &rx_int7_1_mix_inp2_mux), 4390 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 4391 &rx_int8_1_mix_inp0_mux), 4392 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 4393 &rx_int8_1_mix_inp1_mux), 4394 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 4395 &rx_int8_1_mix_inp2_mux), 4396 4397 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4398 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4399 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4400 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4401 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4402 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4403 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4404 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4405 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4406 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4407 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4408 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4409 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4410 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4411 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4412 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4413 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 4414 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 4415 4416 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4417 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4418 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4419 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4420 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4421 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4422 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4423 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4424 SND_SOC_DAPM_MIXER("RX INT8 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 4425 4426 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, 4427 &rx_int0_dem_inp_mux), 4428 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, 4429 &rx_int1_dem_inp_mux), 4430 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0, 4431 &rx_int2_dem_inp_mux), 4432 4433 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM, 4434 INTERP_EAR, 0, &rx_int0_interp_mux, 4435 wcd9335_codec_enable_interpolator, 4436 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4437 SND_SOC_DAPM_POST_PMD), 4438 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM, 4439 INTERP_HPHL, 0, &rx_int1_interp_mux, 4440 wcd9335_codec_enable_interpolator, 4441 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4442 SND_SOC_DAPM_POST_PMD), 4443 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM, 4444 INTERP_HPHR, 0, &rx_int2_interp_mux, 4445 wcd9335_codec_enable_interpolator, 4446 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4447 SND_SOC_DAPM_POST_PMD), 4448 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM, 4449 INTERP_LO1, 0, &rx_int3_interp_mux, 4450 wcd9335_codec_enable_interpolator, 4451 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4452 SND_SOC_DAPM_POST_PMD), 4453 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM, 4454 INTERP_LO2, 0, &rx_int4_interp_mux, 4455 wcd9335_codec_enable_interpolator, 4456 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4457 SND_SOC_DAPM_POST_PMD), 4458 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM, 4459 INTERP_LO3, 0, &rx_int5_interp_mux, 4460 wcd9335_codec_enable_interpolator, 4461 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4462 SND_SOC_DAPM_POST_PMD), 4463 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM, 4464 INTERP_LO4, 0, &rx_int6_interp_mux, 4465 wcd9335_codec_enable_interpolator, 4466 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4467 SND_SOC_DAPM_POST_PMD), 4468 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM, 4469 INTERP_SPKR1, 0, &rx_int7_interp_mux, 4470 wcd9335_codec_enable_interpolator, 4471 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4472 SND_SOC_DAPM_POST_PMD), 4473 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM, 4474 INTERP_SPKR2, 0, &rx_int8_interp_mux, 4475 wcd9335_codec_enable_interpolator, 4476 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4477 SND_SOC_DAPM_POST_PMD), 4478 4479 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, 4480 0, 0, wcd9335_codec_ear_dac_event, 4481 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4482 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4483 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH, 4484 5, 0, wcd9335_codec_hphl_dac_event, 4485 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4486 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4487 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH, 4488 4, 0, wcd9335_codec_hphr_dac_event, 4489 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4490 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4491 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM, 4492 0, 0, wcd9335_codec_lineout_dac_event, 4493 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 4494 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM, 4495 0, 0, wcd9335_codec_lineout_dac_event, 4496 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 4497 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM, 4498 0, 0, wcd9335_codec_lineout_dac_event, 4499 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 4500 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM, 4501 0, 0, wcd9335_codec_lineout_dac_event, 4502 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 4503 SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0, 4504 wcd9335_codec_enable_hphl_pa, 4505 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4506 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4507 SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0, 4508 wcd9335_codec_enable_hphr_pa, 4509 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4510 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4511 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0, 4512 wcd9335_codec_enable_ear_pa, 4513 SND_SOC_DAPM_POST_PMU | 4514 SND_SOC_DAPM_POST_PMD), 4515 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0, 4516 wcd9335_codec_enable_lineout_pa, 4517 SND_SOC_DAPM_POST_PMU | 4518 SND_SOC_DAPM_POST_PMD), 4519 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0, 4520 wcd9335_codec_enable_lineout_pa, 4521 SND_SOC_DAPM_POST_PMU | 4522 SND_SOC_DAPM_POST_PMD), 4523 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0, 4524 wcd9335_codec_enable_lineout_pa, 4525 SND_SOC_DAPM_POST_PMU | 4526 SND_SOC_DAPM_POST_PMD), 4527 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0, 4528 wcd9335_codec_enable_lineout_pa, 4529 SND_SOC_DAPM_POST_PMU | 4530 SND_SOC_DAPM_POST_PMD), 4531 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0, 4532 wcd9335_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | 4533 SND_SOC_DAPM_POST_PMD), 4534 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, 4535 wcd9335_codec_enable_mclk, SND_SOC_DAPM_PRE_PMU | 4536 SND_SOC_DAPM_POST_PMD), 4537 4538 /* TX */ 4539 SND_SOC_DAPM_INPUT("AMIC1"), 4540 SND_SOC_DAPM_INPUT("AMIC2"), 4541 SND_SOC_DAPM_INPUT("AMIC3"), 4542 SND_SOC_DAPM_INPUT("AMIC4"), 4543 SND_SOC_DAPM_INPUT("AMIC5"), 4544 SND_SOC_DAPM_INPUT("AMIC6"), 4545 4546 SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM, 4547 AIF1_CAP, 0, wcd9335_codec_enable_slim, 4548 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4549 4550 SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM, 4551 AIF2_CAP, 0, wcd9335_codec_enable_slim, 4552 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4553 4554 SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM, 4555 AIF3_CAP, 0, wcd9335_codec_enable_slim, 4556 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 4557 4558 SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, 0, 0, 4559 wcd9335_codec_enable_micbias, 4560 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4561 SND_SOC_DAPM_POST_PMD), 4562 SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, 0, 0, 4563 wcd9335_codec_enable_micbias, 4564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4565 SND_SOC_DAPM_POST_PMD), 4566 SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, 0, 0, 4567 wcd9335_codec_enable_micbias, 4568 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4569 SND_SOC_DAPM_POST_PMD), 4570 SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, 0, 0, 4571 wcd9335_codec_enable_micbias, 4572 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4573 SND_SOC_DAPM_POST_PMD), 4574 4575 SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9335_ANA_AMIC1, 7, 0, 4576 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), 4577 SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9335_ANA_AMIC2, 7, 0, 4578 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), 4579 SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9335_ANA_AMIC3, 7, 0, 4580 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), 4581 SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9335_ANA_AMIC4, 7, 0, 4582 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), 4583 SND_SOC_DAPM_ADC_E("ADC5", NULL, WCD9335_ANA_AMIC5, 7, 0, 4584 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), 4585 SND_SOC_DAPM_ADC_E("ADC6", NULL, WCD9335_ANA_AMIC6, 7, 0, 4586 wcd9335_codec_enable_adc, SND_SOC_DAPM_PRE_PMU), 4587 4588 /* Digital Mic Inputs */ 4589 SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0, 4590 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | 4591 SND_SOC_DAPM_POST_PMD), 4592 4593 SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0, 4594 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | 4595 SND_SOC_DAPM_POST_PMD), 4596 4597 SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 0, 0, 4598 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | 4599 SND_SOC_DAPM_POST_PMD), 4600 4601 SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 0, 0, 4602 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | 4603 SND_SOC_DAPM_POST_PMD), 4604 4605 SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 0, 0, 4606 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | 4607 SND_SOC_DAPM_POST_PMD), 4608 4609 SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 0, 0, 4610 wcd9335_codec_enable_dmic, SND_SOC_DAPM_PRE_PMU | 4611 SND_SOC_DAPM_POST_PMD), 4612 4613 SND_SOC_DAPM_MUX("DMIC MUX0", SND_SOC_NOPM, 0, 0, 4614 &tx_dmic_mux0), 4615 SND_SOC_DAPM_MUX("DMIC MUX1", SND_SOC_NOPM, 0, 0, 4616 &tx_dmic_mux1), 4617 SND_SOC_DAPM_MUX("DMIC MUX2", SND_SOC_NOPM, 0, 0, 4618 &tx_dmic_mux2), 4619 SND_SOC_DAPM_MUX("DMIC MUX3", SND_SOC_NOPM, 0, 0, 4620 &tx_dmic_mux3), 4621 SND_SOC_DAPM_MUX("DMIC MUX4", SND_SOC_NOPM, 0, 0, 4622 &tx_dmic_mux4), 4623 SND_SOC_DAPM_MUX("DMIC MUX5", SND_SOC_NOPM, 0, 0, 4624 &tx_dmic_mux5), 4625 SND_SOC_DAPM_MUX("DMIC MUX6", SND_SOC_NOPM, 0, 0, 4626 &tx_dmic_mux6), 4627 SND_SOC_DAPM_MUX("DMIC MUX7", SND_SOC_NOPM, 0, 0, 4628 &tx_dmic_mux7), 4629 SND_SOC_DAPM_MUX("DMIC MUX8", SND_SOC_NOPM, 0, 0, 4630 &tx_dmic_mux8), 4631 4632 SND_SOC_DAPM_MUX("AMIC MUX0", SND_SOC_NOPM, 0, 0, 4633 &tx_amic_mux0), 4634 SND_SOC_DAPM_MUX("AMIC MUX1", SND_SOC_NOPM, 0, 0, 4635 &tx_amic_mux1), 4636 SND_SOC_DAPM_MUX("AMIC MUX2", SND_SOC_NOPM, 0, 0, 4637 &tx_amic_mux2), 4638 SND_SOC_DAPM_MUX("AMIC MUX3", SND_SOC_NOPM, 0, 0, 4639 &tx_amic_mux3), 4640 SND_SOC_DAPM_MUX("AMIC MUX4", SND_SOC_NOPM, 0, 0, 4641 &tx_amic_mux4), 4642 SND_SOC_DAPM_MUX("AMIC MUX5", SND_SOC_NOPM, 0, 0, 4643 &tx_amic_mux5), 4644 SND_SOC_DAPM_MUX("AMIC MUX6", SND_SOC_NOPM, 0, 0, 4645 &tx_amic_mux6), 4646 SND_SOC_DAPM_MUX("AMIC MUX7", SND_SOC_NOPM, 0, 0, 4647 &tx_amic_mux7), 4648 SND_SOC_DAPM_MUX("AMIC MUX8", SND_SOC_NOPM, 0, 0, 4649 &tx_amic_mux8), 4650 4651 SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0, 4652 aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)), 4653 4654 SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0, 4655 aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)), 4656 4657 SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0, 4658 aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)), 4659 4660 SND_SOC_DAPM_MUX("SLIM TX0 MUX", SND_SOC_NOPM, WCD9335_TX0, 0, 4661 &sb_tx0_mux), 4662 SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, WCD9335_TX1, 0, 4663 &sb_tx1_mux), 4664 SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, WCD9335_TX2, 0, 4665 &sb_tx2_mux), 4666 SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, WCD9335_TX3, 0, 4667 &sb_tx3_mux), 4668 SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, WCD9335_TX4, 0, 4669 &sb_tx4_mux), 4670 SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, WCD9335_TX5, 0, 4671 &sb_tx5_mux), 4672 SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, WCD9335_TX6, 0, 4673 &sb_tx6_mux), 4674 SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, WCD9335_TX7, 0, 4675 &sb_tx7_mux), 4676 SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, WCD9335_TX8, 0, 4677 &sb_tx8_mux), 4678 4679 SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9335_CDC_TX0_TX_PATH_CTL, 5, 0, 4680 &tx_adc_mux0, wcd9335_codec_enable_dec, 4681 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4682 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4683 4684 SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9335_CDC_TX1_TX_PATH_CTL, 5, 0, 4685 &tx_adc_mux1, wcd9335_codec_enable_dec, 4686 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4687 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4688 4689 SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9335_CDC_TX2_TX_PATH_CTL, 5, 0, 4690 &tx_adc_mux2, wcd9335_codec_enable_dec, 4691 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4692 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4693 4694 SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9335_CDC_TX3_TX_PATH_CTL, 5, 0, 4695 &tx_adc_mux3, wcd9335_codec_enable_dec, 4696 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4697 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4698 4699 SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9335_CDC_TX4_TX_PATH_CTL, 5, 0, 4700 &tx_adc_mux4, wcd9335_codec_enable_dec, 4701 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4702 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4703 4704 SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9335_CDC_TX5_TX_PATH_CTL, 5, 0, 4705 &tx_adc_mux5, wcd9335_codec_enable_dec, 4706 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4707 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4708 4709 SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9335_CDC_TX6_TX_PATH_CTL, 5, 0, 4710 &tx_adc_mux6, wcd9335_codec_enable_dec, 4711 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4712 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4713 4714 SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9335_CDC_TX7_TX_PATH_CTL, 5, 0, 4715 &tx_adc_mux7, wcd9335_codec_enable_dec, 4716 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4717 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4718 4719 SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9335_CDC_TX8_TX_PATH_CTL, 5, 0, 4720 &tx_adc_mux8, wcd9335_codec_enable_dec, 4721 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 4722 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 4723 }; 4724 4725 static void wcd9335_enable_sido_buck(struct snd_soc_component *component) 4726 { 4727 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 4728 4729 snd_soc_component_update_bits(component, WCD9335_ANA_RCO, 4730 WCD9335_ANA_RCO_BG_EN_MASK, 4731 WCD9335_ANA_RCO_BG_ENABLE); 4732 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, 4733 WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_MASK, 4734 WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_EXT); 4735 /* 100us sleep needed after IREF settings */ 4736 usleep_range(100, 110); 4737 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, 4738 WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_MASK, 4739 WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT); 4740 /* 100us sleep needed after VREF settings */ 4741 usleep_range(100, 110); 4742 wcd->sido_input_src = SIDO_SOURCE_RCO_BG; 4743 } 4744 4745 static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp) 4746 { 4747 _wcd9335_codec_enable_mclk(comp, true); 4748 snd_soc_component_update_bits(comp, 4749 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 4750 WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK, 4751 WCD9335_CHIP_TIER_CTRL_EFUSE_ENABLE); 4752 /* 4753 * 5ms sleep required after enabling efuse control 4754 * before checking the status. 4755 */ 4756 usleep_range(5000, 5500); 4757 4758 if (!(snd_soc_component_read(comp, 4759 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 4760 WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK)) 4761 WARN(1, "%s: Efuse sense is not complete\n", __func__); 4762 4763 wcd9335_enable_sido_buck(comp); 4764 _wcd9335_codec_enable_mclk(comp, false); 4765 4766 return 0; 4767 } 4768 4769 static void wcd9335_codec_init(struct snd_soc_component *component) 4770 { 4771 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 4772 int i; 4773 4774 /* ungate MCLK and set clk rate */ 4775 regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_GATE, 4776 WCD9335_CODEC_RPM_CLK_GATE_MCLK_GATE_MASK, 0); 4777 4778 regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_MCLK_CFG, 4779 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, 4780 WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ); 4781 4782 for (i = 0; i < ARRAY_SIZE(wcd9335_codec_reg_init); i++) 4783 snd_soc_component_update_bits(component, 4784 wcd9335_codec_reg_init[i].reg, 4785 wcd9335_codec_reg_init[i].mask, 4786 wcd9335_codec_reg_init[i].val); 4787 4788 wcd9335_enable_efuse_sensing(component); 4789 } 4790 4791 static int wcd9335_codec_probe(struct snd_soc_component *component) 4792 { 4793 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 4794 int ret; 4795 int i; 4796 4797 snd_soc_component_init_regmap(component, wcd->regmap); 4798 /* Class-H Init*/ 4799 wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, WCD9335); 4800 if (IS_ERR(wcd->clsh_ctrl)) 4801 return PTR_ERR(wcd->clsh_ctrl); 4802 4803 /* Default HPH Mode to Class-H HiFi */ 4804 wcd->hph_mode = CLS_H_HIFI; 4805 wcd->component = component; 4806 4807 wcd9335_codec_init(component); 4808 4809 for (i = 0; i < NUM_CODEC_DAIS; i++) 4810 INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list); 4811 4812 ret = wcd9335_setup_irqs(wcd); 4813 if (ret) 4814 goto free_clsh_ctrl; 4815 4816 return 0; 4817 4818 free_clsh_ctrl: 4819 wcd_clsh_ctrl_free(wcd->clsh_ctrl); 4820 return ret; 4821 } 4822 4823 static void wcd9335_codec_remove(struct snd_soc_component *comp) 4824 { 4825 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 4826 4827 wcd_clsh_ctrl_free(wcd->clsh_ctrl); 4828 wcd9335_teardown_irqs(wcd); 4829 } 4830 4831 static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp, 4832 int clk_id, int source, 4833 unsigned int freq, int dir) 4834 { 4835 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 4836 4837 wcd->mclk_rate = freq; 4838 4839 if (wcd->mclk_rate == WCD9335_MCLK_CLK_12P288MHZ) 4840 snd_soc_component_update_bits(comp, 4841 WCD9335_CODEC_RPM_CLK_MCLK_CFG, 4842 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, 4843 WCD9335_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ); 4844 else if (wcd->mclk_rate == WCD9335_MCLK_CLK_9P6MHZ) 4845 snd_soc_component_update_bits(comp, 4846 WCD9335_CODEC_RPM_CLK_MCLK_CFG, 4847 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, 4848 WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ); 4849 4850 return clk_set_rate(wcd->mclk, freq); 4851 } 4852 4853 static const struct snd_soc_component_driver wcd9335_component_drv = { 4854 .probe = wcd9335_codec_probe, 4855 .remove = wcd9335_codec_remove, 4856 .set_sysclk = wcd9335_codec_set_sysclk, 4857 .controls = wcd9335_snd_controls, 4858 .num_controls = ARRAY_SIZE(wcd9335_snd_controls), 4859 .dapm_widgets = wcd9335_dapm_widgets, 4860 .num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets), 4861 .dapm_routes = wcd9335_audio_map, 4862 .num_dapm_routes = ARRAY_SIZE(wcd9335_audio_map), 4863 .endianness = 1, 4864 }; 4865 4866 static int wcd9335_probe(struct wcd9335_codec *wcd) 4867 { 4868 struct device *dev = wcd->dev; 4869 4870 memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs)); 4871 memcpy(wcd->tx_chs, wcd9335_tx_chs, sizeof(wcd9335_tx_chs)); 4872 4873 wcd->sido_input_src = SIDO_SOURCE_INTERNAL; 4874 wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV; 4875 4876 return devm_snd_soc_register_component(dev, &wcd9335_component_drv, 4877 wcd9335_slim_dais, 4878 ARRAY_SIZE(wcd9335_slim_dais)); 4879 } 4880 4881 static const struct regmap_range_cfg wcd9335_ranges[] = { 4882 { 4883 .name = "WCD9335", 4884 .range_min = 0x0, 4885 .range_max = WCD9335_MAX_REGISTER, 4886 .selector_reg = WCD9335_SEL_REGISTER, 4887 .selector_mask = 0xff, 4888 .selector_shift = 0, 4889 .window_start = 0x800, 4890 .window_len = 0x100, 4891 }, 4892 }; 4893 4894 static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg) 4895 { 4896 switch (reg) { 4897 case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3: 4898 case WCD9335_ANA_MBHC_RESULT_3: 4899 case WCD9335_ANA_MBHC_RESULT_2: 4900 case WCD9335_ANA_MBHC_RESULT_1: 4901 case WCD9335_ANA_MBHC_MECH: 4902 case WCD9335_ANA_MBHC_ELECT: 4903 case WCD9335_ANA_MBHC_ZDET: 4904 case WCD9335_ANA_MICB2: 4905 case WCD9335_ANA_RCO: 4906 case WCD9335_ANA_BIAS: 4907 return true; 4908 default: 4909 return false; 4910 } 4911 } 4912 4913 static const struct regmap_config wcd9335_regmap_config = { 4914 .reg_bits = 16, 4915 .val_bits = 8, 4916 .cache_type = REGCACHE_MAPLE, 4917 .max_register = WCD9335_MAX_REGISTER, 4918 .can_multi_write = true, 4919 .ranges = wcd9335_ranges, 4920 .num_ranges = ARRAY_SIZE(wcd9335_ranges), 4921 .volatile_reg = wcd9335_is_volatile_register, 4922 }; 4923 4924 static const struct regmap_range_cfg wcd9335_ifc_ranges[] = { 4925 { 4926 .name = "WCD9335-IFC-DEV", 4927 .range_min = 0x0, 4928 .range_max = WCD9335_MAX_REGISTER, 4929 .selector_reg = WCD9335_SEL_REGISTER, 4930 .selector_mask = 0xfff, 4931 .selector_shift = 0, 4932 .window_start = 0x800, 4933 .window_len = 0x400, 4934 }, 4935 }; 4936 4937 static const struct regmap_config wcd9335_ifc_regmap_config = { 4938 .reg_bits = 16, 4939 .val_bits = 8, 4940 .can_multi_write = true, 4941 .max_register = WCD9335_MAX_REGISTER, 4942 .ranges = wcd9335_ifc_ranges, 4943 .num_ranges = ARRAY_SIZE(wcd9335_ifc_ranges), 4944 }; 4945 4946 static const struct regmap_irq wcd9335_codec_irqs[] = { 4947 /* INTR_REG 0 */ 4948 [WCD9335_IRQ_SLIMBUS] = { 4949 .reg_offset = 0, 4950 .mask = BIT(0), 4951 .type = { 4952 .type_reg_offset = 0, 4953 .types_supported = IRQ_TYPE_EDGE_BOTH, 4954 .type_reg_mask = BIT(0), 4955 }, 4956 }, 4957 }; 4958 4959 static const unsigned int wcd9335_config_regs[] = { 4960 WCD9335_INTR_LEVEL0, 4961 }; 4962 4963 static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { 4964 .name = "wcd9335_pin1_irq", 4965 .status_base = WCD9335_INTR_PIN1_STATUS0, 4966 .mask_base = WCD9335_INTR_PIN1_MASK0, 4967 .ack_base = WCD9335_INTR_PIN1_CLEAR0, 4968 .num_regs = 4, 4969 .irqs = wcd9335_codec_irqs, 4970 .num_irqs = ARRAY_SIZE(wcd9335_codec_irqs), 4971 .config_base = wcd9335_config_regs, 4972 .num_config_bases = ARRAY_SIZE(wcd9335_config_regs), 4973 .num_config_regs = 4, 4974 .set_type_config = regmap_irq_set_type_config_simple, 4975 }; 4976 4977 static int wcd9335_parse_dt(struct wcd9335_codec *wcd) 4978 { 4979 struct device *dev = wcd->dev; 4980 struct device_node *np = dev->of_node; 4981 int ret; 4982 4983 wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); 4984 if (wcd->reset_gpio < 0) 4985 return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n"); 4986 4987 wcd->mclk = devm_clk_get(dev, "mclk"); 4988 if (IS_ERR(wcd->mclk)) 4989 return dev_err_probe(dev, PTR_ERR(wcd->mclk), "mclk not found\n"); 4990 4991 wcd->native_clk = devm_clk_get(dev, "slimbus"); 4992 if (IS_ERR(wcd->native_clk)) 4993 return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n"); 4994 4995 wcd->supplies[0].supply = "vdd-buck"; 4996 wcd->supplies[1].supply = "vdd-buck-sido"; 4997 wcd->supplies[2].supply = "vdd-tx"; 4998 wcd->supplies[3].supply = "vdd-rx"; 4999 wcd->supplies[4].supply = "vdd-io"; 5000 5001 ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies); 5002 if (ret) 5003 return dev_err_probe(dev, ret, "Failed to get supplies\n"); 5004 5005 return 0; 5006 } 5007 5008 static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) 5009 { 5010 struct device *dev = wcd->dev; 5011 int ret; 5012 5013 ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies); 5014 if (ret) { 5015 dev_err(dev, "Failed to get supplies: err = %d\n", ret); 5016 return ret; 5017 } 5018 5019 /* 5020 * For WCD9335, it takes about 600us for the Vout_A and 5021 * Vout_D to be ready after BUCK_SIDO is powered up. 5022 * SYS_RST_N shouldn't be pulled high during this time 5023 * Toggle the reset line to make sure the reset pulse is 5024 * correctly applied 5025 */ 5026 usleep_range(600, 650); 5027 5028 gpio_direction_output(wcd->reset_gpio, 0); 5029 msleep(20); 5030 gpio_set_value(wcd->reset_gpio, 1); 5031 msleep(20); 5032 5033 return 0; 5034 } 5035 5036 static int wcd9335_bring_up(struct wcd9335_codec *wcd) 5037 { 5038 struct regmap *rm = wcd->regmap; 5039 int val, byte0; 5040 5041 regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val); 5042 regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0); 5043 5044 if ((val < 0) || (byte0 < 0)) { 5045 dev_err(wcd->dev, "WCD9335 CODEC version detection fail!\n"); 5046 return -EINVAL; 5047 } 5048 5049 if (byte0 == 0x1) { 5050 dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n"); 5051 regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01); 5052 regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00); 5053 regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F); 5054 regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65); 5055 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); 5056 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); 5057 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); 5058 regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3); 5059 } else { 5060 dev_err(wcd->dev, "WCD9335 CODEC version not supported\n"); 5061 return -EINVAL; 5062 } 5063 5064 return 0; 5065 } 5066 5067 static int wcd9335_irq_init(struct wcd9335_codec *wcd) 5068 { 5069 int ret; 5070 5071 /* 5072 * INTR1 consists of all possible interrupt sources Ear OCP, 5073 * HPH OCP, MBHC, MAD, VBAT, and SVA 5074 * INTR2 is a subset of first interrupt sources MAD, VBAT, and SVA 5075 */ 5076 wcd->intr1 = of_irq_get_byname(wcd->dev->of_node, "intr1"); 5077 if (wcd->intr1 < 0) 5078 return dev_err_probe(wcd->dev, wcd->intr1, 5079 "Unable to configure IRQ\n"); 5080 5081 ret = devm_regmap_add_irq_chip(wcd->dev, wcd->regmap, wcd->intr1, 5082 IRQF_TRIGGER_HIGH, 0, 5083 &wcd9335_regmap_irq1_chip, &wcd->irq_data); 5084 if (ret) 5085 return dev_err_probe(wcd->dev, ret, "Failed to register IRQ chip\n"); 5086 5087 return 0; 5088 } 5089 5090 static int wcd9335_slim_probe(struct slim_device *slim) 5091 { 5092 struct device *dev = &slim->dev; 5093 struct wcd9335_codec *wcd; 5094 int ret; 5095 5096 wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); 5097 if (!wcd) 5098 return -ENOMEM; 5099 5100 wcd->dev = dev; 5101 ret = wcd9335_parse_dt(wcd); 5102 if (ret) 5103 return ret; 5104 5105 ret = wcd9335_power_on_reset(wcd); 5106 if (ret) 5107 return ret; 5108 5109 dev_set_drvdata(dev, wcd); 5110 5111 return 0; 5112 } 5113 5114 static int wcd9335_slim_status(struct slim_device *sdev, 5115 enum slim_device_status status) 5116 { 5117 struct device *dev = &sdev->dev; 5118 struct device_node *ifc_dev_np; 5119 struct wcd9335_codec *wcd; 5120 int ret; 5121 5122 wcd = dev_get_drvdata(dev); 5123 5124 ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0); 5125 if (!ifc_dev_np) { 5126 dev_err(dev, "No Interface device found\n"); 5127 return -EINVAL; 5128 } 5129 5130 wcd->slim = sdev; 5131 wcd->slim_ifc_dev = of_slim_get_device(sdev->ctrl, ifc_dev_np); 5132 of_node_put(ifc_dev_np); 5133 if (!wcd->slim_ifc_dev) { 5134 dev_err(dev, "Unable to get SLIM Interface device\n"); 5135 return -EINVAL; 5136 } 5137 5138 slim_get_logical_addr(wcd->slim_ifc_dev); 5139 5140 wcd->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config); 5141 if (IS_ERR(wcd->regmap)) 5142 return dev_err_probe(dev, PTR_ERR(wcd->regmap), 5143 "Failed to allocate slim register map\n"); 5144 5145 wcd->if_regmap = regmap_init_slimbus(wcd->slim_ifc_dev, 5146 &wcd9335_ifc_regmap_config); 5147 if (IS_ERR(wcd->if_regmap)) 5148 return dev_err_probe(dev, PTR_ERR(wcd->if_regmap), 5149 "Failed to allocate ifc register map\n"); 5150 5151 ret = wcd9335_bring_up(wcd); 5152 if (ret) { 5153 dev_err(dev, "Failed to bringup WCD9335\n"); 5154 return ret; 5155 } 5156 5157 ret = wcd9335_irq_init(wcd); 5158 if (ret) 5159 return ret; 5160 5161 wcd9335_probe(wcd); 5162 5163 return 0; 5164 } 5165 5166 static const struct slim_device_id wcd9335_slim_id[] = { 5167 {SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9335, 0x1, 0x0}, 5168 {} 5169 }; 5170 MODULE_DEVICE_TABLE(slim, wcd9335_slim_id); 5171 5172 static struct slim_driver wcd9335_slim_driver = { 5173 .driver = { 5174 .name = "wcd9335-slim", 5175 }, 5176 .probe = wcd9335_slim_probe, 5177 .device_status = wcd9335_slim_status, 5178 .id_table = wcd9335_slim_id, 5179 }; 5180 5181 module_slim_driver(wcd9335_slim_driver); 5182 MODULE_DESCRIPTION("WCD9335 slim driver"); 5183 MODULE_LICENSE("GPL v2"); 5184 MODULE_ALIAS("slim:217:1a0:*"); 5185