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