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