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 64 #define WCD9335_SLIM_RX_CH(p) \ 65 {.port = p + WCD9335_RX_START, .shift = p,} 66 67 /* vout step value */ 68 #define WCD9335_CALCULATE_VOUT_D(req_mv) (((req_mv - 650) * 10) / 25) 69 70 enum { 71 WCD9335_RX0 = 0, 72 WCD9335_RX1, 73 WCD9335_RX2, 74 WCD9335_RX3, 75 WCD9335_RX4, 76 WCD9335_RX5, 77 WCD9335_RX6, 78 WCD9335_RX7, 79 WCD9335_RX8, 80 WCD9335_RX9, 81 WCD9335_RX10, 82 WCD9335_RX11, 83 WCD9335_RX12, 84 WCD9335_RX_MAX, 85 }; 86 87 enum { 88 SIDO_SOURCE_INTERNAL = 0, 89 SIDO_SOURCE_RCO_BG, 90 }; 91 92 enum wcd9335_sido_voltage { 93 SIDO_VOLTAGE_SVS_MV = 950, 94 SIDO_VOLTAGE_NOMINAL_MV = 1100, 95 }; 96 97 enum { 98 AIF1_PB = 0, 99 AIF1_CAP, 100 AIF2_PB, 101 AIF2_CAP, 102 AIF3_PB, 103 AIF3_CAP, 104 AIF4_PB, 105 NUM_CODEC_DAIS, 106 }; 107 108 enum { 109 COMPANDER_1, /* HPH_L */ 110 COMPANDER_2, /* HPH_R */ 111 COMPANDER_3, /* LO1_DIFF */ 112 COMPANDER_4, /* LO2_DIFF */ 113 COMPANDER_5, /* LO3_SE */ 114 COMPANDER_6, /* LO4_SE */ 115 COMPANDER_7, /* SWR SPK CH1 */ 116 COMPANDER_8, /* SWR SPK CH2 */ 117 COMPANDER_MAX, 118 }; 119 120 enum { 121 INTn_2_INP_SEL_ZERO = 0, 122 INTn_2_INP_SEL_RX0, 123 INTn_2_INP_SEL_RX1, 124 INTn_2_INP_SEL_RX2, 125 INTn_2_INP_SEL_RX3, 126 INTn_2_INP_SEL_RX4, 127 INTn_2_INP_SEL_RX5, 128 INTn_2_INP_SEL_RX6, 129 INTn_2_INP_SEL_RX7, 130 INTn_2_INP_SEL_PROXIMITY, 131 }; 132 133 enum { 134 INTn_1_MIX_INP_SEL_ZERO = 0, 135 INTn_1_MIX_INP_SEL_DEC0, 136 INTn_1_MIX_INP_SEL_DEC1, 137 INTn_1_MIX_INP_SEL_IIR0, 138 INTn_1_MIX_INP_SEL_IIR1, 139 INTn_1_MIX_INP_SEL_RX0, 140 INTn_1_MIX_INP_SEL_RX1, 141 INTn_1_MIX_INP_SEL_RX2, 142 INTn_1_MIX_INP_SEL_RX3, 143 INTn_1_MIX_INP_SEL_RX4, 144 INTn_1_MIX_INP_SEL_RX5, 145 INTn_1_MIX_INP_SEL_RX6, 146 INTn_1_MIX_INP_SEL_RX7, 147 148 }; 149 150 enum { 151 INTERP_EAR = 0, 152 INTERP_HPHL, 153 INTERP_HPHR, 154 INTERP_LO1, 155 INTERP_LO2, 156 INTERP_LO3, 157 INTERP_LO4, 158 INTERP_SPKR1, 159 INTERP_SPKR2, 160 }; 161 162 enum wcd_clock_type { 163 WCD_CLK_OFF, 164 WCD_CLK_RCO, 165 WCD_CLK_MCLK, 166 }; 167 168 struct wcd9335_slim_ch { 169 u32 ch_num; 170 u16 port; 171 u16 shift; 172 struct list_head list; 173 }; 174 175 struct wcd_slim_codec_dai_data { 176 struct list_head slim_ch_list; 177 struct slim_stream_config sconfig; 178 struct slim_stream_runtime *sruntime; 179 }; 180 181 struct wcd9335_codec { 182 struct device *dev; 183 struct clk *mclk; 184 struct clk *native_clk; 185 u32 mclk_rate; 186 u8 version; 187 188 struct slim_device *slim; 189 struct slim_device *slim_ifc_dev; 190 struct regmap *regmap; 191 struct regmap *if_regmap; 192 struct regmap_irq_chip_data *irq_data; 193 194 struct wcd9335_slim_ch rx_chs[WCD9335_RX_MAX]; 195 u32 num_rx_port; 196 197 int sido_input_src; 198 enum wcd9335_sido_voltage sido_voltage; 199 200 struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS]; 201 struct snd_soc_component *component; 202 203 int master_bias_users; 204 int clk_mclk_users; 205 int clk_rco_users; 206 int sido_ccl_cnt; 207 enum wcd_clock_type clk_type; 208 209 struct wcd_clsh_ctrl *clsh_ctrl; 210 u32 hph_mode; 211 int prim_int_users[WCD9335_NUM_INTERPOLATORS]; 212 213 int comp_enabled[COMPANDER_MAX]; 214 215 int intr1; 216 int reset_gpio; 217 struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; 218 219 unsigned int rx_port_value; 220 int hph_l_gain; 221 int hph_r_gain; 222 u32 rx_bias_count; 223 224 }; 225 226 struct wcd9335_irq { 227 int irq; 228 irqreturn_t (*handler)(int irq, void *data); 229 char *name; 230 }; 231 232 static const struct wcd9335_slim_ch wcd9335_rx_chs[WCD9335_RX_MAX] = { 233 WCD9335_SLIM_RX_CH(0), /* 16 */ 234 WCD9335_SLIM_RX_CH(1), /* 17 */ 235 WCD9335_SLIM_RX_CH(2), 236 WCD9335_SLIM_RX_CH(3), 237 WCD9335_SLIM_RX_CH(4), 238 WCD9335_SLIM_RX_CH(5), 239 WCD9335_SLIM_RX_CH(6), 240 WCD9335_SLIM_RX_CH(7), 241 WCD9335_SLIM_RX_CH(8), 242 WCD9335_SLIM_RX_CH(9), 243 WCD9335_SLIM_RX_CH(10), 244 WCD9335_SLIM_RX_CH(11), 245 WCD9335_SLIM_RX_CH(12), 246 }; 247 248 struct interp_sample_rate { 249 int rate; 250 int rate_val; 251 }; 252 253 static struct interp_sample_rate int_mix_rate_val[] = { 254 {48000, 0x4}, /* 48K */ 255 {96000, 0x5}, /* 96K */ 256 {192000, 0x6}, /* 192K */ 257 }; 258 259 static struct interp_sample_rate int_prim_rate_val[] = { 260 {8000, 0x0}, /* 8K */ 261 {16000, 0x1}, /* 16K */ 262 {24000, -EINVAL},/* 24K */ 263 {32000, 0x3}, /* 32K */ 264 {48000, 0x4}, /* 48K */ 265 {96000, 0x5}, /* 96K */ 266 {192000, 0x6}, /* 192K */ 267 {384000, 0x7}, /* 384K */ 268 {44100, 0x8}, /* 44.1K */ 269 }; 270 271 struct wcd9335_reg_mask_val { 272 u16 reg; 273 u8 mask; 274 u8 val; 275 }; 276 277 static const struct wcd9335_reg_mask_val wcd9335_codec_reg_init[] = { 278 /* Rbuckfly/R_EAR(32) */ 279 {WCD9335_CDC_CLSH_K2_MSB, 0x0F, 0x00}, 280 {WCD9335_CDC_CLSH_K2_LSB, 0xFF, 0x60}, 281 {WCD9335_CPE_SS_DMIC_CFG, 0x80, 0x00}, 282 {WCD9335_CDC_BOOST0_BOOST_CTL, 0x70, 0x50}, 283 {WCD9335_CDC_BOOST1_BOOST_CTL, 0x70, 0x50}, 284 {WCD9335_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08}, 285 {WCD9335_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08}, 286 {WCD9335_ANA_LO_1_2, 0x3C, 0X3C}, 287 {WCD9335_DIFF_LO_COM_SWCAP_REFBUF_FREQ, 0x70, 0x00}, 288 {WCD9335_DIFF_LO_COM_PA_FREQ, 0x70, 0x40}, 289 {WCD9335_SOC_MAD_AUDIO_CTL_2, 0x03, 0x03}, 290 {WCD9335_CDC_TOP_TOP_CFG1, 0x02, 0x02}, 291 {WCD9335_CDC_TOP_TOP_CFG1, 0x01, 0x01}, 292 {WCD9335_EAR_CMBUFF, 0x08, 0x00}, 293 {WCD9335_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 294 {WCD9335_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 295 {WCD9335_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 296 {WCD9335_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01}, 297 {WCD9335_CDC_COMPANDER7_CTL3, 0x80, 0x80}, 298 {WCD9335_CDC_COMPANDER8_CTL3, 0x80, 0x80}, 299 {WCD9335_CDC_COMPANDER7_CTL7, 0x01, 0x01}, 300 {WCD9335_CDC_COMPANDER8_CTL7, 0x01, 0x01}, 301 {WCD9335_CDC_RX0_RX_PATH_CFG0, 0x01, 0x01}, 302 {WCD9335_CDC_RX1_RX_PATH_CFG0, 0x01, 0x01}, 303 {WCD9335_CDC_RX2_RX_PATH_CFG0, 0x01, 0x01}, 304 {WCD9335_CDC_RX3_RX_PATH_CFG0, 0x01, 0x01}, 305 {WCD9335_CDC_RX4_RX_PATH_CFG0, 0x01, 0x01}, 306 {WCD9335_CDC_RX5_RX_PATH_CFG0, 0x01, 0x01}, 307 {WCD9335_CDC_RX6_RX_PATH_CFG0, 0x01, 0x01}, 308 {WCD9335_CDC_RX7_RX_PATH_CFG0, 0x01, 0x01}, 309 {WCD9335_CDC_RX8_RX_PATH_CFG0, 0x01, 0x01}, 310 {WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 0x01, 0x01}, 311 {WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 0x01, 0x01}, 312 {WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 0x01, 0x01}, 313 {WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 0x01, 0x01}, 314 {WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 0x01, 0x01}, 315 {WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 0x01, 0x01}, 316 {WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 0x01, 0x01}, 317 {WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 0x01, 0x01}, 318 {WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 0x01, 0x01}, 319 {WCD9335_VBADC_IBIAS_FE, 0x0C, 0x08}, 320 {WCD9335_RCO_CTRL_2, 0x0F, 0x08}, 321 {WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10}, 322 {WCD9335_FLYBACK_CTRL_1, 0x20, 0x20}, 323 {WCD9335_HPH_OCP_CTL, 0xFF, 0x5A}, 324 {WCD9335_HPH_L_TEST, 0x01, 0x01}, 325 {WCD9335_HPH_R_TEST, 0x01, 0x01}, 326 {WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12}, 327 {WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08}, 328 {WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18}, 329 {WCD9335_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12}, 330 {WCD9335_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08}, 331 {WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18}, 332 {WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45}, 333 {WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4}, 334 {WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08}, 335 {WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02}, 336 }; 337 338 /* Cutoff frequency for high pass filter */ 339 static const char * const cf_text[] = { 340 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ" 341 }; 342 343 static const char * const rx_cf_text[] = { 344 "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ", 345 "CF_NEG_3DB_0P48HZ" 346 }; 347 348 static const char * const rx_int0_7_mix_mux_text[] = { 349 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", 350 "RX6", "RX7", "PROXIMITY" 351 }; 352 353 static const char * const rx_int_mix_mux_text[] = { 354 "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", 355 "RX6", "RX7" 356 }; 357 358 static const char * const rx_prim_mix_text[] = { 359 "ZERO", "DEC0", "DEC1", "IIR0", "IIR1", "RX0", "RX1", "RX2", 360 "RX3", "RX4", "RX5", "RX6", "RX7" 361 }; 362 363 static const char * const rx_int_dem_inp_mux_text[] = { 364 "NORMAL_DSM_OUT", "CLSH_DSM_OUT", 365 }; 366 367 static const char * const rx_int0_interp_mux_text[] = { 368 "ZERO", "RX INT0 MIX2", 369 }; 370 371 static const char * const rx_int1_interp_mux_text[] = { 372 "ZERO", "RX INT1 MIX2", 373 }; 374 375 static const char * const rx_int2_interp_mux_text[] = { 376 "ZERO", "RX INT2 MIX2", 377 }; 378 379 static const char * const rx_int3_interp_mux_text[] = { 380 "ZERO", "RX INT3 MIX2", 381 }; 382 383 static const char * const rx_int4_interp_mux_text[] = { 384 "ZERO", "RX INT4 MIX2", 385 }; 386 387 static const char * const rx_int5_interp_mux_text[] = { 388 "ZERO", "RX INT5 MIX2", 389 }; 390 391 static const char * const rx_int6_interp_mux_text[] = { 392 "ZERO", "RX INT6 MIX2", 393 }; 394 395 static const char * const rx_int7_interp_mux_text[] = { 396 "ZERO", "RX INT7 MIX2", 397 }; 398 399 static const char * const rx_int8_interp_mux_text[] = { 400 "ZERO", "RX INT8 SEC MIX" 401 }; 402 403 static const char * const rx_hph_mode_mux_text[] = { 404 "Class H Invalid", "Class-H Hi-Fi", "Class-H Low Power", "Class-AB", 405 "Class-H Hi-Fi Low Power" 406 }; 407 408 static const char *const slim_rx_mux_text[] = { 409 "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", 410 }; 411 412 static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); 413 static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); 414 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); 415 static const DECLARE_TLV_DB_SCALE(ear_pa_gain, 0, 150, 0); 416 417 static const struct soc_enum cf_dec0_enum = 418 SOC_ENUM_SINGLE(WCD9335_CDC_TX0_TX_PATH_CFG0, 5, 3, cf_text); 419 420 static const struct soc_enum cf_dec1_enum = 421 SOC_ENUM_SINGLE(WCD9335_CDC_TX1_TX_PATH_CFG0, 5, 3, cf_text); 422 423 static const struct soc_enum cf_dec2_enum = 424 SOC_ENUM_SINGLE(WCD9335_CDC_TX2_TX_PATH_CFG0, 5, 3, cf_text); 425 426 static const struct soc_enum cf_dec3_enum = 427 SOC_ENUM_SINGLE(WCD9335_CDC_TX3_TX_PATH_CFG0, 5, 3, cf_text); 428 429 static const struct soc_enum cf_dec4_enum = 430 SOC_ENUM_SINGLE(WCD9335_CDC_TX4_TX_PATH_CFG0, 5, 3, cf_text); 431 432 static const struct soc_enum cf_dec5_enum = 433 SOC_ENUM_SINGLE(WCD9335_CDC_TX5_TX_PATH_CFG0, 5, 3, cf_text); 434 435 static const struct soc_enum cf_dec6_enum = 436 SOC_ENUM_SINGLE(WCD9335_CDC_TX6_TX_PATH_CFG0, 5, 3, cf_text); 437 438 static const struct soc_enum cf_dec7_enum = 439 SOC_ENUM_SINGLE(WCD9335_CDC_TX7_TX_PATH_CFG0, 5, 3, cf_text); 440 441 static const struct soc_enum cf_dec8_enum = 442 SOC_ENUM_SINGLE(WCD9335_CDC_TX8_TX_PATH_CFG0, 5, 3, cf_text); 443 444 static const struct soc_enum cf_int0_1_enum = 445 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CFG2, 0, 4, rx_cf_text); 446 447 static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9335_CDC_RX0_RX_PATH_MIX_CFG, 2, 448 rx_cf_text); 449 450 static const struct soc_enum cf_int1_1_enum = 451 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CFG2, 0, 4, rx_cf_text); 452 453 static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, WCD9335_CDC_RX1_RX_PATH_MIX_CFG, 2, 454 rx_cf_text); 455 456 static const struct soc_enum cf_int2_1_enum = 457 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CFG2, 0, 4, rx_cf_text); 458 459 static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, WCD9335_CDC_RX2_RX_PATH_MIX_CFG, 2, 460 rx_cf_text); 461 462 static const struct soc_enum cf_int3_1_enum = 463 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CFG2, 0, 4, rx_cf_text); 464 465 static SOC_ENUM_SINGLE_DECL(cf_int3_2_enum, WCD9335_CDC_RX3_RX_PATH_MIX_CFG, 2, 466 rx_cf_text); 467 468 static const struct soc_enum cf_int4_1_enum = 469 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CFG2, 0, 4, rx_cf_text); 470 471 static SOC_ENUM_SINGLE_DECL(cf_int4_2_enum, WCD9335_CDC_RX4_RX_PATH_MIX_CFG, 2, 472 rx_cf_text); 473 474 static const struct soc_enum cf_int5_1_enum = 475 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CFG2, 0, 4, rx_cf_text); 476 477 static SOC_ENUM_SINGLE_DECL(cf_int5_2_enum, WCD9335_CDC_RX5_RX_PATH_MIX_CFG, 2, 478 rx_cf_text); 479 480 static const struct soc_enum cf_int6_1_enum = 481 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CFG2, 0, 4, rx_cf_text); 482 483 static SOC_ENUM_SINGLE_DECL(cf_int6_2_enum, WCD9335_CDC_RX6_RX_PATH_MIX_CFG, 2, 484 rx_cf_text); 485 486 static const struct soc_enum cf_int7_1_enum = 487 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CFG2, 0, 4, rx_cf_text); 488 489 static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9335_CDC_RX7_RX_PATH_MIX_CFG, 2, 490 rx_cf_text); 491 492 static const struct soc_enum cf_int8_1_enum = 493 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CFG2, 0, 4, rx_cf_text); 494 495 static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9335_CDC_RX8_RX_PATH_MIX_CFG, 2, 496 rx_cf_text); 497 498 static const struct soc_enum rx_hph_mode_mux_enum = 499 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), 500 rx_hph_mode_mux_text); 501 502 static const struct soc_enum slim_rx_mux_enum = 503 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slim_rx_mux_text), slim_rx_mux_text); 504 505 static const struct soc_enum rx_int0_2_mux_chain_enum = 506 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 0, 10, 507 rx_int0_7_mix_mux_text); 508 509 static const struct soc_enum rx_int1_2_mux_chain_enum = 510 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 0, 9, 511 rx_int_mix_mux_text); 512 513 static const struct soc_enum rx_int2_2_mux_chain_enum = 514 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 0, 9, 515 rx_int_mix_mux_text); 516 517 static const struct soc_enum rx_int3_2_mux_chain_enum = 518 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 0, 9, 519 rx_int_mix_mux_text); 520 521 static const struct soc_enum rx_int4_2_mux_chain_enum = 522 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 0, 9, 523 rx_int_mix_mux_text); 524 525 static const struct soc_enum rx_int5_2_mux_chain_enum = 526 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 0, 9, 527 rx_int_mix_mux_text); 528 529 static const struct soc_enum rx_int6_2_mux_chain_enum = 530 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 0, 9, 531 rx_int_mix_mux_text); 532 533 static const struct soc_enum rx_int7_2_mux_chain_enum = 534 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 0, 10, 535 rx_int0_7_mix_mux_text); 536 537 static const struct soc_enum rx_int8_2_mux_chain_enum = 538 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 0, 9, 539 rx_int_mix_mux_text); 540 541 static const struct soc_enum rx_int0_1_mix_inp0_chain_enum = 542 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 0, 13, 543 rx_prim_mix_text); 544 545 static const struct soc_enum rx_int0_1_mix_inp1_chain_enum = 546 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG0, 4, 13, 547 rx_prim_mix_text); 548 549 static const struct soc_enum rx_int0_1_mix_inp2_chain_enum = 550 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT0_CFG1, 4, 13, 551 rx_prim_mix_text); 552 553 static const struct soc_enum rx_int1_1_mix_inp0_chain_enum = 554 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 0, 13, 555 rx_prim_mix_text); 556 557 static const struct soc_enum rx_int1_1_mix_inp1_chain_enum = 558 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG0, 4, 13, 559 rx_prim_mix_text); 560 561 static const struct soc_enum rx_int1_1_mix_inp2_chain_enum = 562 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT1_CFG1, 4, 13, 563 rx_prim_mix_text); 564 565 static const struct soc_enum rx_int2_1_mix_inp0_chain_enum = 566 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 0, 13, 567 rx_prim_mix_text); 568 569 static const struct soc_enum rx_int2_1_mix_inp1_chain_enum = 570 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG0, 4, 13, 571 rx_prim_mix_text); 572 573 static const struct soc_enum rx_int2_1_mix_inp2_chain_enum = 574 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT2_CFG1, 4, 13, 575 rx_prim_mix_text); 576 577 static const struct soc_enum rx_int3_1_mix_inp0_chain_enum = 578 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 0, 13, 579 rx_prim_mix_text); 580 581 static const struct soc_enum rx_int3_1_mix_inp1_chain_enum = 582 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG0, 4, 13, 583 rx_prim_mix_text); 584 585 static const struct soc_enum rx_int3_1_mix_inp2_chain_enum = 586 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT3_CFG1, 4, 13, 587 rx_prim_mix_text); 588 589 static const struct soc_enum rx_int4_1_mix_inp0_chain_enum = 590 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 0, 13, 591 rx_prim_mix_text); 592 593 static const struct soc_enum rx_int4_1_mix_inp1_chain_enum = 594 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG0, 4, 13, 595 rx_prim_mix_text); 596 597 static const struct soc_enum rx_int4_1_mix_inp2_chain_enum = 598 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT4_CFG1, 4, 13, 599 rx_prim_mix_text); 600 601 static const struct soc_enum rx_int5_1_mix_inp0_chain_enum = 602 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 0, 13, 603 rx_prim_mix_text); 604 605 static const struct soc_enum rx_int5_1_mix_inp1_chain_enum = 606 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG0, 4, 13, 607 rx_prim_mix_text); 608 609 static const struct soc_enum rx_int5_1_mix_inp2_chain_enum = 610 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT5_CFG1, 4, 13, 611 rx_prim_mix_text); 612 613 static const struct soc_enum rx_int6_1_mix_inp0_chain_enum = 614 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 0, 13, 615 rx_prim_mix_text); 616 617 static const struct soc_enum rx_int6_1_mix_inp1_chain_enum = 618 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG0, 4, 13, 619 rx_prim_mix_text); 620 621 static const struct soc_enum rx_int6_1_mix_inp2_chain_enum = 622 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT6_CFG1, 4, 13, 623 rx_prim_mix_text); 624 625 static const struct soc_enum rx_int7_1_mix_inp0_chain_enum = 626 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 0, 13, 627 rx_prim_mix_text); 628 629 static const struct soc_enum rx_int7_1_mix_inp1_chain_enum = 630 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG0, 4, 13, 631 rx_prim_mix_text); 632 633 static const struct soc_enum rx_int7_1_mix_inp2_chain_enum = 634 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT7_CFG1, 4, 13, 635 rx_prim_mix_text); 636 637 static const struct soc_enum rx_int8_1_mix_inp0_chain_enum = 638 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 0, 13, 639 rx_prim_mix_text); 640 641 static const struct soc_enum rx_int8_1_mix_inp1_chain_enum = 642 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG0, 4, 13, 643 rx_prim_mix_text); 644 645 static const struct soc_enum rx_int8_1_mix_inp2_chain_enum = 646 SOC_ENUM_SINGLE(WCD9335_CDC_RX_INP_MUX_RX_INT8_CFG1, 4, 13, 647 rx_prim_mix_text); 648 649 static const struct soc_enum rx_int0_dem_inp_mux_enum = 650 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_SEC0, 0, 651 ARRAY_SIZE(rx_int_dem_inp_mux_text), 652 rx_int_dem_inp_mux_text); 653 654 static const struct soc_enum rx_int1_dem_inp_mux_enum = 655 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_SEC0, 0, 656 ARRAY_SIZE(rx_int_dem_inp_mux_text), 657 rx_int_dem_inp_mux_text); 658 659 static const struct soc_enum rx_int2_dem_inp_mux_enum = 660 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_SEC0, 0, 661 ARRAY_SIZE(rx_int_dem_inp_mux_text), 662 rx_int_dem_inp_mux_text); 663 664 static const struct soc_enum rx_int0_interp_mux_enum = 665 SOC_ENUM_SINGLE(WCD9335_CDC_RX0_RX_PATH_CTL, 5, 2, 666 rx_int0_interp_mux_text); 667 668 static const struct soc_enum rx_int1_interp_mux_enum = 669 SOC_ENUM_SINGLE(WCD9335_CDC_RX1_RX_PATH_CTL, 5, 2, 670 rx_int1_interp_mux_text); 671 672 static const struct soc_enum rx_int2_interp_mux_enum = 673 SOC_ENUM_SINGLE(WCD9335_CDC_RX2_RX_PATH_CTL, 5, 2, 674 rx_int2_interp_mux_text); 675 676 static const struct soc_enum rx_int3_interp_mux_enum = 677 SOC_ENUM_SINGLE(WCD9335_CDC_RX3_RX_PATH_CTL, 5, 2, 678 rx_int3_interp_mux_text); 679 680 static const struct soc_enum rx_int4_interp_mux_enum = 681 SOC_ENUM_SINGLE(WCD9335_CDC_RX4_RX_PATH_CTL, 5, 2, 682 rx_int4_interp_mux_text); 683 684 static const struct soc_enum rx_int5_interp_mux_enum = 685 SOC_ENUM_SINGLE(WCD9335_CDC_RX5_RX_PATH_CTL, 5, 2, 686 rx_int5_interp_mux_text); 687 688 static const struct soc_enum rx_int6_interp_mux_enum = 689 SOC_ENUM_SINGLE(WCD9335_CDC_RX6_RX_PATH_CTL, 5, 2, 690 rx_int6_interp_mux_text); 691 692 static const struct soc_enum rx_int7_interp_mux_enum = 693 SOC_ENUM_SINGLE(WCD9335_CDC_RX7_RX_PATH_CTL, 5, 2, 694 rx_int7_interp_mux_text); 695 696 static const struct soc_enum rx_int8_interp_mux_enum = 697 SOC_ENUM_SINGLE(WCD9335_CDC_RX8_RX_PATH_CTL, 5, 2, 698 rx_int8_interp_mux_text); 699 700 static const struct snd_kcontrol_new rx_int0_2_mux = 701 SOC_DAPM_ENUM("RX INT0_2 MUX Mux", rx_int0_2_mux_chain_enum); 702 703 static const struct snd_kcontrol_new rx_int1_2_mux = 704 SOC_DAPM_ENUM("RX INT1_2 MUX Mux", rx_int1_2_mux_chain_enum); 705 706 static const struct snd_kcontrol_new rx_int2_2_mux = 707 SOC_DAPM_ENUM("RX INT2_2 MUX Mux", rx_int2_2_mux_chain_enum); 708 709 static const struct snd_kcontrol_new rx_int3_2_mux = 710 SOC_DAPM_ENUM("RX INT3_2 MUX Mux", rx_int3_2_mux_chain_enum); 711 712 static const struct snd_kcontrol_new rx_int4_2_mux = 713 SOC_DAPM_ENUM("RX INT4_2 MUX Mux", rx_int4_2_mux_chain_enum); 714 715 static const struct snd_kcontrol_new rx_int5_2_mux = 716 SOC_DAPM_ENUM("RX INT5_2 MUX Mux", rx_int5_2_mux_chain_enum); 717 718 static const struct snd_kcontrol_new rx_int6_2_mux = 719 SOC_DAPM_ENUM("RX INT6_2 MUX Mux", rx_int6_2_mux_chain_enum); 720 721 static const struct snd_kcontrol_new rx_int7_2_mux = 722 SOC_DAPM_ENUM("RX INT7_2 MUX Mux", rx_int7_2_mux_chain_enum); 723 724 static const struct snd_kcontrol_new rx_int8_2_mux = 725 SOC_DAPM_ENUM("RX INT8_2 MUX Mux", rx_int8_2_mux_chain_enum); 726 727 static const struct snd_kcontrol_new rx_int0_1_mix_inp0_mux = 728 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP0 Mux", rx_int0_1_mix_inp0_chain_enum); 729 730 static const struct snd_kcontrol_new rx_int0_1_mix_inp1_mux = 731 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP1 Mux", rx_int0_1_mix_inp1_chain_enum); 732 733 static const struct snd_kcontrol_new rx_int0_1_mix_inp2_mux = 734 SOC_DAPM_ENUM("RX INT0_1 MIX1 INP2 Mux", rx_int0_1_mix_inp2_chain_enum); 735 736 static const struct snd_kcontrol_new rx_int1_1_mix_inp0_mux = 737 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP0 Mux", rx_int1_1_mix_inp0_chain_enum); 738 739 static const struct snd_kcontrol_new rx_int1_1_mix_inp1_mux = 740 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP1 Mux", rx_int1_1_mix_inp1_chain_enum); 741 742 static const struct snd_kcontrol_new rx_int1_1_mix_inp2_mux = 743 SOC_DAPM_ENUM("RX INT1_1 MIX1 INP2 Mux", rx_int1_1_mix_inp2_chain_enum); 744 745 static const struct snd_kcontrol_new rx_int2_1_mix_inp0_mux = 746 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP0 Mux", rx_int2_1_mix_inp0_chain_enum); 747 748 static const struct snd_kcontrol_new rx_int2_1_mix_inp1_mux = 749 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP1 Mux", rx_int2_1_mix_inp1_chain_enum); 750 751 static const struct snd_kcontrol_new rx_int2_1_mix_inp2_mux = 752 SOC_DAPM_ENUM("RX INT2_1 MIX1 INP2 Mux", rx_int2_1_mix_inp2_chain_enum); 753 754 static const struct snd_kcontrol_new rx_int3_1_mix_inp0_mux = 755 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP0 Mux", rx_int3_1_mix_inp0_chain_enum); 756 757 static const struct snd_kcontrol_new rx_int3_1_mix_inp1_mux = 758 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP1 Mux", rx_int3_1_mix_inp1_chain_enum); 759 760 static const struct snd_kcontrol_new rx_int3_1_mix_inp2_mux = 761 SOC_DAPM_ENUM("RX INT3_1 MIX1 INP2 Mux", rx_int3_1_mix_inp2_chain_enum); 762 763 static const struct snd_kcontrol_new rx_int4_1_mix_inp0_mux = 764 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP0 Mux", rx_int4_1_mix_inp0_chain_enum); 765 766 static const struct snd_kcontrol_new rx_int4_1_mix_inp1_mux = 767 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP1 Mux", rx_int4_1_mix_inp1_chain_enum); 768 769 static const struct snd_kcontrol_new rx_int4_1_mix_inp2_mux = 770 SOC_DAPM_ENUM("RX INT4_1 MIX1 INP2 Mux", rx_int4_1_mix_inp2_chain_enum); 771 772 static const struct snd_kcontrol_new rx_int5_1_mix_inp0_mux = 773 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP0 Mux", rx_int5_1_mix_inp0_chain_enum); 774 775 static const struct snd_kcontrol_new rx_int5_1_mix_inp1_mux = 776 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP1 Mux", rx_int5_1_mix_inp1_chain_enum); 777 778 static const struct snd_kcontrol_new rx_int5_1_mix_inp2_mux = 779 SOC_DAPM_ENUM("RX INT5_1 MIX1 INP2 Mux", rx_int5_1_mix_inp2_chain_enum); 780 781 static const struct snd_kcontrol_new rx_int6_1_mix_inp0_mux = 782 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP0 Mux", rx_int6_1_mix_inp0_chain_enum); 783 784 static const struct snd_kcontrol_new rx_int6_1_mix_inp1_mux = 785 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP1 Mux", rx_int6_1_mix_inp1_chain_enum); 786 787 static const struct snd_kcontrol_new rx_int6_1_mix_inp2_mux = 788 SOC_DAPM_ENUM("RX INT6_1 MIX1 INP2 Mux", rx_int6_1_mix_inp2_chain_enum); 789 790 static const struct snd_kcontrol_new rx_int7_1_mix_inp0_mux = 791 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP0 Mux", rx_int7_1_mix_inp0_chain_enum); 792 793 static const struct snd_kcontrol_new rx_int7_1_mix_inp1_mux = 794 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP1 Mux", rx_int7_1_mix_inp1_chain_enum); 795 796 static const struct snd_kcontrol_new rx_int7_1_mix_inp2_mux = 797 SOC_DAPM_ENUM("RX INT7_1 MIX1 INP2 Mux", rx_int7_1_mix_inp2_chain_enum); 798 799 static const struct snd_kcontrol_new rx_int8_1_mix_inp0_mux = 800 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP0 Mux", rx_int8_1_mix_inp0_chain_enum); 801 802 static const struct snd_kcontrol_new rx_int8_1_mix_inp1_mux = 803 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP1 Mux", rx_int8_1_mix_inp1_chain_enum); 804 805 static const struct snd_kcontrol_new rx_int8_1_mix_inp2_mux = 806 SOC_DAPM_ENUM("RX INT8_1 MIX1 INP2 Mux", rx_int8_1_mix_inp2_chain_enum); 807 808 static const struct snd_kcontrol_new rx_int0_interp_mux = 809 SOC_DAPM_ENUM("RX INT0 INTERP Mux", rx_int0_interp_mux_enum); 810 811 static const struct snd_kcontrol_new rx_int1_interp_mux = 812 SOC_DAPM_ENUM("RX INT1 INTERP Mux", rx_int1_interp_mux_enum); 813 814 static const struct snd_kcontrol_new rx_int2_interp_mux = 815 SOC_DAPM_ENUM("RX INT2 INTERP Mux", rx_int2_interp_mux_enum); 816 817 static const struct snd_kcontrol_new rx_int3_interp_mux = 818 SOC_DAPM_ENUM("RX INT3 INTERP Mux", rx_int3_interp_mux_enum); 819 820 static const struct snd_kcontrol_new rx_int4_interp_mux = 821 SOC_DAPM_ENUM("RX INT4 INTERP Mux", rx_int4_interp_mux_enum); 822 823 static const struct snd_kcontrol_new rx_int5_interp_mux = 824 SOC_DAPM_ENUM("RX INT5 INTERP Mux", rx_int5_interp_mux_enum); 825 826 static const struct snd_kcontrol_new rx_int6_interp_mux = 827 SOC_DAPM_ENUM("RX INT6 INTERP Mux", rx_int6_interp_mux_enum); 828 829 static const struct snd_kcontrol_new rx_int7_interp_mux = 830 SOC_DAPM_ENUM("RX INT7 INTERP Mux", rx_int7_interp_mux_enum); 831 832 static const struct snd_kcontrol_new rx_int8_interp_mux = 833 SOC_DAPM_ENUM("RX INT8 INTERP Mux", rx_int8_interp_mux_enum); 834 835 static int slim_rx_mux_get(struct snd_kcontrol *kc, 836 struct snd_ctl_elem_value *ucontrol) 837 { 838 struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); 839 struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev); 840 841 ucontrol->value.enumerated.item[0] = wcd->rx_port_value; 842 843 return 0; 844 } 845 846 static int slim_rx_mux_put(struct snd_kcontrol *kc, 847 struct snd_ctl_elem_value *ucontrol) 848 { 849 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); 850 struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); 851 struct soc_enum *e = (struct soc_enum *)kc->private_value; 852 struct snd_soc_dapm_update *update = NULL; 853 u32 port_id = w->shift; 854 855 wcd->rx_port_value = ucontrol->value.enumerated.item[0]; 856 857 switch (wcd->rx_port_value) { 858 case 0: 859 list_del_init(&wcd->rx_chs[port_id].list); 860 break; 861 case 1: 862 list_add_tail(&wcd->rx_chs[port_id].list, 863 &wcd->dai[AIF1_PB].slim_ch_list); 864 break; 865 case 2: 866 list_add_tail(&wcd->rx_chs[port_id].list, 867 &wcd->dai[AIF2_PB].slim_ch_list); 868 break; 869 case 3: 870 list_add_tail(&wcd->rx_chs[port_id].list, 871 &wcd->dai[AIF3_PB].slim_ch_list); 872 break; 873 case 4: 874 list_add_tail(&wcd->rx_chs[port_id].list, 875 &wcd->dai[AIF4_PB].slim_ch_list); 876 break; 877 default: 878 dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value); 879 goto err; 880 } 881 882 snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value, 883 e, update); 884 885 return 0; 886 err: 887 return -EINVAL; 888 } 889 890 static const struct snd_kcontrol_new slim_rx_mux[WCD9335_RX_MAX] = { 891 SOC_DAPM_ENUM_EXT("SLIM RX0 Mux", slim_rx_mux_enum, 892 slim_rx_mux_get, slim_rx_mux_put), 893 SOC_DAPM_ENUM_EXT("SLIM RX1 Mux", slim_rx_mux_enum, 894 slim_rx_mux_get, slim_rx_mux_put), 895 SOC_DAPM_ENUM_EXT("SLIM RX2 Mux", slim_rx_mux_enum, 896 slim_rx_mux_get, slim_rx_mux_put), 897 SOC_DAPM_ENUM_EXT("SLIM RX3 Mux", slim_rx_mux_enum, 898 slim_rx_mux_get, slim_rx_mux_put), 899 SOC_DAPM_ENUM_EXT("SLIM RX4 Mux", slim_rx_mux_enum, 900 slim_rx_mux_get, slim_rx_mux_put), 901 SOC_DAPM_ENUM_EXT("SLIM RX5 Mux", slim_rx_mux_enum, 902 slim_rx_mux_get, slim_rx_mux_put), 903 SOC_DAPM_ENUM_EXT("SLIM RX6 Mux", slim_rx_mux_enum, 904 slim_rx_mux_get, slim_rx_mux_put), 905 SOC_DAPM_ENUM_EXT("SLIM RX7 Mux", slim_rx_mux_enum, 906 slim_rx_mux_get, slim_rx_mux_put), 907 }; 908 909 static int wcd9335_int_dem_inp_mux_put(struct snd_kcontrol *kc, 910 struct snd_ctl_elem_value *ucontrol) 911 { 912 struct soc_enum *e = (struct soc_enum *)kc->private_value; 913 struct snd_soc_component *component; 914 int reg, val; 915 916 component = snd_soc_dapm_kcontrol_component(kc); 917 val = ucontrol->value.enumerated.item[0]; 918 919 if (e->reg == WCD9335_CDC_RX0_RX_PATH_SEC0) 920 reg = WCD9335_CDC_RX0_RX_PATH_CFG0; 921 else if (e->reg == WCD9335_CDC_RX1_RX_PATH_SEC0) 922 reg = WCD9335_CDC_RX1_RX_PATH_CFG0; 923 else if (e->reg == WCD9335_CDC_RX2_RX_PATH_SEC0) 924 reg = WCD9335_CDC_RX2_RX_PATH_CFG0; 925 else 926 return -EINVAL; 927 928 /* Set Look Ahead Delay */ 929 snd_soc_component_update_bits(component, reg, 930 WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN_MASK, 931 val ? WCD9335_CDC_RX_PATH_CFG0_DLY_ZN_EN : 0); 932 /* Set DEM INP Select */ 933 return snd_soc_dapm_put_enum_double(kc, ucontrol); 934 } 935 936 static const struct snd_kcontrol_new rx_int0_dem_inp_mux = 937 SOC_DAPM_ENUM_EXT("RX INT0 DEM MUX Mux", rx_int0_dem_inp_mux_enum, 938 snd_soc_dapm_get_enum_double, 939 wcd9335_int_dem_inp_mux_put); 940 941 static const struct snd_kcontrol_new rx_int1_dem_inp_mux = 942 SOC_DAPM_ENUM_EXT("RX INT1 DEM MUX Mux", rx_int1_dem_inp_mux_enum, 943 snd_soc_dapm_get_enum_double, 944 wcd9335_int_dem_inp_mux_put); 945 946 static const struct snd_kcontrol_new rx_int2_dem_inp_mux = 947 SOC_DAPM_ENUM_EXT("RX INT2 DEM MUX Mux", rx_int2_dem_inp_mux_enum, 948 snd_soc_dapm_get_enum_double, 949 wcd9335_int_dem_inp_mux_put); 950 951 static int wcd9335_set_mix_interpolator_rate(struct snd_soc_dai *dai, 952 int rate_val, 953 u32 rate) 954 { 955 struct snd_soc_component *component = dai->component; 956 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 957 struct wcd9335_slim_ch *ch; 958 int val, j; 959 960 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { 961 for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) { 962 val = snd_soc_component_read32(component, 963 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)) & 964 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 965 966 if (val == (ch->shift + INTn_2_INP_SEL_RX0)) 967 snd_soc_component_update_bits(component, 968 WCD9335_CDC_RX_PATH_MIX_CTL(j), 969 WCD9335_CDC_MIX_PCM_RATE_MASK, 970 rate_val); 971 } 972 } 973 974 return 0; 975 } 976 977 static int wcd9335_set_prim_interpolator_rate(struct snd_soc_dai *dai, 978 u8 rate_val, 979 u32 rate) 980 { 981 struct snd_soc_component *comp = dai->component; 982 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 983 struct wcd9335_slim_ch *ch; 984 u8 cfg0, cfg1, inp0_sel, inp1_sel, inp2_sel; 985 int inp, j; 986 987 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) { 988 inp = ch->shift + INTn_1_MIX_INP_SEL_RX0; 989 /* 990 * Loop through all interpolator MUX inputs and find out 991 * to which interpolator input, the slim rx port 992 * is connected 993 */ 994 for (j = 0; j < WCD9335_NUM_INTERPOLATORS; j++) { 995 cfg0 = snd_soc_component_read32(comp, 996 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG0(j)); 997 cfg1 = snd_soc_component_read32(comp, 998 WCD9335_CDC_RX_INP_MUX_RX_INT_CFG1(j)); 999 1000 inp0_sel = cfg0 & 1001 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1002 inp1_sel = (cfg0 >> 4) & 1003 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1004 inp2_sel = (cfg1 >> 4) & 1005 WCD9335_CDC_RX_INP_MUX_RX_INT_SEL_MASK; 1006 1007 if ((inp0_sel == inp) || (inp1_sel == inp) || 1008 (inp2_sel == inp)) { 1009 /* rate is in Hz */ 1010 if ((j == 0) && (rate == 44100)) 1011 dev_info(wcd->dev, 1012 "Cannot set 44.1KHz on INT0\n"); 1013 else 1014 snd_soc_component_update_bits(comp, 1015 WCD9335_CDC_RX_PATH_CTL(j), 1016 WCD9335_CDC_MIX_PCM_RATE_MASK, 1017 rate_val); 1018 } 1019 } 1020 } 1021 1022 return 0; 1023 } 1024 1025 static int wcd9335_set_interpolator_rate(struct snd_soc_dai *dai, u32 rate) 1026 { 1027 int i; 1028 1029 /* set mixing path rate */ 1030 for (i = 0; i < ARRAY_SIZE(int_mix_rate_val); i++) { 1031 if (rate == int_mix_rate_val[i].rate) { 1032 wcd9335_set_mix_interpolator_rate(dai, 1033 int_mix_rate_val[i].rate_val, rate); 1034 break; 1035 } 1036 } 1037 1038 /* set primary path sample rate */ 1039 for (i = 0; i < ARRAY_SIZE(int_prim_rate_val); i++) { 1040 if (rate == int_prim_rate_val[i].rate) { 1041 wcd9335_set_prim_interpolator_rate(dai, 1042 int_prim_rate_val[i].rate_val, rate); 1043 break; 1044 } 1045 } 1046 1047 return 0; 1048 } 1049 1050 static int wcd9335_slim_set_hw_params(struct wcd9335_codec *wcd, 1051 struct wcd_slim_codec_dai_data *dai_data, 1052 int direction) 1053 { 1054 struct list_head *slim_ch_list = &dai_data->slim_ch_list; 1055 struct slim_stream_config *cfg = &dai_data->sconfig; 1056 struct wcd9335_slim_ch *ch; 1057 u16 payload = 0; 1058 int ret, i; 1059 1060 cfg->ch_count = 0; 1061 cfg->direction = direction; 1062 cfg->port_mask = 0; 1063 1064 /* Configure slave interface device */ 1065 list_for_each_entry(ch, slim_ch_list, list) { 1066 cfg->ch_count++; 1067 payload |= 1 << ch->shift; 1068 cfg->port_mask |= BIT(ch->port); 1069 } 1070 1071 cfg->chs = kcalloc(cfg->ch_count, sizeof(unsigned int), GFP_KERNEL); 1072 if (!cfg->chs) 1073 return -ENOMEM; 1074 1075 i = 0; 1076 list_for_each_entry(ch, slim_ch_list, list) { 1077 cfg->chs[i++] = ch->ch_num; 1078 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 1079 /* write to interface device */ 1080 ret = regmap_write(wcd->if_regmap, 1081 WCD9335_SLIM_PGD_RX_PORT_MULTI_CHNL_0(ch->port), 1082 payload); 1083 1084 if (ret < 0) 1085 goto err; 1086 1087 /* configure the slave port for water mark and enable*/ 1088 ret = regmap_write(wcd->if_regmap, 1089 WCD9335_SLIM_PGD_RX_PORT_CFG(ch->port), 1090 WCD9335_SLIM_WATER_MARK_VAL); 1091 if (ret < 0) 1092 goto err; 1093 } 1094 } 1095 1096 dai_data->sruntime = slim_stream_allocate(wcd->slim, "WCD9335-SLIM"); 1097 1098 return 0; 1099 1100 err: 1101 dev_err(wcd->dev, "Error Setting slim hw params\n"); 1102 kfree(cfg->chs); 1103 cfg->chs = NULL; 1104 1105 return ret; 1106 } 1107 1108 static int wcd9335_hw_params(struct snd_pcm_substream *substream, 1109 struct snd_pcm_hw_params *params, 1110 struct snd_soc_dai *dai) 1111 { 1112 struct wcd9335_codec *wcd; 1113 int ret; 1114 1115 wcd = snd_soc_component_get_drvdata(dai->component); 1116 1117 switch (substream->stream) { 1118 case SNDRV_PCM_STREAM_PLAYBACK: 1119 ret = wcd9335_set_interpolator_rate(dai, params_rate(params)); 1120 if (ret) { 1121 dev_err(wcd->dev, "cannot set sample rate: %u\n", 1122 params_rate(params)); 1123 return ret; 1124 } 1125 switch (params_width(params)) { 1126 case 16 ... 24: 1127 wcd->dai[dai->id].sconfig.bps = params_width(params); 1128 break; 1129 default: 1130 dev_err(wcd->dev, "%s: Invalid format 0x%x\n", 1131 __func__, params_width(params)); 1132 return -EINVAL; 1133 } 1134 break; 1135 default: 1136 dev_err(wcd->dev, "Invalid stream type %d\n", 1137 substream->stream); 1138 return -EINVAL; 1139 }; 1140 1141 wcd->dai[dai->id].sconfig.rate = params_rate(params); 1142 wcd9335_slim_set_hw_params(wcd, &wcd->dai[dai->id], substream->stream); 1143 1144 return 0; 1145 } 1146 1147 static int wcd9335_trigger(struct snd_pcm_substream *substream, int cmd, 1148 struct snd_soc_dai *dai) 1149 { 1150 struct wcd_slim_codec_dai_data *dai_data; 1151 struct wcd9335_codec *wcd; 1152 struct slim_stream_config *cfg; 1153 1154 wcd = snd_soc_component_get_drvdata(dai->component); 1155 1156 dai_data = &wcd->dai[dai->id]; 1157 1158 switch (cmd) { 1159 case SNDRV_PCM_TRIGGER_START: 1160 case SNDRV_PCM_TRIGGER_RESUME: 1161 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1162 cfg = &dai_data->sconfig; 1163 slim_stream_prepare(dai_data->sruntime, cfg); 1164 slim_stream_enable(dai_data->sruntime); 1165 break; 1166 case SNDRV_PCM_TRIGGER_STOP: 1167 case SNDRV_PCM_TRIGGER_SUSPEND: 1168 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1169 slim_stream_unprepare(dai_data->sruntime); 1170 slim_stream_disable(dai_data->sruntime); 1171 break; 1172 default: 1173 break; 1174 } 1175 1176 return 0; 1177 } 1178 1179 static int wcd9335_set_channel_map(struct snd_soc_dai *dai, 1180 unsigned int tx_num, unsigned int *tx_slot, 1181 unsigned int rx_num, unsigned int *rx_slot) 1182 { 1183 struct wcd9335_codec *wcd; 1184 int i; 1185 1186 wcd = snd_soc_component_get_drvdata(dai->component); 1187 1188 if (!tx_slot || !rx_slot) { 1189 dev_err(wcd->dev, "Invalid tx_slot=%p, rx_slot=%p\n", 1190 tx_slot, rx_slot); 1191 return -EINVAL; 1192 } 1193 1194 if (wcd->rx_chs) { 1195 wcd->num_rx_port = rx_num; 1196 for (i = 0; i < rx_num; i++) { 1197 wcd->rx_chs[i].ch_num = rx_slot[i]; 1198 INIT_LIST_HEAD(&wcd->rx_chs[i].list); 1199 } 1200 } 1201 1202 return 0; 1203 } 1204 1205 static int wcd9335_get_channel_map(struct snd_soc_dai *dai, 1206 unsigned int *tx_num, unsigned int *tx_slot, 1207 unsigned int *rx_num, unsigned int *rx_slot) 1208 { 1209 struct wcd9335_slim_ch *ch; 1210 struct wcd9335_codec *wcd; 1211 int i = 0; 1212 1213 wcd = snd_soc_component_get_drvdata(dai->component); 1214 1215 switch (dai->id) { 1216 case AIF1_PB: 1217 case AIF2_PB: 1218 case AIF3_PB: 1219 case AIF4_PB: 1220 if (!rx_slot || !rx_num) { 1221 dev_err(wcd->dev, "Invalid rx_slot %p or rx_num %p\n", 1222 rx_slot, rx_num); 1223 return -EINVAL; 1224 } 1225 1226 list_for_each_entry(ch, &wcd->dai[dai->id].slim_ch_list, list) 1227 rx_slot[i++] = ch->ch_num; 1228 1229 *rx_num = i; 1230 break; 1231 default: 1232 dev_err(wcd->dev, "Invalid DAI ID %x\n", dai->id); 1233 break; 1234 } 1235 1236 return 0; 1237 } 1238 1239 static struct snd_soc_dai_ops wcd9335_dai_ops = { 1240 .hw_params = wcd9335_hw_params, 1241 .trigger = wcd9335_trigger, 1242 .set_channel_map = wcd9335_set_channel_map, 1243 .get_channel_map = wcd9335_get_channel_map, 1244 }; 1245 1246 static struct snd_soc_dai_driver wcd9335_slim_dais[] = { 1247 [0] = { 1248 .name = "wcd9335_rx1", 1249 .id = AIF1_PB, 1250 .playback = { 1251 .stream_name = "AIF1 Playback", 1252 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 1253 .formats = WCD9335_FORMATS_S16_S24_LE, 1254 .rate_max = 192000, 1255 .rate_min = 8000, 1256 .channels_min = 1, 1257 .channels_max = 2, 1258 }, 1259 .ops = &wcd9335_dai_ops, 1260 }, 1261 [1] = { 1262 .name = "wcd9335_tx1", 1263 .id = AIF1_CAP, 1264 .capture = { 1265 .stream_name = "AIF1 Capture", 1266 .rates = WCD9335_RATES_MASK, 1267 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1268 .rate_min = 8000, 1269 .rate_max = 192000, 1270 .channels_min = 1, 1271 .channels_max = 4, 1272 }, 1273 .ops = &wcd9335_dai_ops, 1274 }, 1275 [2] = { 1276 .name = "wcd9335_rx2", 1277 .id = AIF2_PB, 1278 .playback = { 1279 .stream_name = "AIF2 Playback", 1280 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 1281 .formats = WCD9335_FORMATS_S16_S24_LE, 1282 .rate_min = 8000, 1283 .rate_max = 192000, 1284 .channels_min = 1, 1285 .channels_max = 2, 1286 }, 1287 .ops = &wcd9335_dai_ops, 1288 }, 1289 [3] = { 1290 .name = "wcd9335_tx2", 1291 .id = AIF2_CAP, 1292 .capture = { 1293 .stream_name = "AIF2 Capture", 1294 .rates = WCD9335_RATES_MASK, 1295 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1296 .rate_min = 8000, 1297 .rate_max = 192000, 1298 .channels_min = 1, 1299 .channels_max = 4, 1300 }, 1301 .ops = &wcd9335_dai_ops, 1302 }, 1303 [4] = { 1304 .name = "wcd9335_rx3", 1305 .id = AIF3_PB, 1306 .playback = { 1307 .stream_name = "AIF3 Playback", 1308 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 1309 .formats = WCD9335_FORMATS_S16_S24_LE, 1310 .rate_min = 8000, 1311 .rate_max = 192000, 1312 .channels_min = 1, 1313 .channels_max = 2, 1314 }, 1315 .ops = &wcd9335_dai_ops, 1316 }, 1317 [5] = { 1318 .name = "wcd9335_tx3", 1319 .id = AIF3_CAP, 1320 .capture = { 1321 .stream_name = "AIF3 Capture", 1322 .rates = WCD9335_RATES_MASK, 1323 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1324 .rate_min = 8000, 1325 .rate_max = 192000, 1326 .channels_min = 1, 1327 .channels_max = 4, 1328 }, 1329 .ops = &wcd9335_dai_ops, 1330 }, 1331 [6] = { 1332 .name = "wcd9335_rx4", 1333 .id = AIF4_PB, 1334 .playback = { 1335 .stream_name = "AIF4 Playback", 1336 .rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK, 1337 .formats = WCD9335_FORMATS_S16_S24_LE, 1338 .rate_min = 8000, 1339 .rate_max = 192000, 1340 .channels_min = 1, 1341 .channels_max = 2, 1342 }, 1343 .ops = &wcd9335_dai_ops, 1344 }, 1345 }; 1346 1347 static int wcd9335_get_compander(struct snd_kcontrol *kc, 1348 struct snd_ctl_elem_value *ucontrol) 1349 { 1350 1351 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 1352 int comp = ((struct soc_mixer_control *)kc->private_value)->shift; 1353 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1354 1355 ucontrol->value.integer.value[0] = wcd->comp_enabled[comp]; 1356 return 0; 1357 } 1358 1359 static int wcd9335_set_compander(struct snd_kcontrol *kc, 1360 struct snd_ctl_elem_value *ucontrol) 1361 { 1362 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 1363 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1364 int comp = ((struct soc_mixer_control *) kc->private_value)->shift; 1365 int value = ucontrol->value.integer.value[0]; 1366 int sel; 1367 1368 wcd->comp_enabled[comp] = value; 1369 sel = value ? WCD9335_HPH_GAIN_SRC_SEL_COMPANDER : 1370 WCD9335_HPH_GAIN_SRC_SEL_REGISTER; 1371 1372 /* Any specific register configuration for compander */ 1373 switch (comp) { 1374 case COMPANDER_1: 1375 /* Set Gain Source Select based on compander enable/disable */ 1376 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 1377 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 1378 break; 1379 case COMPANDER_2: 1380 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 1381 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 1382 break; 1383 case COMPANDER_5: 1384 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO3_GAIN, 1385 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 1386 break; 1387 case COMPANDER_6: 1388 snd_soc_component_update_bits(component, WCD9335_SE_LO_LO4_GAIN, 1389 WCD9335_HPH_GAIN_SRC_SEL_MASK, sel); 1390 break; 1391 default: 1392 break; 1393 }; 1394 1395 return 0; 1396 } 1397 1398 static int wcd9335_rx_hph_mode_get(struct snd_kcontrol *kc, 1399 struct snd_ctl_elem_value *ucontrol) 1400 { 1401 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 1402 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1403 1404 ucontrol->value.enumerated.item[0] = wcd->hph_mode; 1405 1406 return 0; 1407 } 1408 1409 static int wcd9335_rx_hph_mode_put(struct snd_kcontrol *kc, 1410 struct snd_ctl_elem_value *ucontrol) 1411 { 1412 struct snd_soc_component *component = snd_soc_kcontrol_component(kc); 1413 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1414 u32 mode_val; 1415 1416 mode_val = ucontrol->value.enumerated.item[0]; 1417 1418 if (mode_val == 0) { 1419 dev_err(wcd->dev, "Invalid HPH Mode, default to ClSH HiFi\n"); 1420 mode_val = CLS_H_HIFI; 1421 } 1422 wcd->hph_mode = mode_val; 1423 1424 return 0; 1425 } 1426 1427 static const struct snd_kcontrol_new wcd9335_snd_controls[] = { 1428 /* -84dB min - 40dB max */ 1429 SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9335_CDC_RX0_RX_VOL_CTL, 1430 0, -84, 40, digital_gain), 1431 SOC_SINGLE_SX_TLV("RX1 Digital Volume", WCD9335_CDC_RX1_RX_VOL_CTL, 1432 0, -84, 40, digital_gain), 1433 SOC_SINGLE_SX_TLV("RX2 Digital Volume", WCD9335_CDC_RX2_RX_VOL_CTL, 1434 0, -84, 40, digital_gain), 1435 SOC_SINGLE_SX_TLV("RX3 Digital Volume", WCD9335_CDC_RX3_RX_VOL_CTL, 1436 0, -84, 40, digital_gain), 1437 SOC_SINGLE_SX_TLV("RX4 Digital Volume", WCD9335_CDC_RX4_RX_VOL_CTL, 1438 0, -84, 40, digital_gain), 1439 SOC_SINGLE_SX_TLV("RX5 Digital Volume", WCD9335_CDC_RX5_RX_VOL_CTL, 1440 0, -84, 40, digital_gain), 1441 SOC_SINGLE_SX_TLV("RX6 Digital Volume", WCD9335_CDC_RX6_RX_VOL_CTL, 1442 0, -84, 40, digital_gain), 1443 SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9335_CDC_RX7_RX_VOL_CTL, 1444 0, -84, 40, digital_gain), 1445 SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9335_CDC_RX8_RX_VOL_CTL, 1446 0, -84, 40, digital_gain), 1447 SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume", 1448 WCD9335_CDC_RX0_RX_VOL_MIX_CTL, 1449 0, -84, 40, digital_gain), 1450 SOC_SINGLE_SX_TLV("RX1 Mix Digital Volume", 1451 WCD9335_CDC_RX1_RX_VOL_MIX_CTL, 1452 0, -84, 40, digital_gain), 1453 SOC_SINGLE_SX_TLV("RX2 Mix Digital Volume", 1454 WCD9335_CDC_RX2_RX_VOL_MIX_CTL, 1455 0, -84, 40, digital_gain), 1456 SOC_SINGLE_SX_TLV("RX3 Mix Digital Volume", 1457 WCD9335_CDC_RX3_RX_VOL_MIX_CTL, 1458 0, -84, 40, digital_gain), 1459 SOC_SINGLE_SX_TLV("RX4 Mix Digital Volume", 1460 WCD9335_CDC_RX4_RX_VOL_MIX_CTL, 1461 0, -84, 40, digital_gain), 1462 SOC_SINGLE_SX_TLV("RX5 Mix Digital Volume", 1463 WCD9335_CDC_RX5_RX_VOL_MIX_CTL, 1464 0, -84, 40, digital_gain), 1465 SOC_SINGLE_SX_TLV("RX6 Mix Digital Volume", 1466 WCD9335_CDC_RX6_RX_VOL_MIX_CTL, 1467 0, -84, 40, digital_gain), 1468 SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume", 1469 WCD9335_CDC_RX7_RX_VOL_MIX_CTL, 1470 0, -84, 40, digital_gain), 1471 SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume", 1472 WCD9335_CDC_RX8_RX_VOL_MIX_CTL, 1473 0, -84, 40, digital_gain), 1474 SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum), 1475 SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum), 1476 SOC_ENUM("RX INT1_1 HPF cut off", cf_int1_1_enum), 1477 SOC_ENUM("RX INT1_2 HPF cut off", cf_int1_2_enum), 1478 SOC_ENUM("RX INT2_1 HPF cut off", cf_int2_1_enum), 1479 SOC_ENUM("RX INT2_2 HPF cut off", cf_int2_2_enum), 1480 SOC_ENUM("RX INT3_1 HPF cut off", cf_int3_1_enum), 1481 SOC_ENUM("RX INT3_2 HPF cut off", cf_int3_2_enum), 1482 SOC_ENUM("RX INT4_1 HPF cut off", cf_int4_1_enum), 1483 SOC_ENUM("RX INT4_2 HPF cut off", cf_int4_2_enum), 1484 SOC_ENUM("RX INT5_1 HPF cut off", cf_int5_1_enum), 1485 SOC_ENUM("RX INT5_2 HPF cut off", cf_int5_2_enum), 1486 SOC_ENUM("RX INT6_1 HPF cut off", cf_int6_1_enum), 1487 SOC_ENUM("RX INT6_2 HPF cut off", cf_int6_2_enum), 1488 SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum), 1489 SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum), 1490 SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum), 1491 SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum), 1492 SOC_SINGLE_EXT("COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0, 1493 wcd9335_get_compander, wcd9335_set_compander), 1494 SOC_SINGLE_EXT("COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0, 1495 wcd9335_get_compander, wcd9335_set_compander), 1496 SOC_SINGLE_EXT("COMP3 Switch", SND_SOC_NOPM, COMPANDER_3, 1, 0, 1497 wcd9335_get_compander, wcd9335_set_compander), 1498 SOC_SINGLE_EXT("COMP4 Switch", SND_SOC_NOPM, COMPANDER_4, 1, 0, 1499 wcd9335_get_compander, wcd9335_set_compander), 1500 SOC_SINGLE_EXT("COMP5 Switch", SND_SOC_NOPM, COMPANDER_5, 1, 0, 1501 wcd9335_get_compander, wcd9335_set_compander), 1502 SOC_SINGLE_EXT("COMP6 Switch", SND_SOC_NOPM, COMPANDER_6, 1, 0, 1503 wcd9335_get_compander, wcd9335_set_compander), 1504 SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0, 1505 wcd9335_get_compander, wcd9335_set_compander), 1506 SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0, 1507 wcd9335_get_compander, wcd9335_set_compander), 1508 SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum, 1509 wcd9335_rx_hph_mode_get, wcd9335_rx_hph_mode_put), 1510 1511 /* Gain Controls */ 1512 SOC_SINGLE_TLV("EAR PA Volume", WCD9335_ANA_EAR, 4, 4, 1, 1513 ear_pa_gain), 1514 SOC_SINGLE_TLV("HPHL Volume", WCD9335_HPH_L_EN, 0, 20, 1, 1515 line_gain), 1516 SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1, 1517 line_gain), 1518 SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER, 1519 3, 16, 1, line_gain), 1520 SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER, 1521 3, 16, 1, line_gain), 1522 SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1, 1523 line_gain), 1524 SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1, 1525 line_gain), 1526 1527 SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0, 1528 analog_gain), 1529 SOC_SINGLE_TLV("ADC2 Volume", WCD9335_ANA_AMIC2, 0, 20, 0, 1530 analog_gain), 1531 SOC_SINGLE_TLV("ADC3 Volume", WCD9335_ANA_AMIC3, 0, 20, 0, 1532 analog_gain), 1533 SOC_SINGLE_TLV("ADC4 Volume", WCD9335_ANA_AMIC4, 0, 20, 0, 1534 analog_gain), 1535 SOC_SINGLE_TLV("ADC5 Volume", WCD9335_ANA_AMIC5, 0, 20, 0, 1536 analog_gain), 1537 SOC_SINGLE_TLV("ADC6 Volume", WCD9335_ANA_AMIC6, 0, 20, 0, 1538 analog_gain), 1539 1540 SOC_ENUM("TX0 HPF cut off", cf_dec0_enum), 1541 SOC_ENUM("TX1 HPF cut off", cf_dec1_enum), 1542 SOC_ENUM("TX2 HPF cut off", cf_dec2_enum), 1543 SOC_ENUM("TX3 HPF cut off", cf_dec3_enum), 1544 SOC_ENUM("TX4 HPF cut off", cf_dec4_enum), 1545 SOC_ENUM("TX5 HPF cut off", cf_dec5_enum), 1546 SOC_ENUM("TX6 HPF cut off", cf_dec6_enum), 1547 SOC_ENUM("TX7 HPF cut off", cf_dec7_enum), 1548 SOC_ENUM("TX8 HPF cut off", cf_dec8_enum), 1549 }; 1550 1551 static void wcd9335_codec_enable_int_port(struct wcd_slim_codec_dai_data *dai, 1552 struct snd_soc_component *component) 1553 { 1554 int port_num = 0; 1555 unsigned short reg = 0; 1556 unsigned int val = 0; 1557 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1558 struct wcd9335_slim_ch *ch; 1559 1560 list_for_each_entry(ch, &dai->slim_ch_list, list) { 1561 if (ch->port >= WCD9335_RX_START) { 1562 port_num = ch->port - WCD9335_RX_START; 1563 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + (port_num / 8); 1564 } else { 1565 port_num = ch->port; 1566 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8); 1567 } 1568 1569 regmap_read(wcd->if_regmap, reg, &val); 1570 if (!(val & BIT(port_num % 8))) 1571 regmap_write(wcd->if_regmap, reg, 1572 val | BIT(port_num % 8)); 1573 } 1574 } 1575 1576 static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w, 1577 struct snd_kcontrol *kc, 1578 int event) 1579 { 1580 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 1581 struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp); 1582 struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift]; 1583 int ret = 0; 1584 1585 switch (event) { 1586 case SND_SOC_DAPM_POST_PMU: 1587 wcd9335_codec_enable_int_port(dai, comp); 1588 break; 1589 case SND_SOC_DAPM_POST_PMD: 1590 kfree(dai->sconfig.chs); 1591 1592 break; 1593 } 1594 1595 return ret; 1596 } 1597 1598 static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w, 1599 struct snd_kcontrol *kc, int event) 1600 { 1601 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 1602 u16 gain_reg; 1603 int offset_val = 0; 1604 int val = 0; 1605 1606 switch (w->reg) { 1607 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: 1608 gain_reg = WCD9335_CDC_RX0_RX_VOL_MIX_CTL; 1609 break; 1610 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL: 1611 gain_reg = WCD9335_CDC_RX1_RX_VOL_MIX_CTL; 1612 break; 1613 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL: 1614 gain_reg = WCD9335_CDC_RX2_RX_VOL_MIX_CTL; 1615 break; 1616 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL: 1617 gain_reg = WCD9335_CDC_RX3_RX_VOL_MIX_CTL; 1618 break; 1619 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL: 1620 gain_reg = WCD9335_CDC_RX4_RX_VOL_MIX_CTL; 1621 break; 1622 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL: 1623 gain_reg = WCD9335_CDC_RX5_RX_VOL_MIX_CTL; 1624 break; 1625 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL: 1626 gain_reg = WCD9335_CDC_RX6_RX_VOL_MIX_CTL; 1627 break; 1628 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL: 1629 gain_reg = WCD9335_CDC_RX7_RX_VOL_MIX_CTL; 1630 break; 1631 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL: 1632 gain_reg = WCD9335_CDC_RX8_RX_VOL_MIX_CTL; 1633 break; 1634 default: 1635 dev_err(comp->dev, "%s: No gain register avail for %s\n", 1636 __func__, w->name); 1637 return 0; 1638 }; 1639 1640 switch (event) { 1641 case SND_SOC_DAPM_POST_PMU: 1642 val = snd_soc_component_read32(comp, gain_reg); 1643 val += offset_val; 1644 snd_soc_component_write(comp, gain_reg, val); 1645 break; 1646 case SND_SOC_DAPM_POST_PMD: 1647 break; 1648 }; 1649 1650 return 0; 1651 } 1652 1653 static u16 wcd9335_interp_get_primary_reg(u16 reg, u16 *ind) 1654 { 1655 u16 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL; 1656 1657 switch (reg) { 1658 case WCD9335_CDC_RX0_RX_PATH_CTL: 1659 case WCD9335_CDC_RX0_RX_PATH_MIX_CTL: 1660 prim_int_reg = WCD9335_CDC_RX0_RX_PATH_CTL; 1661 *ind = 0; 1662 break; 1663 case WCD9335_CDC_RX1_RX_PATH_CTL: 1664 case WCD9335_CDC_RX1_RX_PATH_MIX_CTL: 1665 prim_int_reg = WCD9335_CDC_RX1_RX_PATH_CTL; 1666 *ind = 1; 1667 break; 1668 case WCD9335_CDC_RX2_RX_PATH_CTL: 1669 case WCD9335_CDC_RX2_RX_PATH_MIX_CTL: 1670 prim_int_reg = WCD9335_CDC_RX2_RX_PATH_CTL; 1671 *ind = 2; 1672 break; 1673 case WCD9335_CDC_RX3_RX_PATH_CTL: 1674 case WCD9335_CDC_RX3_RX_PATH_MIX_CTL: 1675 prim_int_reg = WCD9335_CDC_RX3_RX_PATH_CTL; 1676 *ind = 3; 1677 break; 1678 case WCD9335_CDC_RX4_RX_PATH_CTL: 1679 case WCD9335_CDC_RX4_RX_PATH_MIX_CTL: 1680 prim_int_reg = WCD9335_CDC_RX4_RX_PATH_CTL; 1681 *ind = 4; 1682 break; 1683 case WCD9335_CDC_RX5_RX_PATH_CTL: 1684 case WCD9335_CDC_RX5_RX_PATH_MIX_CTL: 1685 prim_int_reg = WCD9335_CDC_RX5_RX_PATH_CTL; 1686 *ind = 5; 1687 break; 1688 case WCD9335_CDC_RX6_RX_PATH_CTL: 1689 case WCD9335_CDC_RX6_RX_PATH_MIX_CTL: 1690 prim_int_reg = WCD9335_CDC_RX6_RX_PATH_CTL; 1691 *ind = 6; 1692 break; 1693 case WCD9335_CDC_RX7_RX_PATH_CTL: 1694 case WCD9335_CDC_RX7_RX_PATH_MIX_CTL: 1695 prim_int_reg = WCD9335_CDC_RX7_RX_PATH_CTL; 1696 *ind = 7; 1697 break; 1698 case WCD9335_CDC_RX8_RX_PATH_CTL: 1699 case WCD9335_CDC_RX8_RX_PATH_MIX_CTL: 1700 prim_int_reg = WCD9335_CDC_RX8_RX_PATH_CTL; 1701 *ind = 8; 1702 break; 1703 }; 1704 1705 return prim_int_reg; 1706 } 1707 1708 static void wcd9335_codec_hd2_control(struct snd_soc_component *component, 1709 u16 prim_int_reg, int event) 1710 { 1711 u16 hd2_scale_reg; 1712 u16 hd2_enable_reg = 0; 1713 1714 if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) { 1715 hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3; 1716 hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0; 1717 } 1718 if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) { 1719 hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3; 1720 hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0; 1721 } 1722 1723 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) { 1724 snd_soc_component_update_bits(component, hd2_scale_reg, 1725 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK, 1726 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P2500); 1727 snd_soc_component_update_bits(component, hd2_scale_reg, 1728 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK, 1729 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_2); 1730 snd_soc_component_update_bits(component, hd2_enable_reg, 1731 WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK, 1732 WCD9335_CDC_RX_PATH_CFG_HD2_ENABLE); 1733 } 1734 1735 if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) { 1736 snd_soc_component_update_bits(component, hd2_enable_reg, 1737 WCD9335_CDC_RX_PATH_CFG_HD2_EN_MASK, 1738 WCD9335_CDC_RX_PATH_CFG_HD2_DISABLE); 1739 snd_soc_component_update_bits(component, hd2_scale_reg, 1740 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_MASK, 1741 WCD9335_CDC_RX_PATH_SEC_HD2_SCALE_1); 1742 snd_soc_component_update_bits(component, hd2_scale_reg, 1743 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_MASK, 1744 WCD9335_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000); 1745 } 1746 } 1747 1748 static int wcd9335_codec_enable_prim_interpolator( 1749 struct snd_soc_component *comp, 1750 u16 reg, int event) 1751 { 1752 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 1753 u16 ind = 0; 1754 int prim_int_reg = wcd9335_interp_get_primary_reg(reg, &ind); 1755 1756 switch (event) { 1757 case SND_SOC_DAPM_PRE_PMU: 1758 wcd->prim_int_users[ind]++; 1759 if (wcd->prim_int_users[ind] == 1) { 1760 snd_soc_component_update_bits(comp, prim_int_reg, 1761 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 1762 WCD9335_CDC_RX_PGA_MUTE_ENABLE); 1763 wcd9335_codec_hd2_control(comp, prim_int_reg, event); 1764 snd_soc_component_update_bits(comp, prim_int_reg, 1765 WCD9335_CDC_RX_CLK_EN_MASK, 1766 WCD9335_CDC_RX_CLK_ENABLE); 1767 } 1768 1769 if ((reg != prim_int_reg) && 1770 ((snd_soc_component_read32(comp, prim_int_reg)) & 1771 WCD9335_CDC_RX_PGA_MUTE_EN_MASK)) 1772 snd_soc_component_update_bits(comp, reg, 1773 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 1774 WCD9335_CDC_RX_PGA_MUTE_ENABLE); 1775 break; 1776 case SND_SOC_DAPM_POST_PMD: 1777 wcd->prim_int_users[ind]--; 1778 if (wcd->prim_int_users[ind] == 0) { 1779 snd_soc_component_update_bits(comp, prim_int_reg, 1780 WCD9335_CDC_RX_CLK_EN_MASK, 1781 WCD9335_CDC_RX_CLK_DISABLE); 1782 snd_soc_component_update_bits(comp, prim_int_reg, 1783 WCD9335_CDC_RX_RESET_MASK, 1784 WCD9335_CDC_RX_RESET_ENABLE); 1785 snd_soc_component_update_bits(comp, prim_int_reg, 1786 WCD9335_CDC_RX_RESET_MASK, 1787 WCD9335_CDC_RX_RESET_DISABLE); 1788 wcd9335_codec_hd2_control(comp, prim_int_reg, event); 1789 } 1790 break; 1791 }; 1792 1793 return 0; 1794 } 1795 1796 static int wcd9335_config_compander(struct snd_soc_component *component, 1797 int interp_n, int event) 1798 { 1799 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1800 int comp; 1801 u16 comp_ctl0_reg, rx_path_cfg0_reg; 1802 1803 /* EAR does not have compander */ 1804 if (!interp_n) 1805 return 0; 1806 1807 comp = interp_n - 1; 1808 if (!wcd->comp_enabled[comp]) 1809 return 0; 1810 1811 comp_ctl0_reg = WCD9335_CDC_COMPANDER1_CTL(comp); 1812 rx_path_cfg0_reg = WCD9335_CDC_RX1_RX_PATH_CFG(comp); 1813 1814 if (SND_SOC_DAPM_EVENT_ON(event)) { 1815 /* Enable Compander Clock */ 1816 snd_soc_component_update_bits(component, comp_ctl0_reg, 1817 WCD9335_CDC_COMPANDER_CLK_EN_MASK, 1818 WCD9335_CDC_COMPANDER_CLK_ENABLE); 1819 /* Reset comander */ 1820 snd_soc_component_update_bits(component, comp_ctl0_reg, 1821 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 1822 WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE); 1823 snd_soc_component_update_bits(component, comp_ctl0_reg, 1824 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 1825 WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE); 1826 /* Enables DRE in this path */ 1827 snd_soc_component_update_bits(component, rx_path_cfg0_reg, 1828 WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK, 1829 WCD9335_CDC_RX_PATH_CFG_CMP_ENABLE); 1830 } 1831 1832 if (SND_SOC_DAPM_EVENT_OFF(event)) { 1833 snd_soc_component_update_bits(component, comp_ctl0_reg, 1834 WCD9335_CDC_COMPANDER_HALT_MASK, 1835 WCD9335_CDC_COMPANDER_HALT); 1836 snd_soc_component_update_bits(component, rx_path_cfg0_reg, 1837 WCD9335_CDC_RX_PATH_CFG_CMP_EN_MASK, 1838 WCD9335_CDC_RX_PATH_CFG_CMP_DISABLE); 1839 1840 snd_soc_component_update_bits(component, comp_ctl0_reg, 1841 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 1842 WCD9335_CDC_COMPANDER_SOFT_RST_ENABLE); 1843 snd_soc_component_update_bits(component, comp_ctl0_reg, 1844 WCD9335_CDC_COMPANDER_SOFT_RST_MASK, 1845 WCD9335_CDC_COMPANDER_SOFT_RST_DISABLE); 1846 snd_soc_component_update_bits(component, comp_ctl0_reg, 1847 WCD9335_CDC_COMPANDER_CLK_EN_MASK, 1848 WCD9335_CDC_COMPANDER_CLK_DISABLE); 1849 snd_soc_component_update_bits(component, comp_ctl0_reg, 1850 WCD9335_CDC_COMPANDER_HALT_MASK, 1851 WCD9335_CDC_COMPANDER_NOHALT); 1852 } 1853 1854 return 0; 1855 } 1856 1857 static int wcd9335_codec_enable_interpolator(struct snd_soc_dapm_widget *w, 1858 struct snd_kcontrol *kc, int event) 1859 { 1860 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 1861 u16 gain_reg; 1862 u16 reg; 1863 int val; 1864 int offset_val = 0; 1865 1866 if (!(strcmp(w->name, "RX INT0 INTERP"))) { 1867 reg = WCD9335_CDC_RX0_RX_PATH_CTL; 1868 gain_reg = WCD9335_CDC_RX0_RX_VOL_CTL; 1869 } else if (!(strcmp(w->name, "RX INT1 INTERP"))) { 1870 reg = WCD9335_CDC_RX1_RX_PATH_CTL; 1871 gain_reg = WCD9335_CDC_RX1_RX_VOL_CTL; 1872 } else if (!(strcmp(w->name, "RX INT2 INTERP"))) { 1873 reg = WCD9335_CDC_RX2_RX_PATH_CTL; 1874 gain_reg = WCD9335_CDC_RX2_RX_VOL_CTL; 1875 } else if (!(strcmp(w->name, "RX INT3 INTERP"))) { 1876 reg = WCD9335_CDC_RX3_RX_PATH_CTL; 1877 gain_reg = WCD9335_CDC_RX3_RX_VOL_CTL; 1878 } else if (!(strcmp(w->name, "RX INT4 INTERP"))) { 1879 reg = WCD9335_CDC_RX4_RX_PATH_CTL; 1880 gain_reg = WCD9335_CDC_RX4_RX_VOL_CTL; 1881 } else if (!(strcmp(w->name, "RX INT5 INTERP"))) { 1882 reg = WCD9335_CDC_RX5_RX_PATH_CTL; 1883 gain_reg = WCD9335_CDC_RX5_RX_VOL_CTL; 1884 } else if (!(strcmp(w->name, "RX INT6 INTERP"))) { 1885 reg = WCD9335_CDC_RX6_RX_PATH_CTL; 1886 gain_reg = WCD9335_CDC_RX6_RX_VOL_CTL; 1887 } else if (!(strcmp(w->name, "RX INT7 INTERP"))) { 1888 reg = WCD9335_CDC_RX7_RX_PATH_CTL; 1889 gain_reg = WCD9335_CDC_RX7_RX_VOL_CTL; 1890 } else if (!(strcmp(w->name, "RX INT8 INTERP"))) { 1891 reg = WCD9335_CDC_RX8_RX_PATH_CTL; 1892 gain_reg = WCD9335_CDC_RX8_RX_VOL_CTL; 1893 } else { 1894 dev_err(comp->dev, "%s: Interpolator reg not found\n", 1895 __func__); 1896 return -EINVAL; 1897 } 1898 1899 switch (event) { 1900 case SND_SOC_DAPM_PRE_PMU: 1901 /* Reset if needed */ 1902 wcd9335_codec_enable_prim_interpolator(comp, reg, event); 1903 break; 1904 case SND_SOC_DAPM_POST_PMU: 1905 wcd9335_config_compander(comp, w->shift, event); 1906 val = snd_soc_component_read32(comp, gain_reg); 1907 val += offset_val; 1908 snd_soc_component_write(comp, gain_reg, val); 1909 break; 1910 case SND_SOC_DAPM_POST_PMD: 1911 wcd9335_config_compander(comp, w->shift, event); 1912 wcd9335_codec_enable_prim_interpolator(comp, reg, event); 1913 break; 1914 }; 1915 1916 return 0; 1917 } 1918 1919 static void wcd9335_codec_hph_mode_gain_opt(struct snd_soc_component *component, 1920 u8 gain) 1921 { 1922 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 1923 u8 hph_l_en, hph_r_en; 1924 u8 l_val, r_val; 1925 u8 hph_pa_status; 1926 bool is_hphl_pa, is_hphr_pa; 1927 1928 hph_pa_status = snd_soc_component_read32(component, WCD9335_ANA_HPH); 1929 is_hphl_pa = hph_pa_status >> 7; 1930 is_hphr_pa = (hph_pa_status & 0x40) >> 6; 1931 1932 hph_l_en = snd_soc_component_read32(component, WCD9335_HPH_L_EN); 1933 hph_r_en = snd_soc_component_read32(component, WCD9335_HPH_R_EN); 1934 1935 l_val = (hph_l_en & 0xC0) | 0x20 | gain; 1936 r_val = (hph_r_en & 0xC0) | 0x20 | gain; 1937 1938 /* 1939 * Set HPH_L & HPH_R gain source selection to REGISTER 1940 * for better click and pop only if corresponding PAs are 1941 * not enabled. Also cache the values of the HPHL/R 1942 * PA gains to be applied after PAs are enabled 1943 */ 1944 if ((l_val != hph_l_en) && !is_hphl_pa) { 1945 snd_soc_component_write(component, WCD9335_HPH_L_EN, l_val); 1946 wcd->hph_l_gain = hph_l_en & 0x1F; 1947 } 1948 1949 if ((r_val != hph_r_en) && !is_hphr_pa) { 1950 snd_soc_component_write(component, WCD9335_HPH_R_EN, r_val); 1951 wcd->hph_r_gain = hph_r_en & 0x1F; 1952 } 1953 } 1954 1955 static void wcd9335_codec_hph_lohifi_config(struct snd_soc_component *comp, 1956 int event) 1957 { 1958 if (SND_SOC_DAPM_EVENT_ON(event)) { 1959 snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA, 1960 WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK, 1961 0x06); 1962 snd_soc_component_update_bits(comp, 1963 WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 1964 0xF0, 0x40); 1965 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 1966 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 1967 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000); 1968 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 1969 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 1970 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE); 1971 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1, 1972 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 1973 0x0C); 1974 wcd9335_codec_hph_mode_gain_opt(comp, 0x11); 1975 } 1976 1977 if (SND_SOC_DAPM_EVENT_OFF(event)) { 1978 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 1979 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 1980 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE); 1981 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 1982 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 1983 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500); 1984 snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 1985 0x8A); 1986 snd_soc_component_update_bits(comp, WCD9335_RX_BIAS_HPH_PA, 1987 WCD9335_RX_BIAS_HPH_PA_AMP_5_UA_MASK, 1988 0x0A); 1989 } 1990 } 1991 1992 static void wcd9335_codec_hph_lp_config(struct snd_soc_component *comp, 1993 int event) 1994 { 1995 if (SND_SOC_DAPM_EVENT_ON(event)) { 1996 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1, 1997 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 1998 0x0C); 1999 wcd9335_codec_hph_mode_gain_opt(comp, 0x10); 2000 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 2001 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 2002 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000); 2003 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2004 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 2005 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE); 2006 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2007 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK, 2008 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_ENABLE); 2009 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2010 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK, 2011 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENABLE); 2012 snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL, 2013 WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_MASK, 2014 WCD9335_HPH_RDAC_N1P65_LD_OUTCTL_V_N1P60); 2015 snd_soc_component_update_bits(comp, WCD9335_HPH_RDAC_LDO_CTL, 2016 WCD9335_HPH_RDAC_1P65_LD_OUTCTL_MASK, 2017 WCD9335_HPH_RDAC_1P65_LD_OUTCTL_V_N1P60); 2018 snd_soc_component_update_bits(comp, 2019 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x0F, 0x01); 2020 snd_soc_component_update_bits(comp, 2021 WCD9335_RX_BIAS_HPH_RDAC_LDO, 0xF0, 0x10); 2022 } 2023 2024 if (SND_SOC_DAPM_EVENT_OFF(event)) { 2025 snd_soc_component_write(comp, WCD9335_RX_BIAS_HPH_RDAC_LDO, 2026 0x88); 2027 snd_soc_component_write(comp, WCD9335_HPH_RDAC_LDO_CTL, 2028 0x33); 2029 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2030 WCD9335_HPH_PA_CTL2_HPH_PSRR_ENH_MASK, 2031 WCD9335_HPH_PA_CTL2_HPH_PSRR_DISABLE); 2032 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2033 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_MASK, 2034 WCD9335_HPH_PA_CTL2_FORCE_PSRREH_DISABLE); 2035 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2036 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 2037 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE); 2038 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 2039 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 2040 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500); 2041 snd_soc_component_update_bits(comp, WCD9335_HPH_R_EN, 2042 WCD9335_HPH_CONST_SEL_L_MASK, 2043 WCD9335_HPH_CONST_SEL_L_HQ_PATH); 2044 snd_soc_component_update_bits(comp, WCD9335_HPH_L_EN, 2045 WCD9335_HPH_CONST_SEL_L_MASK, 2046 WCD9335_HPH_CONST_SEL_L_HQ_PATH); 2047 } 2048 } 2049 2050 static void wcd9335_codec_hph_hifi_config(struct snd_soc_component *comp, 2051 int event) 2052 { 2053 if (SND_SOC_DAPM_EVENT_ON(event)) { 2054 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 2055 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 2056 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_1000); 2057 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2058 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 2059 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_ENABLE); 2060 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL1, 2061 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 2062 0x0C); 2063 wcd9335_codec_hph_mode_gain_opt(comp, 0x11); 2064 } 2065 2066 if (SND_SOC_DAPM_EVENT_OFF(event)) { 2067 snd_soc_component_update_bits(comp, WCD9335_HPH_PA_CTL2, 2068 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_MASK, 2069 WCD9335_HPH_PA_CTL2_FORCE_IQCTRL_DISABLE); 2070 snd_soc_component_update_bits(comp, WCD9335_HPH_CNP_WG_CTL, 2071 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_MASK, 2072 WCD9335_HPH_CNP_WG_CTL_CURR_LDIV_RATIO_500); 2073 } 2074 } 2075 2076 static void wcd9335_codec_hph_mode_config(struct snd_soc_component *component, 2077 int event, int mode) 2078 { 2079 switch (mode) { 2080 case CLS_H_LP: 2081 wcd9335_codec_hph_lp_config(component, event); 2082 break; 2083 case CLS_H_LOHIFI: 2084 wcd9335_codec_hph_lohifi_config(component, event); 2085 break; 2086 case CLS_H_HIFI: 2087 wcd9335_codec_hph_hifi_config(component, event); 2088 break; 2089 } 2090 } 2091 2092 static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, 2093 struct snd_kcontrol *kc, 2094 int event) 2095 { 2096 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2097 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2098 int hph_mode = wcd->hph_mode; 2099 u8 dem_inp; 2100 int ret = 0; 2101 2102 switch (event) { 2103 case SND_SOC_DAPM_PRE_PMU: 2104 /* Read DEM INP Select */ 2105 dem_inp = snd_soc_component_read32(comp, 2106 WCD9335_CDC_RX1_RX_PATH_SEC0) & 0x03; 2107 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || 2108 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { 2109 dev_err(comp->dev, "Incorrect DEM Input\n"); 2110 return -EINVAL; 2111 } 2112 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, 2113 WCD_CLSH_STATE_HPHL, 2114 ((hph_mode == CLS_H_LOHIFI) ? 2115 CLS_H_HIFI : hph_mode)); 2116 2117 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 2118 2119 break; 2120 case SND_SOC_DAPM_POST_PMU: 2121 usleep_range(1000, 1100); 2122 break; 2123 case SND_SOC_DAPM_PRE_PMD: 2124 break; 2125 case SND_SOC_DAPM_POST_PMD: 2126 /* 1000us required as per HW requirement */ 2127 usleep_range(1000, 1100); 2128 2129 if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) & 2130 WCD_CLSH_STATE_HPHR)) 2131 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 2132 2133 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 2134 WCD_CLSH_STATE_HPHL, 2135 ((hph_mode == CLS_H_LOHIFI) ? 2136 CLS_H_HIFI : hph_mode)); 2137 break; 2138 }; 2139 2140 return ret; 2141 } 2142 2143 static int wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget *w, 2144 struct snd_kcontrol *kc, int event) 2145 { 2146 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2147 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2148 2149 switch (event) { 2150 case SND_SOC_DAPM_PRE_PMU: 2151 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, 2152 WCD_CLSH_STATE_LO, CLS_AB); 2153 break; 2154 case SND_SOC_DAPM_POST_PMD: 2155 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 2156 WCD_CLSH_STATE_LO, CLS_AB); 2157 break; 2158 } 2159 2160 return 0; 2161 } 2162 2163 static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w, 2164 struct snd_kcontrol *kc, int event) 2165 { 2166 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2167 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2168 int ret = 0; 2169 2170 switch (event) { 2171 case SND_SOC_DAPM_PRE_PMU: 2172 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_PRE_DAC, 2173 WCD_CLSH_STATE_EAR, CLS_H_NORMAL); 2174 2175 break; 2176 case SND_SOC_DAPM_POST_PMD: 2177 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 2178 WCD_CLSH_STATE_EAR, CLS_H_NORMAL); 2179 break; 2180 }; 2181 2182 return ret; 2183 } 2184 2185 static void wcd9335_codec_hph_post_pa_config(struct wcd9335_codec *wcd, 2186 int mode, int event) 2187 { 2188 u8 scale_val = 0; 2189 2190 switch (event) { 2191 case SND_SOC_DAPM_POST_PMU: 2192 switch (mode) { 2193 case CLS_H_HIFI: 2194 scale_val = 0x3; 2195 break; 2196 case CLS_H_LOHIFI: 2197 scale_val = 0x1; 2198 break; 2199 } 2200 break; 2201 case SND_SOC_DAPM_PRE_PMD: 2202 scale_val = 0x6; 2203 break; 2204 } 2205 2206 if (scale_val) 2207 snd_soc_component_update_bits(wcd->component, 2208 WCD9335_HPH_PA_CTL1, 2209 WCD9335_HPH_PA_GM3_IB_SCALE_MASK, 2210 scale_val << 1); 2211 if (SND_SOC_DAPM_EVENT_ON(event)) { 2212 if (wcd->comp_enabled[COMPANDER_1] || 2213 wcd->comp_enabled[COMPANDER_2]) { 2214 /* GAIN Source Selection */ 2215 snd_soc_component_update_bits(wcd->component, 2216 WCD9335_HPH_L_EN, 2217 WCD9335_HPH_GAIN_SRC_SEL_MASK, 2218 WCD9335_HPH_GAIN_SRC_SEL_COMPANDER); 2219 snd_soc_component_update_bits(wcd->component, 2220 WCD9335_HPH_R_EN, 2221 WCD9335_HPH_GAIN_SRC_SEL_MASK, 2222 WCD9335_HPH_GAIN_SRC_SEL_COMPANDER); 2223 snd_soc_component_update_bits(wcd->component, 2224 WCD9335_HPH_AUTO_CHOP, 2225 WCD9335_HPH_AUTO_CHOP_MASK, 2226 WCD9335_HPH_AUTO_CHOP_FORCE_ENABLE); 2227 } 2228 snd_soc_component_update_bits(wcd->component, 2229 WCD9335_HPH_L_EN, 2230 WCD9335_HPH_PA_GAIN_MASK, 2231 wcd->hph_l_gain); 2232 snd_soc_component_update_bits(wcd->component, 2233 WCD9335_HPH_R_EN, 2234 WCD9335_HPH_PA_GAIN_MASK, 2235 wcd->hph_r_gain); 2236 } 2237 2238 if (SND_SOC_DAPM_EVENT_OFF(event)) 2239 snd_soc_component_update_bits(wcd->component, 2240 WCD9335_HPH_AUTO_CHOP, 2241 WCD9335_HPH_AUTO_CHOP_MASK, 2242 WCD9335_HPH_AUTO_CHOP_ENABLE_BY_CMPDR_GAIN); 2243 } 2244 2245 static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w, 2246 struct snd_kcontrol *kc, 2247 int event) 2248 { 2249 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2250 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2251 int hph_mode = wcd->hph_mode; 2252 u8 dem_inp; 2253 int ret = 0; 2254 2255 switch (event) { 2256 case SND_SOC_DAPM_PRE_PMU: 2257 2258 /* Read DEM INP Select */ 2259 dem_inp = snd_soc_component_read32(comp, 2260 WCD9335_CDC_RX2_RX_PATH_SEC0) & 2261 WCD9335_CDC_RX_PATH_DEM_INP_SEL_MASK; 2262 if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) || 2263 (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) { 2264 dev_err(comp->dev, "DEM Input not set correctly, hph_mode: %d\n", 2265 hph_mode); 2266 return -EINVAL; 2267 } 2268 2269 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, 2270 WCD_CLSH_EVENT_PRE_DAC, 2271 WCD_CLSH_STATE_HPHR, 2272 ((hph_mode == CLS_H_LOHIFI) ? 2273 CLS_H_HIFI : hph_mode)); 2274 2275 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 2276 2277 break; 2278 case SND_SOC_DAPM_POST_PMD: 2279 /* 1000us required as per HW requirement */ 2280 usleep_range(1000, 1100); 2281 2282 if (!(wcd_clsh_ctrl_get_state(wcd->clsh_ctrl) & 2283 WCD_CLSH_STATE_HPHL)) 2284 wcd9335_codec_hph_mode_config(comp, event, hph_mode); 2285 2286 wcd_clsh_ctrl_set_state(wcd->clsh_ctrl, WCD_CLSH_EVENT_POST_PA, 2287 WCD_CLSH_STATE_HPHR, ((hph_mode == CLS_H_LOHIFI) ? 2288 CLS_H_HIFI : hph_mode)); 2289 break; 2290 }; 2291 2292 return ret; 2293 } 2294 2295 static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w, 2296 struct snd_kcontrol *kc, 2297 int event) 2298 { 2299 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2300 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2301 int hph_mode = wcd->hph_mode; 2302 int ret = 0; 2303 2304 switch (event) { 2305 case SND_SOC_DAPM_PRE_PMU: 2306 break; 2307 case SND_SOC_DAPM_POST_PMU: 2308 /* 2309 * 7ms sleep is required after PA is enabled as per 2310 * HW requirement 2311 */ 2312 usleep_range(7000, 7100); 2313 2314 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 2315 snd_soc_component_update_bits(comp, 2316 WCD9335_CDC_RX1_RX_PATH_CTL, 2317 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2318 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2319 2320 /* Remove mix path mute if it is enabled */ 2321 if ((snd_soc_component_read32(comp, 2322 WCD9335_CDC_RX1_RX_PATH_MIX_CTL)) & 2323 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 2324 snd_soc_component_update_bits(comp, 2325 WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 2326 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2327 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2328 2329 break; 2330 case SND_SOC_DAPM_PRE_PMD: 2331 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 2332 break; 2333 case SND_SOC_DAPM_POST_PMD: 2334 /* 5ms sleep is required after PA is disabled as per 2335 * HW requirement 2336 */ 2337 usleep_range(5000, 5500); 2338 break; 2339 }; 2340 2341 return ret; 2342 } 2343 2344 static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w, 2345 struct snd_kcontrol *kc, 2346 int event) 2347 { 2348 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2349 int vol_reg = 0, mix_vol_reg = 0; 2350 int ret = 0; 2351 2352 if (w->reg == WCD9335_ANA_LO_1_2) { 2353 if (w->shift == 7) { 2354 vol_reg = WCD9335_CDC_RX3_RX_PATH_CTL; 2355 mix_vol_reg = WCD9335_CDC_RX3_RX_PATH_MIX_CTL; 2356 } else if (w->shift == 6) { 2357 vol_reg = WCD9335_CDC_RX4_RX_PATH_CTL; 2358 mix_vol_reg = WCD9335_CDC_RX4_RX_PATH_MIX_CTL; 2359 } 2360 } else if (w->reg == WCD9335_ANA_LO_3_4) { 2361 if (w->shift == 7) { 2362 vol_reg = WCD9335_CDC_RX5_RX_PATH_CTL; 2363 mix_vol_reg = WCD9335_CDC_RX5_RX_PATH_MIX_CTL; 2364 } else if (w->shift == 6) { 2365 vol_reg = WCD9335_CDC_RX6_RX_PATH_CTL; 2366 mix_vol_reg = WCD9335_CDC_RX6_RX_PATH_MIX_CTL; 2367 } 2368 } else { 2369 dev_err(comp->dev, "Error enabling lineout PA\n"); 2370 return -EINVAL; 2371 } 2372 2373 switch (event) { 2374 case SND_SOC_DAPM_POST_PMU: 2375 /* 5ms sleep is required after PA is enabled as per 2376 * HW requirement 2377 */ 2378 usleep_range(5000, 5500); 2379 snd_soc_component_update_bits(comp, vol_reg, 2380 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2381 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2382 2383 /* Remove mix path mute if it is enabled */ 2384 if ((snd_soc_component_read32(comp, mix_vol_reg)) & 2385 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 2386 snd_soc_component_update_bits(comp, mix_vol_reg, 2387 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2388 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2389 break; 2390 case SND_SOC_DAPM_POST_PMD: 2391 /* 5ms sleep is required after PA is disabled as per 2392 * HW requirement 2393 */ 2394 usleep_range(5000, 5500); 2395 break; 2396 }; 2397 2398 return ret; 2399 } 2400 2401 static void wcd9335_codec_init_flyback(struct snd_soc_component *component) 2402 { 2403 snd_soc_component_update_bits(component, WCD9335_HPH_L_EN, 2404 WCD9335_HPH_CONST_SEL_L_MASK, 2405 WCD9335_HPH_CONST_SEL_L_BYPASS); 2406 snd_soc_component_update_bits(component, WCD9335_HPH_R_EN, 2407 WCD9335_HPH_CONST_SEL_L_MASK, 2408 WCD9335_HPH_CONST_SEL_L_BYPASS); 2409 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF, 2410 WCD9335_RX_BIAS_FLYB_VPOS_5_UA_MASK, 2411 WCD9335_RX_BIAS_FLYB_I_0P0_UA); 2412 snd_soc_component_update_bits(component, WCD9335_RX_BIAS_FLYB_BUFF, 2413 WCD9335_RX_BIAS_FLYB_VNEG_5_UA_MASK, 2414 WCD9335_RX_BIAS_FLYB_I_0P0_UA); 2415 } 2416 2417 static int wcd9335_codec_enable_rx_bias(struct snd_soc_dapm_widget *w, 2418 struct snd_kcontrol *kc, int event) 2419 { 2420 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2421 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2422 2423 switch (event) { 2424 case SND_SOC_DAPM_PRE_PMU: 2425 wcd->rx_bias_count++; 2426 if (wcd->rx_bias_count == 1) { 2427 wcd9335_codec_init_flyback(comp); 2428 snd_soc_component_update_bits(comp, 2429 WCD9335_ANA_RX_SUPPLIES, 2430 WCD9335_ANA_RX_BIAS_ENABLE_MASK, 2431 WCD9335_ANA_RX_BIAS_ENABLE); 2432 } 2433 break; 2434 case SND_SOC_DAPM_POST_PMD: 2435 wcd->rx_bias_count--; 2436 if (!wcd->rx_bias_count) 2437 snd_soc_component_update_bits(comp, 2438 WCD9335_ANA_RX_SUPPLIES, 2439 WCD9335_ANA_RX_BIAS_ENABLE_MASK, 2440 WCD9335_ANA_RX_BIAS_DISABLE); 2441 break; 2442 }; 2443 2444 return 0; 2445 } 2446 2447 static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w, 2448 struct snd_kcontrol *kc, int event) 2449 { 2450 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2451 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 2452 int hph_mode = wcd->hph_mode; 2453 int ret = 0; 2454 2455 switch (event) { 2456 case SND_SOC_DAPM_PRE_PMU: 2457 break; 2458 case SND_SOC_DAPM_POST_PMU: 2459 /* 2460 * 7ms sleep is required after PA is enabled as per 2461 * HW requirement 2462 */ 2463 usleep_range(7000, 7100); 2464 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 2465 snd_soc_component_update_bits(comp, 2466 WCD9335_CDC_RX2_RX_PATH_CTL, 2467 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2468 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2469 /* Remove mix path mute if it is enabled */ 2470 if ((snd_soc_component_read32(comp, 2471 WCD9335_CDC_RX2_RX_PATH_MIX_CTL)) & 2472 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 2473 snd_soc_component_update_bits(comp, 2474 WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 2475 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2476 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2477 2478 break; 2479 2480 case SND_SOC_DAPM_PRE_PMD: 2481 wcd9335_codec_hph_post_pa_config(wcd, hph_mode, event); 2482 break; 2483 case SND_SOC_DAPM_POST_PMD: 2484 /* 5ms sleep is required after PA is disabled as per 2485 * HW requirement 2486 */ 2487 usleep_range(5000, 5500); 2488 break; 2489 }; 2490 2491 return ret; 2492 } 2493 2494 static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w, 2495 struct snd_kcontrol *kc, int event) 2496 { 2497 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2498 int ret = 0; 2499 2500 switch (event) { 2501 case SND_SOC_DAPM_POST_PMU: 2502 /* 5ms sleep is required after PA is enabled as per 2503 * HW requirement 2504 */ 2505 usleep_range(5000, 5500); 2506 snd_soc_component_update_bits(comp, 2507 WCD9335_CDC_RX0_RX_PATH_CTL, 2508 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2509 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2510 /* Remove mix path mute if it is enabled */ 2511 if ((snd_soc_component_read32(comp, 2512 WCD9335_CDC_RX0_RX_PATH_MIX_CTL)) & 2513 WCD9335_CDC_RX_PGA_MUTE_EN_MASK) 2514 snd_soc_component_update_bits(comp, 2515 WCD9335_CDC_RX0_RX_PATH_MIX_CTL, 2516 WCD9335_CDC_RX_PGA_MUTE_EN_MASK, 2517 WCD9335_CDC_RX_PGA_MUTE_DISABLE); 2518 break; 2519 case SND_SOC_DAPM_POST_PMD: 2520 /* 5ms sleep is required after PA is disabled as per 2521 * HW requirement 2522 */ 2523 usleep_range(5000, 5500); 2524 2525 break; 2526 }; 2527 2528 return ret; 2529 } 2530 2531 static irqreturn_t wcd9335_slimbus_irq(int irq, void *data) 2532 { 2533 struct wcd9335_codec *wcd = data; 2534 unsigned long status = 0; 2535 int i, j, port_id; 2536 unsigned int val, int_val = 0; 2537 irqreturn_t ret = IRQ_NONE; 2538 bool tx; 2539 unsigned short reg = 0; 2540 2541 for (i = WCD9335_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0; 2542 i <= WCD9335_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) { 2543 regmap_read(wcd->if_regmap, i, &val); 2544 status |= ((u32)val << (8 * j)); 2545 } 2546 2547 for_each_set_bit(j, &status, 32) { 2548 tx = (j >= 16 ? true : false); 2549 port_id = (tx ? j - 16 : j); 2550 regmap_read(wcd->if_regmap, 2551 WCD9335_SLIM_PGD_PORT_INT_RX_SOURCE0 + j, &val); 2552 if (val) { 2553 if (!tx) 2554 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + 2555 (port_id / 8); 2556 else 2557 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + 2558 (port_id / 8); 2559 regmap_read( 2560 wcd->if_regmap, reg, &int_val); 2561 /* 2562 * Ignore interrupts for ports for which the 2563 * interrupts are not specifically enabled. 2564 */ 2565 if (!(int_val & (1 << (port_id % 8)))) 2566 continue; 2567 } 2568 2569 if (val & WCD9335_SLIM_IRQ_OVERFLOW) 2570 dev_err_ratelimited(wcd->dev, 2571 "%s: overflow error on %s port %d, value %x\n", 2572 __func__, (tx ? "TX" : "RX"), port_id, val); 2573 2574 if (val & WCD9335_SLIM_IRQ_UNDERFLOW) 2575 dev_err_ratelimited(wcd->dev, 2576 "%s: underflow error on %s port %d, value %x\n", 2577 __func__, (tx ? "TX" : "RX"), port_id, val); 2578 2579 if ((val & WCD9335_SLIM_IRQ_OVERFLOW) || 2580 (val & WCD9335_SLIM_IRQ_UNDERFLOW)) { 2581 if (!tx) 2582 reg = WCD9335_SLIM_PGD_PORT_INT_EN0 + 2583 (port_id / 8); 2584 else 2585 reg = WCD9335_SLIM_PGD_PORT_INT_TX_EN0 + 2586 (port_id / 8); 2587 regmap_read( 2588 wcd->if_regmap, reg, &int_val); 2589 if (int_val & (1 << (port_id % 8))) { 2590 int_val = int_val ^ (1 << (port_id % 8)); 2591 regmap_write(wcd->if_regmap, 2592 reg, int_val); 2593 } 2594 } 2595 2596 regmap_write(wcd->if_regmap, 2597 WCD9335_SLIM_PGD_PORT_INT_CLR_RX_0 + (j / 8), 2598 BIT(j % 8)); 2599 ret = IRQ_HANDLED; 2600 } 2601 2602 return ret; 2603 } 2604 2605 static struct wcd9335_irq wcd9335_irqs[] = { 2606 { 2607 .irq = WCD9335_IRQ_SLIMBUS, 2608 .handler = wcd9335_slimbus_irq, 2609 .name = "SLIM Slave", 2610 }, 2611 }; 2612 2613 static int wcd9335_setup_irqs(struct wcd9335_codec *wcd) 2614 { 2615 int irq, ret, i; 2616 2617 for (i = 0; i < ARRAY_SIZE(wcd9335_irqs); i++) { 2618 irq = regmap_irq_get_virq(wcd->irq_data, wcd9335_irqs[i].irq); 2619 if (irq < 0) { 2620 dev_err(wcd->dev, "Failed to get %s\n", 2621 wcd9335_irqs[i].name); 2622 return irq; 2623 } 2624 2625 ret = devm_request_threaded_irq(wcd->dev, irq, NULL, 2626 wcd9335_irqs[i].handler, 2627 IRQF_TRIGGER_RISING, 2628 wcd9335_irqs[i].name, wcd); 2629 if (ret) { 2630 dev_err(wcd->dev, "Failed to request %s\n", 2631 wcd9335_irqs[i].name); 2632 return ret; 2633 } 2634 } 2635 2636 /* enable interrupts on all slave ports */ 2637 for (i = 0; i < WCD9335_SLIM_NUM_PORT_REG; i++) 2638 regmap_write(wcd->if_regmap, WCD9335_SLIM_PGD_PORT_INT_EN0 + i, 2639 0xFF); 2640 2641 return ret; 2642 } 2643 2644 static void wcd9335_cdc_sido_ccl_enable(struct wcd9335_codec *wcd, 2645 bool ccl_flag) 2646 { 2647 struct snd_soc_component *comp = wcd->component; 2648 2649 if (ccl_flag) { 2650 if (++wcd->sido_ccl_cnt == 1) 2651 snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10, 2652 WCD9335_SIDO_SIDO_CCL_DEF_VALUE); 2653 } else { 2654 if (wcd->sido_ccl_cnt == 0) { 2655 dev_err(wcd->dev, "sido_ccl already disabled\n"); 2656 return; 2657 } 2658 if (--wcd->sido_ccl_cnt == 0) 2659 snd_soc_component_write(comp, WCD9335_SIDO_SIDO_CCL_10, 2660 WCD9335_SIDO_SIDO_CCL_10_ICHARG_PWR_SEL_C320FF); 2661 } 2662 } 2663 2664 static int wcd9335_enable_master_bias(struct wcd9335_codec *wcd) 2665 { 2666 wcd->master_bias_users++; 2667 if (wcd->master_bias_users == 1) { 2668 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 2669 WCD9335_ANA_BIAS_EN_MASK, 2670 WCD9335_ANA_BIAS_ENABLE); 2671 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 2672 WCD9335_ANA_BIAS_PRECHRG_EN_MASK, 2673 WCD9335_ANA_BIAS_PRECHRG_ENABLE); 2674 /* 2675 * 1ms delay is required after pre-charge is enabled 2676 * as per HW requirement 2677 */ 2678 usleep_range(1000, 1100); 2679 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 2680 WCD9335_ANA_BIAS_PRECHRG_EN_MASK, 2681 WCD9335_ANA_BIAS_PRECHRG_DISABLE); 2682 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 2683 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE, 2684 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL); 2685 } 2686 2687 return 0; 2688 } 2689 2690 static int wcd9335_enable_mclk(struct wcd9335_codec *wcd) 2691 { 2692 /* Enable mclk requires master bias to be enabled first */ 2693 if (wcd->master_bias_users <= 0) 2694 return -EINVAL; 2695 2696 if (((wcd->clk_mclk_users == 0) && (wcd->clk_type == WCD_CLK_MCLK)) || 2697 ((wcd->clk_mclk_users > 0) && (wcd->clk_type != WCD_CLK_MCLK))) { 2698 dev_err(wcd->dev, "Error enabling MCLK, clk_type: %d\n", 2699 wcd->clk_type); 2700 return -EINVAL; 2701 } 2702 2703 if (++wcd->clk_mclk_users == 1) { 2704 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 2705 WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK, 2706 WCD9335_ANA_CLK_EXT_CLKBUF_ENABLE); 2707 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 2708 WCD9335_ANA_CLK_MCLK_SRC_MASK, 2709 WCD9335_ANA_CLK_MCLK_SRC_EXTERNAL); 2710 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 2711 WCD9335_ANA_CLK_MCLK_EN_MASK, 2712 WCD9335_ANA_CLK_MCLK_ENABLE); 2713 regmap_update_bits(wcd->regmap, 2714 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 2715 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_EN_MASK, 2716 WCD9335_CDC_CLK_RST_CTRL_FS_CNT_ENABLE); 2717 regmap_update_bits(wcd->regmap, 2718 WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL, 2719 WCD9335_CDC_CLK_RST_CTRL_MCLK_EN_MASK, 2720 WCD9335_CDC_CLK_RST_CTRL_MCLK_ENABLE); 2721 /* 2722 * 10us sleep is required after clock is enabled 2723 * as per HW requirement 2724 */ 2725 usleep_range(10, 15); 2726 } 2727 2728 wcd->clk_type = WCD_CLK_MCLK; 2729 2730 return 0; 2731 } 2732 2733 static int wcd9335_disable_mclk(struct wcd9335_codec *wcd) 2734 { 2735 if (wcd->clk_mclk_users <= 0) 2736 return -EINVAL; 2737 2738 if (--wcd->clk_mclk_users == 0) { 2739 if (wcd->clk_rco_users > 0) { 2740 /* MCLK to RCO switch */ 2741 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 2742 WCD9335_ANA_CLK_MCLK_SRC_MASK, 2743 WCD9335_ANA_CLK_MCLK_SRC_RCO); 2744 wcd->clk_type = WCD_CLK_RCO; 2745 } else { 2746 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 2747 WCD9335_ANA_CLK_MCLK_EN_MASK, 2748 WCD9335_ANA_CLK_MCLK_DISABLE); 2749 wcd->clk_type = WCD_CLK_OFF; 2750 } 2751 2752 regmap_update_bits(wcd->regmap, WCD9335_ANA_CLK_TOP, 2753 WCD9335_ANA_CLK_EXT_CLKBUF_EN_MASK, 2754 WCD9335_ANA_CLK_EXT_CLKBUF_DISABLE); 2755 } 2756 2757 return 0; 2758 } 2759 2760 static int wcd9335_disable_master_bias(struct wcd9335_codec *wcd) 2761 { 2762 if (wcd->master_bias_users <= 0) 2763 return -EINVAL; 2764 2765 wcd->master_bias_users--; 2766 if (wcd->master_bias_users == 0) { 2767 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 2768 WCD9335_ANA_BIAS_EN_MASK, 2769 WCD9335_ANA_BIAS_DISABLE); 2770 regmap_update_bits(wcd->regmap, WCD9335_ANA_BIAS, 2771 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE, 2772 WCD9335_ANA_BIAS_PRECHRG_CTL_MODE_MANUAL); 2773 } 2774 return 0; 2775 } 2776 2777 static int wcd9335_cdc_req_mclk_enable(struct wcd9335_codec *wcd, 2778 bool enable) 2779 { 2780 int ret = 0; 2781 2782 if (enable) { 2783 wcd9335_cdc_sido_ccl_enable(wcd, true); 2784 ret = clk_prepare_enable(wcd->mclk); 2785 if (ret) { 2786 dev_err(wcd->dev, "%s: ext clk enable failed\n", 2787 __func__); 2788 goto err; 2789 } 2790 /* get BG */ 2791 wcd9335_enable_master_bias(wcd); 2792 /* get MCLK */ 2793 wcd9335_enable_mclk(wcd); 2794 2795 } else { 2796 /* put MCLK */ 2797 wcd9335_disable_mclk(wcd); 2798 /* put BG */ 2799 wcd9335_disable_master_bias(wcd); 2800 clk_disable_unprepare(wcd->mclk); 2801 wcd9335_cdc_sido_ccl_enable(wcd, false); 2802 } 2803 err: 2804 return ret; 2805 } 2806 2807 static void wcd9335_codec_apply_sido_voltage(struct wcd9335_codec *wcd, 2808 enum wcd9335_sido_voltage req_mv) 2809 { 2810 struct snd_soc_component *comp = wcd->component; 2811 int vout_d_val; 2812 2813 if (req_mv == wcd->sido_voltage) 2814 return; 2815 2816 /* compute the vout_d step value */ 2817 vout_d_val = WCD9335_CALCULATE_VOUT_D(req_mv) & 2818 WCD9335_ANA_BUCK_VOUT_MASK; 2819 snd_soc_component_write(comp, WCD9335_ANA_BUCK_VOUT_D, vout_d_val); 2820 snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL, 2821 WCD9335_ANA_BUCK_CTL_RAMP_START_MASK, 2822 WCD9335_ANA_BUCK_CTL_RAMP_START_ENABLE); 2823 2824 /* 1 msec sleep required after SIDO Vout_D voltage change */ 2825 usleep_range(1000, 1100); 2826 wcd->sido_voltage = req_mv; 2827 snd_soc_component_update_bits(comp, WCD9335_ANA_BUCK_CTL, 2828 WCD9335_ANA_BUCK_CTL_RAMP_START_MASK, 2829 WCD9335_ANA_BUCK_CTL_RAMP_START_DISABLE); 2830 } 2831 2832 static int wcd9335_codec_update_sido_voltage(struct wcd9335_codec *wcd, 2833 enum wcd9335_sido_voltage req_mv) 2834 { 2835 int ret = 0; 2836 2837 /* enable mclk before setting SIDO voltage */ 2838 ret = wcd9335_cdc_req_mclk_enable(wcd, true); 2839 if (ret) { 2840 dev_err(wcd->dev, "Ext clk enable failed\n"); 2841 goto err; 2842 } 2843 2844 wcd9335_codec_apply_sido_voltage(wcd, req_mv); 2845 wcd9335_cdc_req_mclk_enable(wcd, false); 2846 2847 err: 2848 return ret; 2849 } 2850 2851 static int _wcd9335_codec_enable_mclk(struct snd_soc_component *component, 2852 int enable) 2853 { 2854 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 2855 int ret; 2856 2857 if (enable) { 2858 ret = wcd9335_cdc_req_mclk_enable(wcd, true); 2859 if (ret) 2860 return ret; 2861 2862 wcd9335_codec_apply_sido_voltage(wcd, 2863 SIDO_VOLTAGE_NOMINAL_MV); 2864 } else { 2865 wcd9335_codec_update_sido_voltage(wcd, 2866 wcd->sido_voltage); 2867 wcd9335_cdc_req_mclk_enable(wcd, false); 2868 } 2869 2870 return 0; 2871 } 2872 2873 static int wcd9335_codec_enable_mclk(struct snd_soc_dapm_widget *w, 2874 struct snd_kcontrol *kc, int event) 2875 { 2876 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); 2877 2878 switch (event) { 2879 case SND_SOC_DAPM_PRE_PMU: 2880 return _wcd9335_codec_enable_mclk(comp, true); 2881 case SND_SOC_DAPM_POST_PMD: 2882 return _wcd9335_codec_enable_mclk(comp, false); 2883 } 2884 2885 return 0; 2886 } 2887 2888 static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = { 2889 /* TODO SPK1 & SPK2 OUT*/ 2890 SND_SOC_DAPM_OUTPUT("EAR"), 2891 SND_SOC_DAPM_OUTPUT("HPHL"), 2892 SND_SOC_DAPM_OUTPUT("HPHR"), 2893 SND_SOC_DAPM_OUTPUT("LINEOUT1"), 2894 SND_SOC_DAPM_OUTPUT("LINEOUT2"), 2895 SND_SOC_DAPM_OUTPUT("LINEOUT3"), 2896 SND_SOC_DAPM_OUTPUT("LINEOUT4"), 2897 SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM, 2898 AIF1_PB, 0, wcd9335_codec_enable_slim, 2899 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 2900 SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM, 2901 AIF2_PB, 0, wcd9335_codec_enable_slim, 2902 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 2903 SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM, 2904 AIF3_PB, 0, wcd9335_codec_enable_slim, 2905 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 2906 SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM, 2907 AIF4_PB, 0, wcd9335_codec_enable_slim, 2908 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 2909 SND_SOC_DAPM_MUX("SLIM RX0 MUX", SND_SOC_NOPM, WCD9335_RX0, 0, 2910 &slim_rx_mux[WCD9335_RX0]), 2911 SND_SOC_DAPM_MUX("SLIM RX1 MUX", SND_SOC_NOPM, WCD9335_RX1, 0, 2912 &slim_rx_mux[WCD9335_RX1]), 2913 SND_SOC_DAPM_MUX("SLIM RX2 MUX", SND_SOC_NOPM, WCD9335_RX2, 0, 2914 &slim_rx_mux[WCD9335_RX2]), 2915 SND_SOC_DAPM_MUX("SLIM RX3 MUX", SND_SOC_NOPM, WCD9335_RX3, 0, 2916 &slim_rx_mux[WCD9335_RX3]), 2917 SND_SOC_DAPM_MUX("SLIM RX4 MUX", SND_SOC_NOPM, WCD9335_RX4, 0, 2918 &slim_rx_mux[WCD9335_RX4]), 2919 SND_SOC_DAPM_MUX("SLIM RX5 MUX", SND_SOC_NOPM, WCD9335_RX5, 0, 2920 &slim_rx_mux[WCD9335_RX5]), 2921 SND_SOC_DAPM_MUX("SLIM RX6 MUX", SND_SOC_NOPM, WCD9335_RX6, 0, 2922 &slim_rx_mux[WCD9335_RX6]), 2923 SND_SOC_DAPM_MUX("SLIM RX7 MUX", SND_SOC_NOPM, WCD9335_RX7, 0, 2924 &slim_rx_mux[WCD9335_RX7]), 2925 SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0), 2926 SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0), 2927 SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0), 2928 SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0), 2929 SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0), 2930 SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0), 2931 SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0), 2932 SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0), 2933 SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", WCD9335_CDC_RX0_RX_PATH_MIX_CTL, 2934 5, 0, &rx_int0_2_mux, wcd9335_codec_enable_mix_path, 2935 SND_SOC_DAPM_POST_PMU), 2936 SND_SOC_DAPM_MUX_E("RX INT1_2 MUX", WCD9335_CDC_RX1_RX_PATH_MIX_CTL, 2937 5, 0, &rx_int1_2_mux, wcd9335_codec_enable_mix_path, 2938 SND_SOC_DAPM_POST_PMU), 2939 SND_SOC_DAPM_MUX_E("RX INT2_2 MUX", WCD9335_CDC_RX2_RX_PATH_MIX_CTL, 2940 5, 0, &rx_int2_2_mux, wcd9335_codec_enable_mix_path, 2941 SND_SOC_DAPM_POST_PMU), 2942 SND_SOC_DAPM_MUX_E("RX INT3_2 MUX", WCD9335_CDC_RX3_RX_PATH_MIX_CTL, 2943 5, 0, &rx_int3_2_mux, wcd9335_codec_enable_mix_path, 2944 SND_SOC_DAPM_POST_PMU), 2945 SND_SOC_DAPM_MUX_E("RX INT4_2 MUX", WCD9335_CDC_RX4_RX_PATH_MIX_CTL, 2946 5, 0, &rx_int4_2_mux, wcd9335_codec_enable_mix_path, 2947 SND_SOC_DAPM_POST_PMU), 2948 SND_SOC_DAPM_MUX_E("RX INT5_2 MUX", WCD9335_CDC_RX5_RX_PATH_MIX_CTL, 2949 5, 0, &rx_int5_2_mux, wcd9335_codec_enable_mix_path, 2950 SND_SOC_DAPM_POST_PMU), 2951 SND_SOC_DAPM_MUX_E("RX INT6_2 MUX", WCD9335_CDC_RX6_RX_PATH_MIX_CTL, 2952 5, 0, &rx_int6_2_mux, wcd9335_codec_enable_mix_path, 2953 SND_SOC_DAPM_POST_PMU), 2954 SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", WCD9335_CDC_RX7_RX_PATH_MIX_CTL, 2955 5, 0, &rx_int7_2_mux, wcd9335_codec_enable_mix_path, 2956 SND_SOC_DAPM_POST_PMU), 2957 SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", WCD9335_CDC_RX8_RX_PATH_MIX_CTL, 2958 5, 0, &rx_int8_2_mux, wcd9335_codec_enable_mix_path, 2959 SND_SOC_DAPM_POST_PMU), 2960 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2961 &rx_int0_1_mix_inp0_mux), 2962 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2963 &rx_int0_1_mix_inp1_mux), 2964 SND_SOC_DAPM_MUX("RX INT0_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 2965 &rx_int0_1_mix_inp2_mux), 2966 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2967 &rx_int1_1_mix_inp0_mux), 2968 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2969 &rx_int1_1_mix_inp1_mux), 2970 SND_SOC_DAPM_MUX("RX INT1_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 2971 &rx_int1_1_mix_inp2_mux), 2972 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2973 &rx_int2_1_mix_inp0_mux), 2974 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2975 &rx_int2_1_mix_inp1_mux), 2976 SND_SOC_DAPM_MUX("RX INT2_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 2977 &rx_int2_1_mix_inp2_mux), 2978 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2979 &rx_int3_1_mix_inp0_mux), 2980 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2981 &rx_int3_1_mix_inp1_mux), 2982 SND_SOC_DAPM_MUX("RX INT3_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 2983 &rx_int3_1_mix_inp2_mux), 2984 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2985 &rx_int4_1_mix_inp0_mux), 2986 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2987 &rx_int4_1_mix_inp1_mux), 2988 SND_SOC_DAPM_MUX("RX INT4_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 2989 &rx_int4_1_mix_inp2_mux), 2990 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2991 &rx_int5_1_mix_inp0_mux), 2992 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2993 &rx_int5_1_mix_inp1_mux), 2994 SND_SOC_DAPM_MUX("RX INT5_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 2995 &rx_int5_1_mix_inp2_mux), 2996 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 2997 &rx_int6_1_mix_inp0_mux), 2998 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 2999 &rx_int6_1_mix_inp1_mux), 3000 SND_SOC_DAPM_MUX("RX INT6_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 3001 &rx_int6_1_mix_inp2_mux), 3002 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 3003 &rx_int7_1_mix_inp0_mux), 3004 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 3005 &rx_int7_1_mix_inp1_mux), 3006 SND_SOC_DAPM_MUX("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 3007 &rx_int7_1_mix_inp2_mux), 3008 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0, 3009 &rx_int8_1_mix_inp0_mux), 3010 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0, 3011 &rx_int8_1_mix_inp1_mux), 3012 SND_SOC_DAPM_MUX("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0, 3013 &rx_int8_1_mix_inp2_mux), 3014 3015 SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3016 SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3017 SND_SOC_DAPM_MIXER("RX INT1_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3018 SND_SOC_DAPM_MIXER("RX INT1 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3019 SND_SOC_DAPM_MIXER("RX INT2_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3020 SND_SOC_DAPM_MIXER("RX INT2 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3021 SND_SOC_DAPM_MIXER("RX INT3_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3022 SND_SOC_DAPM_MIXER("RX INT3 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3023 SND_SOC_DAPM_MIXER("RX INT4_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3024 SND_SOC_DAPM_MIXER("RX INT4 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3025 SND_SOC_DAPM_MIXER("RX INT5_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3026 SND_SOC_DAPM_MIXER("RX INT5 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3027 SND_SOC_DAPM_MIXER("RX INT6_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3028 SND_SOC_DAPM_MIXER("RX INT6 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3029 SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3030 SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3031 SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 3032 SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0), 3033 3034 SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3035 SND_SOC_DAPM_MIXER("RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3036 SND_SOC_DAPM_MIXER("RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3037 SND_SOC_DAPM_MIXER("RX INT3 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3038 SND_SOC_DAPM_MIXER("RX INT4 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3039 SND_SOC_DAPM_MIXER("RX INT5 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3040 SND_SOC_DAPM_MIXER("RX INT6 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3041 SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3042 SND_SOC_DAPM_MIXER("RX INT8 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0), 3043 3044 SND_SOC_DAPM_MUX("RX INT0 DEM MUX", SND_SOC_NOPM, 0, 0, 3045 &rx_int0_dem_inp_mux), 3046 SND_SOC_DAPM_MUX("RX INT1 DEM MUX", SND_SOC_NOPM, 0, 0, 3047 &rx_int1_dem_inp_mux), 3048 SND_SOC_DAPM_MUX("RX INT2 DEM MUX", SND_SOC_NOPM, 0, 0, 3049 &rx_int2_dem_inp_mux), 3050 3051 SND_SOC_DAPM_MUX_E("RX INT0 INTERP", SND_SOC_NOPM, 3052 INTERP_EAR, 0, &rx_int0_interp_mux, 3053 wcd9335_codec_enable_interpolator, 3054 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3055 SND_SOC_DAPM_POST_PMD), 3056 SND_SOC_DAPM_MUX_E("RX INT1 INTERP", SND_SOC_NOPM, 3057 INTERP_HPHL, 0, &rx_int1_interp_mux, 3058 wcd9335_codec_enable_interpolator, 3059 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3060 SND_SOC_DAPM_POST_PMD), 3061 SND_SOC_DAPM_MUX_E("RX INT2 INTERP", SND_SOC_NOPM, 3062 INTERP_HPHR, 0, &rx_int2_interp_mux, 3063 wcd9335_codec_enable_interpolator, 3064 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3065 SND_SOC_DAPM_POST_PMD), 3066 SND_SOC_DAPM_MUX_E("RX INT3 INTERP", SND_SOC_NOPM, 3067 INTERP_LO1, 0, &rx_int3_interp_mux, 3068 wcd9335_codec_enable_interpolator, 3069 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3070 SND_SOC_DAPM_POST_PMD), 3071 SND_SOC_DAPM_MUX_E("RX INT4 INTERP", SND_SOC_NOPM, 3072 INTERP_LO2, 0, &rx_int4_interp_mux, 3073 wcd9335_codec_enable_interpolator, 3074 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3075 SND_SOC_DAPM_POST_PMD), 3076 SND_SOC_DAPM_MUX_E("RX INT5 INTERP", SND_SOC_NOPM, 3077 INTERP_LO3, 0, &rx_int5_interp_mux, 3078 wcd9335_codec_enable_interpolator, 3079 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3080 SND_SOC_DAPM_POST_PMD), 3081 SND_SOC_DAPM_MUX_E("RX INT6 INTERP", SND_SOC_NOPM, 3082 INTERP_LO4, 0, &rx_int6_interp_mux, 3083 wcd9335_codec_enable_interpolator, 3084 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3085 SND_SOC_DAPM_POST_PMD), 3086 SND_SOC_DAPM_MUX_E("RX INT7 INTERP", SND_SOC_NOPM, 3087 INTERP_SPKR1, 0, &rx_int7_interp_mux, 3088 wcd9335_codec_enable_interpolator, 3089 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3090 SND_SOC_DAPM_POST_PMD), 3091 SND_SOC_DAPM_MUX_E("RX INT8 INTERP", SND_SOC_NOPM, 3092 INTERP_SPKR2, 0, &rx_int8_interp_mux, 3093 wcd9335_codec_enable_interpolator, 3094 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3095 SND_SOC_DAPM_POST_PMD), 3096 3097 SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM, 3098 0, 0, wcd9335_codec_ear_dac_event, 3099 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3100 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 3101 SND_SOC_DAPM_DAC_E("RX INT1 DAC", NULL, WCD9335_ANA_HPH, 3102 5, 0, wcd9335_codec_hphl_dac_event, 3103 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3104 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 3105 SND_SOC_DAPM_DAC_E("RX INT2 DAC", NULL, WCD9335_ANA_HPH, 3106 4, 0, wcd9335_codec_hphr_dac_event, 3107 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3108 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 3109 SND_SOC_DAPM_DAC_E("RX INT3 DAC", NULL, SND_SOC_NOPM, 3110 0, 0, wcd9335_codec_lineout_dac_event, 3111 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 3112 SND_SOC_DAPM_DAC_E("RX INT4 DAC", NULL, SND_SOC_NOPM, 3113 0, 0, wcd9335_codec_lineout_dac_event, 3114 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 3115 SND_SOC_DAPM_DAC_E("RX INT5 DAC", NULL, SND_SOC_NOPM, 3116 0, 0, wcd9335_codec_lineout_dac_event, 3117 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 3118 SND_SOC_DAPM_DAC_E("RX INT6 DAC", NULL, SND_SOC_NOPM, 3119 0, 0, wcd9335_codec_lineout_dac_event, 3120 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 3121 SND_SOC_DAPM_PGA_E("HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0, 3122 wcd9335_codec_enable_hphl_pa, 3123 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3124 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 3125 SND_SOC_DAPM_PGA_E("HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0, 3126 wcd9335_codec_enable_hphr_pa, 3127 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | 3128 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), 3129 SND_SOC_DAPM_PGA_E("EAR PA", WCD9335_ANA_EAR, 7, 0, NULL, 0, 3130 wcd9335_codec_enable_ear_pa, 3131 SND_SOC_DAPM_POST_PMU | 3132 SND_SOC_DAPM_POST_PMD), 3133 SND_SOC_DAPM_PGA_E("LINEOUT1 PA", WCD9335_ANA_LO_1_2, 7, 0, NULL, 0, 3134 wcd9335_codec_enable_lineout_pa, 3135 SND_SOC_DAPM_POST_PMU | 3136 SND_SOC_DAPM_POST_PMD), 3137 SND_SOC_DAPM_PGA_E("LINEOUT2 PA", WCD9335_ANA_LO_1_2, 6, 0, NULL, 0, 3138 wcd9335_codec_enable_lineout_pa, 3139 SND_SOC_DAPM_POST_PMU | 3140 SND_SOC_DAPM_POST_PMD), 3141 SND_SOC_DAPM_PGA_E("LINEOUT3 PA", WCD9335_ANA_LO_3_4, 7, 0, NULL, 0, 3142 wcd9335_codec_enable_lineout_pa, 3143 SND_SOC_DAPM_POST_PMU | 3144 SND_SOC_DAPM_POST_PMD), 3145 SND_SOC_DAPM_PGA_E("LINEOUT4 PA", WCD9335_ANA_LO_3_4, 6, 0, NULL, 0, 3146 wcd9335_codec_enable_lineout_pa, 3147 SND_SOC_DAPM_POST_PMU | 3148 SND_SOC_DAPM_POST_PMD), 3149 SND_SOC_DAPM_SUPPLY("RX_BIAS", SND_SOC_NOPM, 0, 0, 3150 wcd9335_codec_enable_rx_bias, SND_SOC_DAPM_PRE_PMU | 3151 SND_SOC_DAPM_POST_PMD), 3152 SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, 3153 wcd9335_codec_enable_mclk, SND_SOC_DAPM_PRE_PMU | 3154 SND_SOC_DAPM_POST_PMD), 3155 3156 }; 3157 3158 static void wcd9335_enable_sido_buck(struct snd_soc_component *component) 3159 { 3160 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 3161 3162 snd_soc_component_update_bits(component, WCD9335_ANA_RCO, 3163 WCD9335_ANA_RCO_BG_EN_MASK, 3164 WCD9335_ANA_RCO_BG_ENABLE); 3165 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, 3166 WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_MASK, 3167 WCD9335_ANA_BUCK_CTL_VOUT_D_IREF_EXT); 3168 /* 100us sleep needed after IREF settings */ 3169 usleep_range(100, 110); 3170 snd_soc_component_update_bits(component, WCD9335_ANA_BUCK_CTL, 3171 WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_MASK, 3172 WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT); 3173 /* 100us sleep needed after VREF settings */ 3174 usleep_range(100, 110); 3175 wcd->sido_input_src = SIDO_SOURCE_RCO_BG; 3176 } 3177 3178 static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp) 3179 { 3180 _wcd9335_codec_enable_mclk(comp, true); 3181 snd_soc_component_update_bits(comp, 3182 WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 3183 WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK, 3184 WCD9335_CHIP_TIER_CTRL_EFUSE_ENABLE); 3185 /* 3186 * 5ms sleep required after enabling efuse control 3187 * before checking the status. 3188 */ 3189 usleep_range(5000, 5500); 3190 3191 if (!(snd_soc_component_read32(comp, 3192 WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 3193 WCD9335_CHIP_TIER_CTRL_EFUSE_EN_MASK)) 3194 WARN(1, "%s: Efuse sense is not complete\n", __func__); 3195 3196 wcd9335_enable_sido_buck(comp); 3197 _wcd9335_codec_enable_mclk(comp, false); 3198 3199 return 0; 3200 } 3201 3202 static void wcd9335_codec_init(struct snd_soc_component *component) 3203 { 3204 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 3205 int i; 3206 3207 /* ungate MCLK and set clk rate */ 3208 regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_GATE, 3209 WCD9335_CODEC_RPM_CLK_GATE_MCLK_GATE_MASK, 0); 3210 3211 regmap_update_bits(wcd->regmap, WCD9335_CODEC_RPM_CLK_MCLK_CFG, 3212 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, 3213 WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ); 3214 3215 for (i = 0; i < ARRAY_SIZE(wcd9335_codec_reg_init); i++) 3216 snd_soc_component_update_bits(component, 3217 wcd9335_codec_reg_init[i].reg, 3218 wcd9335_codec_reg_init[i].mask, 3219 wcd9335_codec_reg_init[i].val); 3220 3221 wcd9335_enable_efuse_sensing(component); 3222 } 3223 3224 static int wcd9335_codec_probe(struct snd_soc_component *component) 3225 { 3226 struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); 3227 int i; 3228 3229 snd_soc_component_init_regmap(component, wcd->regmap); 3230 /* Class-H Init*/ 3231 wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, wcd->version); 3232 if (IS_ERR(wcd->clsh_ctrl)) 3233 return PTR_ERR(wcd->clsh_ctrl); 3234 3235 /* Default HPH Mode to Class-H HiFi */ 3236 wcd->hph_mode = CLS_H_HIFI; 3237 wcd->component = component; 3238 3239 wcd9335_codec_init(component); 3240 3241 for (i = 0; i < NUM_CODEC_DAIS; i++) 3242 INIT_LIST_HEAD(&wcd->dai[i].slim_ch_list); 3243 3244 return wcd9335_setup_irqs(wcd); 3245 } 3246 3247 static void wcd9335_codec_remove(struct snd_soc_component *comp) 3248 { 3249 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3250 3251 wcd_clsh_ctrl_free(wcd->clsh_ctrl); 3252 free_irq(regmap_irq_get_virq(wcd->irq_data, WCD9335_IRQ_SLIMBUS), wcd); 3253 } 3254 3255 static int wcd9335_codec_set_sysclk(struct snd_soc_component *comp, 3256 int clk_id, int source, 3257 unsigned int freq, int dir) 3258 { 3259 struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev); 3260 3261 wcd->mclk_rate = freq; 3262 3263 if (wcd->mclk_rate == WCD9335_MCLK_CLK_12P288MHZ) 3264 snd_soc_component_update_bits(comp, 3265 WCD9335_CODEC_RPM_CLK_MCLK_CFG, 3266 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, 3267 WCD9335_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ); 3268 else if (wcd->mclk_rate == WCD9335_MCLK_CLK_9P6MHZ) 3269 snd_soc_component_update_bits(comp, 3270 WCD9335_CODEC_RPM_CLK_MCLK_CFG, 3271 WCD9335_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK, 3272 WCD9335_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ); 3273 3274 return clk_set_rate(wcd->mclk, freq); 3275 } 3276 3277 static const struct snd_soc_component_driver wcd9335_component_drv = { 3278 .probe = wcd9335_codec_probe, 3279 .remove = wcd9335_codec_remove, 3280 .set_sysclk = wcd9335_codec_set_sysclk, 3281 .controls = wcd9335_snd_controls, 3282 .num_controls = ARRAY_SIZE(wcd9335_snd_controls), 3283 .dapm_widgets = wcd9335_dapm_widgets, 3284 .num_dapm_widgets = ARRAY_SIZE(wcd9335_dapm_widgets), 3285 }; 3286 3287 static int wcd9335_probe(struct wcd9335_codec *wcd) 3288 { 3289 struct device *dev = wcd->dev; 3290 3291 memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs)); 3292 3293 wcd->sido_input_src = SIDO_SOURCE_INTERNAL; 3294 wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV; 3295 3296 return devm_snd_soc_register_component(dev, &wcd9335_component_drv, 3297 wcd9335_slim_dais, 3298 ARRAY_SIZE(wcd9335_slim_dais)); 3299 } 3300 3301 static const struct regmap_range_cfg wcd9335_ranges[] = { 3302 { 3303 .name = "WCD9335", 3304 .range_min = 0x0, 3305 .range_max = WCD9335_MAX_REGISTER, 3306 .selector_reg = WCD9335_REG(0x0, 0), 3307 .selector_mask = 0xff, 3308 .selector_shift = 0, 3309 .window_start = 0x0, 3310 .window_len = 0x1000, 3311 }, 3312 }; 3313 3314 static bool wcd9335_is_volatile_register(struct device *dev, unsigned int reg) 3315 { 3316 switch (reg) { 3317 case WCD9335_INTR_PIN1_STATUS0...WCD9335_INTR_PIN2_CLEAR3: 3318 case WCD9335_ANA_MBHC_RESULT_3: 3319 case WCD9335_ANA_MBHC_RESULT_2: 3320 case WCD9335_ANA_MBHC_RESULT_1: 3321 case WCD9335_ANA_MBHC_MECH: 3322 case WCD9335_ANA_MBHC_ELECT: 3323 case WCD9335_ANA_MBHC_ZDET: 3324 case WCD9335_ANA_MICB2: 3325 case WCD9335_ANA_RCO: 3326 case WCD9335_ANA_BIAS: 3327 return true; 3328 default: 3329 return false; 3330 } 3331 } 3332 3333 static struct regmap_config wcd9335_regmap_config = { 3334 .reg_bits = 16, 3335 .val_bits = 8, 3336 .cache_type = REGCACHE_RBTREE, 3337 .max_register = WCD9335_MAX_REGISTER, 3338 .can_multi_write = true, 3339 .ranges = wcd9335_ranges, 3340 .num_ranges = ARRAY_SIZE(wcd9335_ranges), 3341 .volatile_reg = wcd9335_is_volatile_register, 3342 }; 3343 3344 static const struct regmap_range_cfg wcd9335_ifc_ranges[] = { 3345 { 3346 .name = "WCD9335-IFC-DEV", 3347 .range_min = 0x0, 3348 .range_max = WCD9335_REG(0, 0x7ff), 3349 .selector_reg = WCD9335_REG(0, 0x0), 3350 .selector_mask = 0xff, 3351 .selector_shift = 0, 3352 .window_start = 0x0, 3353 .window_len = 0x1000, 3354 }, 3355 }; 3356 3357 static struct regmap_config wcd9335_ifc_regmap_config = { 3358 .reg_bits = 16, 3359 .val_bits = 8, 3360 .can_multi_write = true, 3361 .max_register = WCD9335_REG(0, 0x7FF), 3362 .ranges = wcd9335_ifc_ranges, 3363 .num_ranges = ARRAY_SIZE(wcd9335_ifc_ranges), 3364 }; 3365 3366 static const struct regmap_irq wcd9335_codec_irqs[] = { 3367 /* INTR_REG 0 */ 3368 [WCD9335_IRQ_SLIMBUS] = { 3369 .reg_offset = 0, 3370 .mask = BIT(0), 3371 .type = { 3372 .type_reg_offset = 0, 3373 .types_supported = IRQ_TYPE_EDGE_BOTH, 3374 .type_reg_mask = BIT(0), 3375 }, 3376 }, 3377 }; 3378 3379 static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { 3380 .name = "wcd9335_pin1_irq", 3381 .status_base = WCD9335_INTR_PIN1_STATUS0, 3382 .mask_base = WCD9335_INTR_PIN1_MASK0, 3383 .ack_base = WCD9335_INTR_PIN1_CLEAR0, 3384 .type_base = WCD9335_INTR_LEVEL0, 3385 .num_type_reg = 4, 3386 .num_regs = 4, 3387 .irqs = wcd9335_codec_irqs, 3388 .num_irqs = ARRAY_SIZE(wcd9335_codec_irqs), 3389 }; 3390 3391 static int wcd9335_parse_dt(struct wcd9335_codec *wcd) 3392 { 3393 struct device *dev = wcd->dev; 3394 struct device_node *np = dev->of_node; 3395 int ret; 3396 3397 wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); 3398 if (wcd->reset_gpio < 0) { 3399 dev_err(dev, "Reset GPIO missing from DT\n"); 3400 return wcd->reset_gpio; 3401 } 3402 3403 wcd->mclk = devm_clk_get(dev, "mclk"); 3404 if (IS_ERR(wcd->mclk)) { 3405 dev_err(dev, "mclk not found\n"); 3406 return PTR_ERR(wcd->mclk); 3407 } 3408 3409 wcd->native_clk = devm_clk_get(dev, "slimbus"); 3410 if (IS_ERR(wcd->native_clk)) { 3411 dev_err(dev, "slimbus clock not found\n"); 3412 return PTR_ERR(wcd->native_clk); 3413 } 3414 3415 wcd->supplies[0].supply = "vdd-buck"; 3416 wcd->supplies[1].supply = "vdd-buck-sido"; 3417 wcd->supplies[2].supply = "vdd-tx"; 3418 wcd->supplies[3].supply = "vdd-rx"; 3419 wcd->supplies[4].supply = "vdd-io"; 3420 3421 ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies); 3422 if (ret) { 3423 dev_err(dev, "Failed to get supplies: err = %d\n", ret); 3424 return ret; 3425 } 3426 3427 return 0; 3428 } 3429 3430 static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) 3431 { 3432 struct device *dev = wcd->dev; 3433 int ret; 3434 3435 ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies); 3436 if (ret) { 3437 dev_err(dev, "Failed to get supplies: err = %d\n", ret); 3438 return ret; 3439 } 3440 3441 /* 3442 * For WCD9335, it takes about 600us for the Vout_A and 3443 * Vout_D to be ready after BUCK_SIDO is powered up. 3444 * SYS_RST_N shouldn't be pulled high during this time 3445 * Toggle the reset line to make sure the reset pulse is 3446 * correctly applied 3447 */ 3448 usleep_range(600, 650); 3449 3450 gpio_direction_output(wcd->reset_gpio, 0); 3451 msleep(20); 3452 gpio_set_value(wcd->reset_gpio, 1); 3453 msleep(20); 3454 3455 return 0; 3456 } 3457 3458 static int wcd9335_bring_up(struct wcd9335_codec *wcd) 3459 { 3460 struct regmap *rm = wcd->regmap; 3461 int val, byte0; 3462 3463 regmap_read(rm, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val); 3464 regmap_read(rm, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0); 3465 3466 if ((val < 0) || (byte0 < 0)) { 3467 dev_err(wcd->dev, "WCD9335 CODEC version detection fail!\n"); 3468 return -EINVAL; 3469 } 3470 3471 if (byte0 == 0x1) { 3472 dev_info(wcd->dev, "WCD9335 CODEC version is v2.0\n"); 3473 wcd->version = WCD9335_VERSION_2_0; 3474 regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x01); 3475 regmap_write(rm, WCD9335_SIDO_SIDO_TEST_2, 0x00); 3476 regmap_write(rm, WCD9335_SIDO_SIDO_CCL_8, 0x6F); 3477 regmap_write(rm, WCD9335_BIAS_VBG_FINE_ADJ, 0x65); 3478 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5); 3479 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7); 3480 regmap_write(rm, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); 3481 regmap_write(rm, WCD9335_CODEC_RPM_RST_CTL, 0x3); 3482 } else { 3483 dev_err(wcd->dev, "WCD9335 CODEC version not supported\n"); 3484 return -EINVAL; 3485 } 3486 3487 return 0; 3488 } 3489 3490 static int wcd9335_irq_init(struct wcd9335_codec *wcd) 3491 { 3492 int ret; 3493 3494 /* 3495 * INTR1 consists of all possible interrupt sources Ear OCP, 3496 * HPH OCP, MBHC, MAD, VBAT, and SVA 3497 * INTR2 is a subset of first interrupt sources MAD, VBAT, and SVA 3498 */ 3499 wcd->intr1 = of_irq_get_byname(wcd->dev->of_node, "intr1"); 3500 if (wcd->intr1 < 0) { 3501 if (wcd->intr1 != -EPROBE_DEFER) 3502 dev_err(wcd->dev, "Unable to configure IRQ\n"); 3503 3504 return wcd->intr1; 3505 } 3506 3507 ret = devm_regmap_add_irq_chip(wcd->dev, wcd->regmap, wcd->intr1, 3508 IRQF_TRIGGER_HIGH, 0, 3509 &wcd9335_regmap_irq1_chip, &wcd->irq_data); 3510 if (ret) 3511 dev_err(wcd->dev, "Failed to register IRQ chip: %d\n", ret); 3512 3513 return ret; 3514 } 3515 3516 static int wcd9335_slim_probe(struct slim_device *slim) 3517 { 3518 struct device *dev = &slim->dev; 3519 struct wcd9335_codec *wcd; 3520 int ret; 3521 3522 wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL); 3523 if (!wcd) 3524 return -ENOMEM; 3525 3526 wcd->dev = dev; 3527 ret = wcd9335_parse_dt(wcd); 3528 if (ret) { 3529 dev_err(dev, "Error parsing DT: %d\n", ret); 3530 return ret; 3531 } 3532 3533 ret = wcd9335_power_on_reset(wcd); 3534 if (ret) 3535 return ret; 3536 3537 dev_set_drvdata(dev, wcd); 3538 3539 return 0; 3540 } 3541 3542 static int wcd9335_slim_status(struct slim_device *sdev, 3543 enum slim_device_status status) 3544 { 3545 struct device *dev = &sdev->dev; 3546 struct device_node *ifc_dev_np; 3547 struct wcd9335_codec *wcd; 3548 int ret; 3549 3550 wcd = dev_get_drvdata(dev); 3551 3552 ifc_dev_np = of_parse_phandle(dev->of_node, "slim-ifc-dev", 0); 3553 if (!ifc_dev_np) { 3554 dev_err(dev, "No Interface device found\n"); 3555 return -EINVAL; 3556 } 3557 3558 wcd->slim = sdev; 3559 wcd->slim_ifc_dev = of_slim_get_device(sdev->ctrl, ifc_dev_np); 3560 if (!wcd->slim_ifc_dev) { 3561 dev_err(dev, "Unable to get SLIM Interface device\n"); 3562 return -EINVAL; 3563 } 3564 3565 slim_get_logical_addr(wcd->slim_ifc_dev); 3566 3567 wcd->regmap = regmap_init_slimbus(sdev, &wcd9335_regmap_config); 3568 if (IS_ERR(wcd->regmap)) { 3569 dev_err(dev, "Failed to allocate slim register map\n"); 3570 return PTR_ERR(wcd->regmap); 3571 } 3572 3573 wcd->if_regmap = regmap_init_slimbus(wcd->slim_ifc_dev, 3574 &wcd9335_ifc_regmap_config); 3575 if (IS_ERR(wcd->if_regmap)) { 3576 dev_err(dev, "Failed to allocate ifc register map\n"); 3577 return PTR_ERR(wcd->if_regmap); 3578 } 3579 3580 ret = wcd9335_bring_up(wcd); 3581 if (ret) { 3582 dev_err(dev, "Failed to bringup WCD9335\n"); 3583 return ret; 3584 } 3585 3586 ret = wcd9335_irq_init(wcd); 3587 if (ret) 3588 return ret; 3589 3590 wcd9335_probe(wcd); 3591 3592 return ret; 3593 } 3594 3595 static const struct slim_device_id wcd9335_slim_id[] = { 3596 {SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9335, 0x1, 0x0}, 3597 {} 3598 }; 3599 MODULE_DEVICE_TABLE(slim, wcd9335_slim_id); 3600 3601 static struct slim_driver wcd9335_slim_driver = { 3602 .driver = { 3603 .name = "wcd9335-slim", 3604 }, 3605 .probe = wcd9335_slim_probe, 3606 .device_status = wcd9335_slim_status, 3607 .id_table = wcd9335_slim_id, 3608 }; 3609 3610 module_slim_driver(wcd9335_slim_driver); 3611 MODULE_DESCRIPTION("WCD9335 slim driver"); 3612 MODULE_LICENSE("GPL v2"); 3613 MODULE_ALIAS("slim:217:1a0:*"); 3614