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