cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wcd938x.c (162538B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2// Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
      3
      4#include <linux/module.h>
      5#include <linux/slab.h>
      6#include <linux/platform_device.h>
      7#include <linux/device.h>
      8#include <linux/delay.h>
      9#include <linux/gpio/consumer.h>
     10#include <linux/kernel.h>
     11#include <linux/pm_runtime.h>
     12#include <linux/component.h>
     13#include <sound/tlv.h>
     14#include <linux/of_gpio.h>
     15#include <linux/of.h>
     16#include <sound/jack.h>
     17#include <sound/pcm.h>
     18#include <sound/pcm_params.h>
     19#include <linux/regmap.h>
     20#include <sound/soc.h>
     21#include <sound/soc-dapm.h>
     22#include <linux/regulator/consumer.h>
     23
     24#include "wcd-clsh-v2.h"
     25#include "wcd-mbhc-v2.h"
     26#include "wcd938x.h"
     27
     28#define WCD938X_MAX_MICBIAS		(4)
     29#define WCD938X_MAX_SUPPLY		(4)
     30#define WCD938X_MBHC_MAX_BUTTONS	(8)
     31#define TX_ADC_MAX			(4)
     32#define WCD938X_TX_MAX_SWR_PORTS	(5)
     33
     34#define WCD938X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
     35			    SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
     36			    SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
     37/* Fractional Rates */
     38#define WCD938X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
     39				 SNDRV_PCM_RATE_176400)
     40#define WCD938X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
     41				    SNDRV_PCM_FMTBIT_S24_LE)
     42/* Convert from vout ctl to micbias voltage in mV */
     43#define  WCD_VOUT_CTL_TO_MICB(v)	(1000 + v * 50)
     44#define SWR_CLK_RATE_0P6MHZ		(600000)
     45#define SWR_CLK_RATE_1P2MHZ		(1200000)
     46#define SWR_CLK_RATE_2P4MHZ		(2400000)
     47#define SWR_CLK_RATE_4P8MHZ		(4800000)
     48#define SWR_CLK_RATE_9P6MHZ		(9600000)
     49#define SWR_CLK_RATE_11P2896MHZ		(1128960)
     50
     51#define WCD938X_DRV_NAME "wcd938x_codec"
     52#define WCD938X_VERSION_1_0		(1)
     53#define EAR_RX_PATH_AUX			(1)
     54
     55#define ADC_MODE_VAL_HIFI		0x01
     56#define ADC_MODE_VAL_LO_HIF		0x02
     57#define ADC_MODE_VAL_NORMAL		0x03
     58#define ADC_MODE_VAL_LP			0x05
     59#define ADC_MODE_VAL_ULP1		0x09
     60#define ADC_MODE_VAL_ULP2		0x0B
     61
     62/* Z value defined in milliohm */
     63#define WCD938X_ZDET_VAL_32             (32000)
     64#define WCD938X_ZDET_VAL_400            (400000)
     65#define WCD938X_ZDET_VAL_1200           (1200000)
     66#define WCD938X_ZDET_VAL_100K           (100000000)
     67/* Z floating defined in ohms */
     68#define WCD938X_ZDET_FLOATING_IMPEDANCE	(0x0FFFFFFE)
     69#define WCD938X_ZDET_NUM_MEASUREMENTS   (900)
     70#define WCD938X_MBHC_GET_C1(c)          ((c & 0xC000) >> 14)
     71#define WCD938X_MBHC_GET_X1(x)          (x & 0x3FFF)
     72/* Z value compared in milliOhm */
     73#define WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
     74#define WCD938X_MBHC_ZDET_CONST         (86 * 16384)
     75#define WCD938X_MBHC_MOISTURE_RREF      R_24_KOHM
     76#define WCD_MBHC_HS_V_MAX           1600
     77
     78#define WCD938X_EAR_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \
     79{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
     80	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
     81		 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
     82	.tlv.p = (tlv_array), \
     83	.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
     84	.put = wcd938x_ear_pa_put_gain, \
     85	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
     86
     87enum {
     88	WCD9380 = 0,
     89	WCD9385 = 5,
     90};
     91
     92enum {
     93	TX_HDR12 = 0,
     94	TX_HDR34,
     95	TX_HDR_MAX,
     96};
     97
     98enum {
     99	WCD_RX1,
    100	WCD_RX2,
    101	WCD_RX3
    102};
    103
    104enum {
    105	/* INTR_CTRL_INT_MASK_0 */
    106	WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0,
    107	WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET,
    108	WCD938X_IRQ_MBHC_ELECT_INS_REM_DET,
    109	WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
    110	WCD938X_IRQ_MBHC_SW_DET,
    111	WCD938X_IRQ_HPHR_OCP_INT,
    112	WCD938X_IRQ_HPHR_CNP_INT,
    113	WCD938X_IRQ_HPHL_OCP_INT,
    114
    115	/* INTR_CTRL_INT_MASK_1 */
    116	WCD938X_IRQ_HPHL_CNP_INT,
    117	WCD938X_IRQ_EAR_CNP_INT,
    118	WCD938X_IRQ_EAR_SCD_INT,
    119	WCD938X_IRQ_AUX_CNP_INT,
    120	WCD938X_IRQ_AUX_SCD_INT,
    121	WCD938X_IRQ_HPHL_PDM_WD_INT,
    122	WCD938X_IRQ_HPHR_PDM_WD_INT,
    123	WCD938X_IRQ_AUX_PDM_WD_INT,
    124
    125	/* INTR_CTRL_INT_MASK_2 */
    126	WCD938X_IRQ_LDORT_SCD_INT,
    127	WCD938X_IRQ_MBHC_MOISTURE_INT,
    128	WCD938X_IRQ_HPHL_SURGE_DET_INT,
    129	WCD938X_IRQ_HPHR_SURGE_DET_INT,
    130	WCD938X_NUM_IRQS,
    131};
    132
    133enum {
    134	WCD_ADC1 = 0,
    135	WCD_ADC2,
    136	WCD_ADC3,
    137	WCD_ADC4,
    138	ALLOW_BUCK_DISABLE,
    139	HPH_COMP_DELAY,
    140	HPH_PA_DELAY,
    141	AMIC2_BCS_ENABLE,
    142	WCD_SUPPLIES_LPM_MODE,
    143};
    144
    145enum {
    146	ADC_MODE_INVALID = 0,
    147	ADC_MODE_HIFI,
    148	ADC_MODE_LO_HIF,
    149	ADC_MODE_NORMAL,
    150	ADC_MODE_LP,
    151	ADC_MODE_ULP1,
    152	ADC_MODE_ULP2,
    153};
    154
    155enum {
    156	AIF1_PB = 0,
    157	AIF1_CAP,
    158	NUM_CODEC_DAIS,
    159};
    160
    161static u8 tx_mode_bit[] = {
    162	[ADC_MODE_INVALID] = 0x00,
    163	[ADC_MODE_HIFI] = 0x01,
    164	[ADC_MODE_LO_HIF] = 0x02,
    165	[ADC_MODE_NORMAL] = 0x04,
    166	[ADC_MODE_LP] = 0x08,
    167	[ADC_MODE_ULP1] = 0x10,
    168	[ADC_MODE_ULP2] = 0x20,
    169};
    170
    171struct wcd938x_priv {
    172	struct sdw_slave *tx_sdw_dev;
    173	struct wcd938x_sdw_priv *sdw_priv[NUM_CODEC_DAIS];
    174	struct device *txdev;
    175	struct device *rxdev;
    176	struct device_node *rxnode, *txnode;
    177	struct regmap *regmap;
    178	struct mutex micb_lock;
    179	/* mbhc module */
    180	struct wcd_mbhc *wcd_mbhc;
    181	struct wcd_mbhc_config mbhc_cfg;
    182	struct wcd_mbhc_intr intr_ids;
    183	struct wcd_clsh_ctrl *clsh_info;
    184	struct irq_domain *virq;
    185	struct regmap_irq_chip *wcd_regmap_irq_chip;
    186	struct regmap_irq_chip_data *irq_chip;
    187	struct regulator_bulk_data supplies[WCD938X_MAX_SUPPLY];
    188	struct snd_soc_jack *jack;
    189	unsigned long status_mask;
    190	s32 micb_ref[WCD938X_MAX_MICBIAS];
    191	s32 pullup_ref[WCD938X_MAX_MICBIAS];
    192	u32 hph_mode;
    193	u32 tx_mode[TX_ADC_MAX];
    194	int flyback_cur_det_disable;
    195	int ear_rx_path;
    196	int variant;
    197	int reset_gpio;
    198	struct gpio_desc *us_euro_gpio;
    199	u32 micb1_mv;
    200	u32 micb2_mv;
    201	u32 micb3_mv;
    202	u32 micb4_mv;
    203	int hphr_pdm_wd_int;
    204	int hphl_pdm_wd_int;
    205	int aux_pdm_wd_int;
    206	bool comp1_enable;
    207	bool comp2_enable;
    208	bool ldoh;
    209	bool bcs_dis;
    210};
    211
    212static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
    213static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(line_gain, 600, -3000);
    214static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000);
    215
    216struct wcd938x_mbhc_zdet_param {
    217	u16 ldo_ctl;
    218	u16 noff;
    219	u16 nshift;
    220	u16 btn5;
    221	u16 btn6;
    222	u16 btn7;
    223};
    224
    225static struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = {
    226	WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD938X_ANA_MBHC_MECH, 0x80),
    227	WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD938X_ANA_MBHC_MECH, 0x40),
    228	WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD938X_ANA_MBHC_MECH, 0x20),
    229	WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x30),
    230	WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, WCD938X_ANA_MBHC_ELECT, 0x08),
    231	WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F),
    232	WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, WCD938X_ANA_MBHC_MECH, 0x04),
    233	WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x10),
    234	WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x08),
    235	WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, WCD938X_ANA_MBHC_MECH, 0x01),
    236	WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, WCD938X_ANA_MBHC_ELECT, 0x06),
    237	WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, WCD938X_ANA_MBHC_ELECT, 0x80),
    238	WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F),
    239	WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, WCD938X_MBHC_NEW_CTL_1, 0x03),
    240	WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, WCD938X_MBHC_NEW_CTL_2, 0x03),
    241	WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x08),
    242	WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
    243	WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x20),
    244	WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x80),
    245	WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x40),
    246	WCD_MBHC_FIELD(WCD_MBHC_OCP_FSM_EN, WCD938X_HPH_OCP_CTL, 0x10),
    247	WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x07),
    248	WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, WCD938X_ANA_MBHC_ELECT, 0x70),
    249	WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0xFF),
    250	WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, WCD938X_ANA_MICB2, 0xC0),
    251	WCD_MBHC_FIELD(WCD_MBHC_HPH_CNP_WG_TIME, WCD938X_HPH_CNP_WG_TIME, 0xFF),
    252	WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, WCD938X_ANA_HPH, 0x40),
    253	WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, WCD938X_ANA_HPH, 0x80),
    254	WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, WCD938X_ANA_HPH, 0xC0),
    255	WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
    256	WCD_MBHC_FIELD(WCD_MBHC_ANC_DET_EN, WCD938X_MBHC_CTL_BCS, 0x02),
    257	WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x01),
    258	WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, WCD938X_MBHC_NEW_CTL_2, 0x70),
    259	WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x20),
    260	WCD_MBHC_FIELD(WCD_MBHC_HPHR_GND, WCD938X_HPH_PA_CTL2, 0x40),
    261	WCD_MBHC_FIELD(WCD_MBHC_HPHL_GND, WCD938X_HPH_PA_CTL2, 0x10),
    262	WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, WCD938X_HPH_L_TEST, 0x01),
    263	WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, WCD938X_HPH_R_TEST, 0x01),
    264	WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x80),
    265	WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x20),
    266	WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, WCD938X_MBHC_NEW_CTL_1, 0x08),
    267	WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, WCD938X_MBHC_NEW_FSM_STATUS, 0x40),
    268	WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, WCD938X_MBHC_NEW_FSM_STATUS, 0x80),
    269	WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, WCD938X_MBHC_NEW_ADC_RESULT, 0xFF),
    270	WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, WCD938X_ANA_MICB2, 0x3F),
    271	WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, WCD938X_MBHC_NEW_CTL_1, 0x10),
    272	WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, WCD938X_MBHC_NEW_CTL_1, 0x04),
    273	WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, WCD938X_ANA_MBHC_ZDET, 0x02),
    274};
    275
    276static const struct reg_default wcd938x_defaults[] = {
    277	{WCD938X_ANA_PAGE_REGISTER,                            0x00},
    278	{WCD938X_ANA_BIAS,                                     0x00},
    279	{WCD938X_ANA_RX_SUPPLIES,                              0x00},
    280	{WCD938X_ANA_HPH,                                      0x0C},
    281	{WCD938X_ANA_EAR,                                      0x00},
    282	{WCD938X_ANA_EAR_COMPANDER_CTL,                        0x02},
    283	{WCD938X_ANA_TX_CH1,                                   0x20},
    284	{WCD938X_ANA_TX_CH2,                                   0x00},
    285	{WCD938X_ANA_TX_CH3,                                   0x20},
    286	{WCD938X_ANA_TX_CH4,                                   0x00},
    287	{WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC,                 0x00},
    288	{WCD938X_ANA_MICB3_DSP_EN_LOGIC,                       0x00},
    289	{WCD938X_ANA_MBHC_MECH,                                0x39},
    290	{WCD938X_ANA_MBHC_ELECT,                               0x08},
    291	{WCD938X_ANA_MBHC_ZDET,                                0x00},
    292	{WCD938X_ANA_MBHC_RESULT_1,                            0x00},
    293	{WCD938X_ANA_MBHC_RESULT_2,                            0x00},
    294	{WCD938X_ANA_MBHC_RESULT_3,                            0x00},
    295	{WCD938X_ANA_MBHC_BTN0,                                0x00},
    296	{WCD938X_ANA_MBHC_BTN1,                                0x10},
    297	{WCD938X_ANA_MBHC_BTN2,                                0x20},
    298	{WCD938X_ANA_MBHC_BTN3,                                0x30},
    299	{WCD938X_ANA_MBHC_BTN4,                                0x40},
    300	{WCD938X_ANA_MBHC_BTN5,                                0x50},
    301	{WCD938X_ANA_MBHC_BTN6,                                0x60},
    302	{WCD938X_ANA_MBHC_BTN7,                                0x70},
    303	{WCD938X_ANA_MICB1,                                    0x10},
    304	{WCD938X_ANA_MICB2,                                    0x10},
    305	{WCD938X_ANA_MICB2_RAMP,                               0x00},
    306	{WCD938X_ANA_MICB3,                                    0x10},
    307	{WCD938X_ANA_MICB4,                                    0x10},
    308	{WCD938X_BIAS_CTL,                                     0x2A},
    309	{WCD938X_BIAS_VBG_FINE_ADJ,                            0x55},
    310	{WCD938X_LDOL_VDDCX_ADJUST,                            0x01},
    311	{WCD938X_LDOL_DISABLE_LDOL,                            0x00},
    312	{WCD938X_MBHC_CTL_CLK,                                 0x00},
    313	{WCD938X_MBHC_CTL_ANA,                                 0x00},
    314	{WCD938X_MBHC_CTL_SPARE_1,                             0x00},
    315	{WCD938X_MBHC_CTL_SPARE_2,                             0x00},
    316	{WCD938X_MBHC_CTL_BCS,                                 0x00},
    317	{WCD938X_MBHC_MOISTURE_DET_FSM_STATUS,                 0x00},
    318	{WCD938X_MBHC_TEST_CTL,                                0x00},
    319	{WCD938X_LDOH_MODE,                                    0x2B},
    320	{WCD938X_LDOH_BIAS,                                    0x68},
    321	{WCD938X_LDOH_STB_LOADS,                               0x00},
    322	{WCD938X_LDOH_SLOWRAMP,                                0x50},
    323	{WCD938X_MICB1_TEST_CTL_1,                             0x1A},
    324	{WCD938X_MICB1_TEST_CTL_2,                             0x00},
    325	{WCD938X_MICB1_TEST_CTL_3,                             0xA4},
    326	{WCD938X_MICB2_TEST_CTL_1,                             0x1A},
    327	{WCD938X_MICB2_TEST_CTL_2,                             0x00},
    328	{WCD938X_MICB2_TEST_CTL_3,                             0x24},
    329	{WCD938X_MICB3_TEST_CTL_1,                             0x1A},
    330	{WCD938X_MICB3_TEST_CTL_2,                             0x00},
    331	{WCD938X_MICB3_TEST_CTL_3,                             0xA4},
    332	{WCD938X_MICB4_TEST_CTL_1,                             0x1A},
    333	{WCD938X_MICB4_TEST_CTL_2,                             0x00},
    334	{WCD938X_MICB4_TEST_CTL_3,                             0xA4},
    335	{WCD938X_TX_COM_ADC_VCM,                               0x39},
    336	{WCD938X_TX_COM_BIAS_ATEST,                            0xE0},
    337	{WCD938X_TX_COM_SPARE1,                                0x00},
    338	{WCD938X_TX_COM_SPARE2,                                0x00},
    339	{WCD938X_TX_COM_TXFE_DIV_CTL,                          0x22},
    340	{WCD938X_TX_COM_TXFE_DIV_START,                        0x00},
    341	{WCD938X_TX_COM_SPARE3,                                0x00},
    342	{WCD938X_TX_COM_SPARE4,                                0x00},
    343	{WCD938X_TX_1_2_TEST_EN,                               0xCC},
    344	{WCD938X_TX_1_2_ADC_IB,                                0xE9},
    345	{WCD938X_TX_1_2_ATEST_REFCTL,                          0x0A},
    346	{WCD938X_TX_1_2_TEST_CTL,                              0x38},
    347	{WCD938X_TX_1_2_TEST_BLK_EN1,                          0xFF},
    348	{WCD938X_TX_1_2_TXFE1_CLKDIV,                          0x00},
    349	{WCD938X_TX_1_2_SAR2_ERR,                              0x00},
    350	{WCD938X_TX_1_2_SAR1_ERR,                              0x00},
    351	{WCD938X_TX_3_4_TEST_EN,                               0xCC},
    352	{WCD938X_TX_3_4_ADC_IB,                                0xE9},
    353	{WCD938X_TX_3_4_ATEST_REFCTL,                          0x0A},
    354	{WCD938X_TX_3_4_TEST_CTL,                              0x38},
    355	{WCD938X_TX_3_4_TEST_BLK_EN3,                          0xFF},
    356	{WCD938X_TX_3_4_TXFE3_CLKDIV,                          0x00},
    357	{WCD938X_TX_3_4_SAR4_ERR,                              0x00},
    358	{WCD938X_TX_3_4_SAR3_ERR,                              0x00},
    359	{WCD938X_TX_3_4_TEST_BLK_EN2,                          0xFB},
    360	{WCD938X_TX_3_4_TXFE2_CLKDIV,                          0x00},
    361	{WCD938X_TX_3_4_SPARE1,                                0x00},
    362	{WCD938X_TX_3_4_TEST_BLK_EN4,                          0xFB},
    363	{WCD938X_TX_3_4_TXFE4_CLKDIV,                          0x00},
    364	{WCD938X_TX_3_4_SPARE2,                                0x00},
    365	{WCD938X_CLASSH_MODE_1,                                0x40},
    366	{WCD938X_CLASSH_MODE_2,                                0x3A},
    367	{WCD938X_CLASSH_MODE_3,                                0x00},
    368	{WCD938X_CLASSH_CTRL_VCL_1,                            0x70},
    369	{WCD938X_CLASSH_CTRL_VCL_2,                            0x82},
    370	{WCD938X_CLASSH_CTRL_CCL_1,                            0x31},
    371	{WCD938X_CLASSH_CTRL_CCL_2,                            0x80},
    372	{WCD938X_CLASSH_CTRL_CCL_3,                            0x80},
    373	{WCD938X_CLASSH_CTRL_CCL_4,                            0x51},
    374	{WCD938X_CLASSH_CTRL_CCL_5,                            0x00},
    375	{WCD938X_CLASSH_BUCK_TMUX_A_D,                         0x00},
    376	{WCD938X_CLASSH_BUCK_SW_DRV_CNTL,                      0x77},
    377	{WCD938X_CLASSH_SPARE,                                 0x00},
    378	{WCD938X_FLYBACK_EN,                                   0x4E},
    379	{WCD938X_FLYBACK_VNEG_CTRL_1,                          0x0B},
    380	{WCD938X_FLYBACK_VNEG_CTRL_2,                          0x45},
    381	{WCD938X_FLYBACK_VNEG_CTRL_3,                          0x74},
    382	{WCD938X_FLYBACK_VNEG_CTRL_4,                          0x7F},
    383	{WCD938X_FLYBACK_VNEG_CTRL_5,                          0x83},
    384	{WCD938X_FLYBACK_VNEG_CTRL_6,                          0x98},
    385	{WCD938X_FLYBACK_VNEG_CTRL_7,                          0xA9},
    386	{WCD938X_FLYBACK_VNEG_CTRL_8,                          0x68},
    387	{WCD938X_FLYBACK_VNEG_CTRL_9,                          0x64},
    388	{WCD938X_FLYBACK_VNEGDAC_CTRL_1,                       0xED},
    389	{WCD938X_FLYBACK_VNEGDAC_CTRL_2,                       0xF0},
    390	{WCD938X_FLYBACK_VNEGDAC_CTRL_3,                       0xA6},
    391	{WCD938X_FLYBACK_CTRL_1,                               0x65},
    392	{WCD938X_FLYBACK_TEST_CTL,                             0x00},
    393	{WCD938X_RX_AUX_SW_CTL,                                0x00},
    394	{WCD938X_RX_PA_AUX_IN_CONN,                            0x01},
    395	{WCD938X_RX_TIMER_DIV,                                 0x32},
    396	{WCD938X_RX_OCP_CTL,                                   0x1F},
    397	{WCD938X_RX_OCP_COUNT,                                 0x77},
    398	{WCD938X_RX_BIAS_EAR_DAC,                              0xA0},
    399	{WCD938X_RX_BIAS_EAR_AMP,                              0xAA},
    400	{WCD938X_RX_BIAS_HPH_LDO,                              0xA9},
    401	{WCD938X_RX_BIAS_HPH_PA,                               0xAA},
    402	{WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2,                    0x8A},
    403	{WCD938X_RX_BIAS_HPH_RDAC_LDO,                         0x88},
    404	{WCD938X_RX_BIAS_HPH_CNP1,                             0x82},
    405	{WCD938X_RX_BIAS_HPH_LOWPOWER,                         0x82},
    406	{WCD938X_RX_BIAS_AUX_DAC,                              0xA0},
    407	{WCD938X_RX_BIAS_AUX_AMP,                              0xAA},
    408	{WCD938X_RX_BIAS_VNEGDAC_BLEEDER,                      0x50},
    409	{WCD938X_RX_BIAS_MISC,                                 0x00},
    410	{WCD938X_RX_BIAS_BUCK_RST,                             0x08},
    411	{WCD938X_RX_BIAS_BUCK_VREF_ERRAMP,                     0x44},
    412	{WCD938X_RX_BIAS_FLYB_ERRAMP,                          0x40},
    413	{WCD938X_RX_BIAS_FLYB_BUFF,                            0xAA},
    414	{WCD938X_RX_BIAS_FLYB_MID_RST,                         0x14},
    415	{WCD938X_HPH_L_STATUS,                                 0x04},
    416	{WCD938X_HPH_R_STATUS,                                 0x04},
    417	{WCD938X_HPH_CNP_EN,                                   0x80},
    418	{WCD938X_HPH_CNP_WG_CTL,                               0x9A},
    419	{WCD938X_HPH_CNP_WG_TIME,                              0x14},
    420	{WCD938X_HPH_OCP_CTL,                                  0x28},
    421	{WCD938X_HPH_AUTO_CHOP,                                0x16},
    422	{WCD938X_HPH_CHOP_CTL,                                 0x83},
    423	{WCD938X_HPH_PA_CTL1,                                  0x46},
    424	{WCD938X_HPH_PA_CTL2,                                  0x50},
    425	{WCD938X_HPH_L_EN,                                     0x80},
    426	{WCD938X_HPH_L_TEST,                                   0xE0},
    427	{WCD938X_HPH_L_ATEST,                                  0x50},
    428	{WCD938X_HPH_R_EN,                                     0x80},
    429	{WCD938X_HPH_R_TEST,                                   0xE0},
    430	{WCD938X_HPH_R_ATEST,                                  0x54},
    431	{WCD938X_HPH_RDAC_CLK_CTL1,                            0x99},
    432	{WCD938X_HPH_RDAC_CLK_CTL2,                            0x9B},
    433	{WCD938X_HPH_RDAC_LDO_CTL,                             0x33},
    434	{WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL,                     0x00},
    435	{WCD938X_HPH_REFBUFF_UHQA_CTL,                         0x68},
    436	{WCD938X_HPH_REFBUFF_LP_CTL,                           0x0E},
    437	{WCD938X_HPH_L_DAC_CTL,                                0x20},
    438	{WCD938X_HPH_R_DAC_CTL,                                0x20},
    439	{WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL,               0x55},
    440	{WCD938X_HPH_SURGE_HPHLR_SURGE_EN,                     0x19},
    441	{WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1,                  0xA0},
    442	{WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS,                 0x00},
    443	{WCD938X_EAR_EAR_EN_REG,                               0x22},
    444	{WCD938X_EAR_EAR_PA_CON,                               0x44},
    445	{WCD938X_EAR_EAR_SP_CON,                               0xDB},
    446	{WCD938X_EAR_EAR_DAC_CON,                              0x80},
    447	{WCD938X_EAR_EAR_CNP_FSM_CON,                          0xB2},
    448	{WCD938X_EAR_TEST_CTL,                                 0x00},
    449	{WCD938X_EAR_STATUS_REG_1,                             0x00},
    450	{WCD938X_EAR_STATUS_REG_2,                             0x08},
    451	{WCD938X_ANA_NEW_PAGE_REGISTER,                        0x00},
    452	{WCD938X_HPH_NEW_ANA_HPH2,                             0x00},
    453	{WCD938X_HPH_NEW_ANA_HPH3,                             0x00},
    454	{WCD938X_SLEEP_CTL,                                    0x16},
    455	{WCD938X_SLEEP_WATCHDOG_CTL,                           0x00},
    456	{WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL,                 0x00},
    457	{WCD938X_MBHC_NEW_CTL_1,                               0x02},
    458	{WCD938X_MBHC_NEW_CTL_2,                               0x05},
    459	{WCD938X_MBHC_NEW_PLUG_DETECT_CTL,                     0xE9},
    460	{WCD938X_MBHC_NEW_ZDET_ANA_CTL,                        0x0F},
    461	{WCD938X_MBHC_NEW_ZDET_RAMP_CTL,                       0x00},
    462	{WCD938X_MBHC_NEW_FSM_STATUS,                          0x00},
    463	{WCD938X_MBHC_NEW_ADC_RESULT,                          0x00},
    464	{WCD938X_TX_NEW_AMIC_MUX_CFG,                          0x00},
    465	{WCD938X_AUX_AUXPA,                                    0x00},
    466	{WCD938X_LDORXTX_MODE,                                 0x0C},
    467	{WCD938X_LDORXTX_CONFIG,                               0x10},
    468	{WCD938X_DIE_CRACK_DIE_CRK_DET_EN,                     0x00},
    469	{WCD938X_DIE_CRACK_DIE_CRK_DET_OUT,                    0x00},
    470	{WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL,                    0x40},
    471	{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L,                   0x81},
    472	{WCD938X_HPH_NEW_INT_RDAC_VREF_CTL,                    0x10},
    473	{WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL,                0x00},
    474	{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,                   0x81},
    475	{WCD938X_HPH_NEW_INT_PA_MISC1,                         0x22},
    476	{WCD938X_HPH_NEW_INT_PA_MISC2,                         0x00},
    477	{WCD938X_HPH_NEW_INT_PA_RDAC_MISC,                     0x00},
    478	{WCD938X_HPH_NEW_INT_HPH_TIMER1,                       0xFE},
    479	{WCD938X_HPH_NEW_INT_HPH_TIMER2,                       0x02},
    480	{WCD938X_HPH_NEW_INT_HPH_TIMER3,                       0x4E},
    481	{WCD938X_HPH_NEW_INT_HPH_TIMER4,                       0x54},
    482	{WCD938X_HPH_NEW_INT_PA_RDAC_MISC2,                    0x00},
    483	{WCD938X_HPH_NEW_INT_PA_RDAC_MISC3,                    0x00},
    484	{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW,               0x90},
    485	{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW,               0x90},
    486	{WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI,              0x62},
    487	{WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP,                 0x01},
    488	{WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP,                   0x11},
    489	{WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL,            0x57},
    490	{WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL,       0x01},
    491	{WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT,                0x00},
    492	{WCD938X_MBHC_NEW_INT_SPARE_2,                         0x00},
    493	{WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON,                  0xA8},
    494	{WCD938X_EAR_INT_NEW_CNP_VCM_CON1,                     0x42},
    495	{WCD938X_EAR_INT_NEW_CNP_VCM_CON2,                     0x22},
    496	{WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS,                 0x00},
    497	{WCD938X_AUX_INT_EN_REG,                               0x00},
    498	{WCD938X_AUX_INT_PA_CTRL,                              0x06},
    499	{WCD938X_AUX_INT_SP_CTRL,                              0xD2},
    500	{WCD938X_AUX_INT_DAC_CTRL,                             0x80},
    501	{WCD938X_AUX_INT_CLK_CTRL,                             0x50},
    502	{WCD938X_AUX_INT_TEST_CTRL,                            0x00},
    503	{WCD938X_AUX_INT_STATUS_REG,                           0x00},
    504	{WCD938X_AUX_INT_MISC,                                 0x00},
    505	{WCD938X_LDORXTX_INT_BIAS,                             0x6E},
    506	{WCD938X_LDORXTX_INT_STB_LOADS_DTEST,                  0x50},
    507	{WCD938X_LDORXTX_INT_TEST0,                            0x1C},
    508	{WCD938X_LDORXTX_INT_STARTUP_TIMER,                    0xFF},
    509	{WCD938X_LDORXTX_INT_TEST1,                            0x1F},
    510	{WCD938X_LDORXTX_INT_STATUS,                           0x00},
    511	{WCD938X_SLEEP_INT_WATCHDOG_CTL_1,                     0x0A},
    512	{WCD938X_SLEEP_INT_WATCHDOG_CTL_2,                     0x0A},
    513	{WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1,               0x02},
    514	{WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2,               0x60},
    515	{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2,               0xFF},
    516	{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1,               0x7F},
    517	{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0,               0x3F},
    518	{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M,          0x1F},
    519	{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M,          0x0F},
    520	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1,          0xD7},
    521	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0,            0xC8},
    522	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP,           0xC6},
    523	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1,      0xD5},
    524	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0,        0xCA},
    525	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP,       0x05},
    526	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0,    0xA5},
    527	{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP,       0x13},
    528	{WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1,             0x88},
    529	{WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP,            0x42},
    530	{WCD938X_TX_COM_NEW_INT_TXADC_INT_L2,                  0xFF},
    531	{WCD938X_TX_COM_NEW_INT_TXADC_INT_L1,                  0x64},
    532	{WCD938X_TX_COM_NEW_INT_TXADC_INT_L0,                  0x64},
    533	{WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP,                 0x77},
    534	{WCD938X_DIGITAL_PAGE_REGISTER,                        0x00},
    535	{WCD938X_DIGITAL_CHIP_ID0,                             0x00},
    536	{WCD938X_DIGITAL_CHIP_ID1,                             0x00},
    537	{WCD938X_DIGITAL_CHIP_ID2,                             0x0D},
    538	{WCD938X_DIGITAL_CHIP_ID3,                             0x01},
    539	{WCD938X_DIGITAL_SWR_TX_CLK_RATE,                      0x00},
    540	{WCD938X_DIGITAL_CDC_RST_CTL,                          0x03},
    541	{WCD938X_DIGITAL_TOP_CLK_CFG,                          0x00},
    542	{WCD938X_DIGITAL_CDC_ANA_CLK_CTL,                      0x00},
    543	{WCD938X_DIGITAL_CDC_DIG_CLK_CTL,                      0xF0},
    544	{WCD938X_DIGITAL_SWR_RST_EN,                           0x00},
    545	{WCD938X_DIGITAL_CDC_PATH_MODE,                        0x55},
    546	{WCD938X_DIGITAL_CDC_RX_RST,                           0x00},
    547	{WCD938X_DIGITAL_CDC_RX0_CTL,                          0xFC},
    548	{WCD938X_DIGITAL_CDC_RX1_CTL,                          0xFC},
    549	{WCD938X_DIGITAL_CDC_RX2_CTL,                          0xFC},
    550	{WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,                  0x00},
    551	{WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,                  0x00},
    552	{WCD938X_DIGITAL_CDC_COMP_CTL_0,                       0x00},
    553	{WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL,                   0x1E},
    554	{WCD938X_DIGITAL_CDC_HPH_DSM_A1_0,                     0x00},
    555	{WCD938X_DIGITAL_CDC_HPH_DSM_A1_1,                     0x01},
    556	{WCD938X_DIGITAL_CDC_HPH_DSM_A2_0,                     0x63},
    557	{WCD938X_DIGITAL_CDC_HPH_DSM_A2_1,                     0x04},
    558	{WCD938X_DIGITAL_CDC_HPH_DSM_A3_0,                     0xAC},
    559	{WCD938X_DIGITAL_CDC_HPH_DSM_A3_1,                     0x04},
    560	{WCD938X_DIGITAL_CDC_HPH_DSM_A4_0,                     0x1A},
    561	{WCD938X_DIGITAL_CDC_HPH_DSM_A4_1,                     0x03},
    562	{WCD938X_DIGITAL_CDC_HPH_DSM_A5_0,                     0xBC},
    563	{WCD938X_DIGITAL_CDC_HPH_DSM_A5_1,                     0x02},
    564	{WCD938X_DIGITAL_CDC_HPH_DSM_A6_0,                     0xC7},
    565	{WCD938X_DIGITAL_CDC_HPH_DSM_A7_0,                     0xF8},
    566	{WCD938X_DIGITAL_CDC_HPH_DSM_C_0,                      0x47},
    567	{WCD938X_DIGITAL_CDC_HPH_DSM_C_1,                      0x43},
    568	{WCD938X_DIGITAL_CDC_HPH_DSM_C_2,                      0xB1},
    569	{WCD938X_DIGITAL_CDC_HPH_DSM_C_3,                      0x17},
    570	{WCD938X_DIGITAL_CDC_HPH_DSM_R1,                       0x4D},
    571	{WCD938X_DIGITAL_CDC_HPH_DSM_R2,                       0x29},
    572	{WCD938X_DIGITAL_CDC_HPH_DSM_R3,                       0x34},
    573	{WCD938X_DIGITAL_CDC_HPH_DSM_R4,                       0x59},
    574	{WCD938X_DIGITAL_CDC_HPH_DSM_R5,                       0x66},
    575	{WCD938X_DIGITAL_CDC_HPH_DSM_R6,                       0x87},
    576	{WCD938X_DIGITAL_CDC_HPH_DSM_R7,                       0x64},
    577	{WCD938X_DIGITAL_CDC_AUX_DSM_A1_0,                     0x00},
    578	{WCD938X_DIGITAL_CDC_AUX_DSM_A1_1,                     0x01},
    579	{WCD938X_DIGITAL_CDC_AUX_DSM_A2_0,                     0x96},
    580	{WCD938X_DIGITAL_CDC_AUX_DSM_A2_1,                     0x09},
    581	{WCD938X_DIGITAL_CDC_AUX_DSM_A3_0,                     0xAB},
    582	{WCD938X_DIGITAL_CDC_AUX_DSM_A3_1,                     0x05},
    583	{WCD938X_DIGITAL_CDC_AUX_DSM_A4_0,                     0x1C},
    584	{WCD938X_DIGITAL_CDC_AUX_DSM_A4_1,                     0x02},
    585	{WCD938X_DIGITAL_CDC_AUX_DSM_A5_0,                     0x17},
    586	{WCD938X_DIGITAL_CDC_AUX_DSM_A5_1,                     0x02},
    587	{WCD938X_DIGITAL_CDC_AUX_DSM_A6_0,                     0xAA},
    588	{WCD938X_DIGITAL_CDC_AUX_DSM_A7_0,                     0xE3},
    589	{WCD938X_DIGITAL_CDC_AUX_DSM_C_0,                      0x69},
    590	{WCD938X_DIGITAL_CDC_AUX_DSM_C_1,                      0x54},
    591	{WCD938X_DIGITAL_CDC_AUX_DSM_C_2,                      0x02},
    592	{WCD938X_DIGITAL_CDC_AUX_DSM_C_3,                      0x15},
    593	{WCD938X_DIGITAL_CDC_AUX_DSM_R1,                       0xA4},
    594	{WCD938X_DIGITAL_CDC_AUX_DSM_R2,                       0xB5},
    595	{WCD938X_DIGITAL_CDC_AUX_DSM_R3,                       0x86},
    596	{WCD938X_DIGITAL_CDC_AUX_DSM_R4,                       0x85},
    597	{WCD938X_DIGITAL_CDC_AUX_DSM_R5,                       0xAA},
    598	{WCD938X_DIGITAL_CDC_AUX_DSM_R6,                       0xE2},
    599	{WCD938X_DIGITAL_CDC_AUX_DSM_R7,                       0x62},
    600	{WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0,                    0x55},
    601	{WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1,                    0xA9},
    602	{WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0,                   0x3D},
    603	{WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1,                   0x2E},
    604	{WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2,                   0x01},
    605	{WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0,                   0x00},
    606	{WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1,                   0xFC},
    607	{WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2,                   0x01},
    608	{WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,                     0x00},
    609	{WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,                     0x00},
    610	{WCD938X_DIGITAL_CDC_EAR_PATH_CTL,                     0x00},
    611	{WCD938X_DIGITAL_CDC_SWR_CLH,                          0x00},
    612	{WCD938X_DIGITAL_SWR_CLH_BYP,                          0x00},
    613	{WCD938X_DIGITAL_CDC_TX0_CTL,                          0x68},
    614	{WCD938X_DIGITAL_CDC_TX1_CTL,                          0x68},
    615	{WCD938X_DIGITAL_CDC_TX2_CTL,                          0x68},
    616	{WCD938X_DIGITAL_CDC_TX_RST,                           0x00},
    617	{WCD938X_DIGITAL_CDC_REQ_CTL,                          0x01},
    618	{WCD938X_DIGITAL_CDC_RST,                              0x00},
    619	{WCD938X_DIGITAL_CDC_AMIC_CTL,                         0x0F},
    620	{WCD938X_DIGITAL_CDC_DMIC_CTL,                         0x04},
    621	{WCD938X_DIGITAL_CDC_DMIC1_CTL,                        0x01},
    622	{WCD938X_DIGITAL_CDC_DMIC2_CTL,                        0x01},
    623	{WCD938X_DIGITAL_CDC_DMIC3_CTL,                        0x01},
    624	{WCD938X_DIGITAL_CDC_DMIC4_CTL,                        0x01},
    625	{WCD938X_DIGITAL_EFUSE_PRG_CTL,                        0x00},
    626	{WCD938X_DIGITAL_EFUSE_CTL,                            0x2B},
    627	{WCD938X_DIGITAL_CDC_DMIC_RATE_1_2,                    0x11},
    628	{WCD938X_DIGITAL_CDC_DMIC_RATE_3_4,                    0x11},
    629	{WCD938X_DIGITAL_PDM_WD_CTL0,                          0x00},
    630	{WCD938X_DIGITAL_PDM_WD_CTL1,                          0x00},
    631	{WCD938X_DIGITAL_PDM_WD_CTL2,                          0x00},
    632	{WCD938X_DIGITAL_INTR_MODE,                            0x00},
    633	{WCD938X_DIGITAL_INTR_MASK_0,                          0xFF},
    634	{WCD938X_DIGITAL_INTR_MASK_1,                          0xFF},
    635	{WCD938X_DIGITAL_INTR_MASK_2,                          0x3F},
    636	{WCD938X_DIGITAL_INTR_STATUS_0,                        0x00},
    637	{WCD938X_DIGITAL_INTR_STATUS_1,                        0x00},
    638	{WCD938X_DIGITAL_INTR_STATUS_2,                        0x00},
    639	{WCD938X_DIGITAL_INTR_CLEAR_0,                         0x00},
    640	{WCD938X_DIGITAL_INTR_CLEAR_1,                         0x00},
    641	{WCD938X_DIGITAL_INTR_CLEAR_2,                         0x00},
    642	{WCD938X_DIGITAL_INTR_LEVEL_0,                         0x00},
    643	{WCD938X_DIGITAL_INTR_LEVEL_1,                         0x00},
    644	{WCD938X_DIGITAL_INTR_LEVEL_2,                         0x00},
    645	{WCD938X_DIGITAL_INTR_SET_0,                           0x00},
    646	{WCD938X_DIGITAL_INTR_SET_1,                           0x00},
    647	{WCD938X_DIGITAL_INTR_SET_2,                           0x00},
    648	{WCD938X_DIGITAL_INTR_TEST_0,                          0x00},
    649	{WCD938X_DIGITAL_INTR_TEST_1,                          0x00},
    650	{WCD938X_DIGITAL_INTR_TEST_2,                          0x00},
    651	{WCD938X_DIGITAL_TX_MODE_DBG_EN,                       0x00},
    652	{WCD938X_DIGITAL_TX_MODE_DBG_0_1,                      0x00},
    653	{WCD938X_DIGITAL_TX_MODE_DBG_2_3,                      0x00},
    654	{WCD938X_DIGITAL_LB_IN_SEL_CTL,                        0x00},
    655	{WCD938X_DIGITAL_LOOP_BACK_MODE,                       0x00},
    656	{WCD938X_DIGITAL_SWR_DAC_TEST,                         0x00},
    657	{WCD938X_DIGITAL_SWR_HM_TEST_RX_0,                     0x40},
    658	{WCD938X_DIGITAL_SWR_HM_TEST_TX_0,                     0x40},
    659	{WCD938X_DIGITAL_SWR_HM_TEST_RX_1,                     0x00},
    660	{WCD938X_DIGITAL_SWR_HM_TEST_TX_1,                     0x00},
    661	{WCD938X_DIGITAL_SWR_HM_TEST_TX_2,                     0x00},
    662	{WCD938X_DIGITAL_SWR_HM_TEST_0,                        0x00},
    663	{WCD938X_DIGITAL_SWR_HM_TEST_1,                        0x00},
    664	{WCD938X_DIGITAL_PAD_CTL_SWR_0,                        0x8F},
    665	{WCD938X_DIGITAL_PAD_CTL_SWR_1,                        0x06},
    666	{WCD938X_DIGITAL_I2C_CTL,                              0x00},
    667	{WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE,                0x00},
    668	{WCD938X_DIGITAL_EFUSE_TEST_CTL_0,                     0x00},
    669	{WCD938X_DIGITAL_EFUSE_TEST_CTL_1,                     0x00},
    670	{WCD938X_DIGITAL_EFUSE_T_DATA_0,                       0x00},
    671	{WCD938X_DIGITAL_EFUSE_T_DATA_1,                       0x00},
    672	{WCD938X_DIGITAL_PAD_CTL_PDM_RX0,                      0xF1},
    673	{WCD938X_DIGITAL_PAD_CTL_PDM_RX1,                      0xF1},
    674	{WCD938X_DIGITAL_PAD_CTL_PDM_TX0,                      0xF1},
    675	{WCD938X_DIGITAL_PAD_CTL_PDM_TX1,                      0xF1},
    676	{WCD938X_DIGITAL_PAD_CTL_PDM_TX2,                      0xF1},
    677	{WCD938X_DIGITAL_PAD_INP_DIS_0,                        0x00},
    678	{WCD938X_DIGITAL_PAD_INP_DIS_1,                        0x00},
    679	{WCD938X_DIGITAL_DRIVE_STRENGTH_0,                     0x00},
    680	{WCD938X_DIGITAL_DRIVE_STRENGTH_1,                     0x00},
    681	{WCD938X_DIGITAL_DRIVE_STRENGTH_2,                     0x00},
    682	{WCD938X_DIGITAL_RX_DATA_EDGE_CTL,                     0x1F},
    683	{WCD938X_DIGITAL_TX_DATA_EDGE_CTL,                     0x80},
    684	{WCD938X_DIGITAL_GPIO_MODE,                            0x00},
    685	{WCD938X_DIGITAL_PIN_CTL_OE,                           0x00},
    686	{WCD938X_DIGITAL_PIN_CTL_DATA_0,                       0x00},
    687	{WCD938X_DIGITAL_PIN_CTL_DATA_1,                       0x00},
    688	{WCD938X_DIGITAL_PIN_STATUS_0,                         0x00},
    689	{WCD938X_DIGITAL_PIN_STATUS_1,                         0x00},
    690	{WCD938X_DIGITAL_DIG_DEBUG_CTL,                        0x00},
    691	{WCD938X_DIGITAL_DIG_DEBUG_EN,                         0x00},
    692	{WCD938X_DIGITAL_ANA_CSR_DBG_ADD,                      0x00},
    693	{WCD938X_DIGITAL_ANA_CSR_DBG_CTL,                      0x48},
    694	{WCD938X_DIGITAL_SSP_DBG,                              0x00},
    695	{WCD938X_DIGITAL_MODE_STATUS_0,                        0x00},
    696	{WCD938X_DIGITAL_MODE_STATUS_1,                        0x00},
    697	{WCD938X_DIGITAL_SPARE_0,                              0x00},
    698	{WCD938X_DIGITAL_SPARE_1,                              0x00},
    699	{WCD938X_DIGITAL_SPARE_2,                              0x00},
    700	{WCD938X_DIGITAL_EFUSE_REG_0,                          0x00},
    701	{WCD938X_DIGITAL_EFUSE_REG_1,                          0xFF},
    702	{WCD938X_DIGITAL_EFUSE_REG_2,                          0xFF},
    703	{WCD938X_DIGITAL_EFUSE_REG_3,                          0xFF},
    704	{WCD938X_DIGITAL_EFUSE_REG_4,                          0xFF},
    705	{WCD938X_DIGITAL_EFUSE_REG_5,                          0xFF},
    706	{WCD938X_DIGITAL_EFUSE_REG_6,                          0xFF},
    707	{WCD938X_DIGITAL_EFUSE_REG_7,                          0xFF},
    708	{WCD938X_DIGITAL_EFUSE_REG_8,                          0xFF},
    709	{WCD938X_DIGITAL_EFUSE_REG_9,                          0xFF},
    710	{WCD938X_DIGITAL_EFUSE_REG_10,                         0xFF},
    711	{WCD938X_DIGITAL_EFUSE_REG_11,                         0xFF},
    712	{WCD938X_DIGITAL_EFUSE_REG_12,                         0xFF},
    713	{WCD938X_DIGITAL_EFUSE_REG_13,                         0xFF},
    714	{WCD938X_DIGITAL_EFUSE_REG_14,                         0xFF},
    715	{WCD938X_DIGITAL_EFUSE_REG_15,                         0xFF},
    716	{WCD938X_DIGITAL_EFUSE_REG_16,                         0xFF},
    717	{WCD938X_DIGITAL_EFUSE_REG_17,                         0xFF},
    718	{WCD938X_DIGITAL_EFUSE_REG_18,                         0xFF},
    719	{WCD938X_DIGITAL_EFUSE_REG_19,                         0xFF},
    720	{WCD938X_DIGITAL_EFUSE_REG_20,                         0x0E},
    721	{WCD938X_DIGITAL_EFUSE_REG_21,                         0x00},
    722	{WCD938X_DIGITAL_EFUSE_REG_22,                         0x00},
    723	{WCD938X_DIGITAL_EFUSE_REG_23,                         0xF8},
    724	{WCD938X_DIGITAL_EFUSE_REG_24,                         0x16},
    725	{WCD938X_DIGITAL_EFUSE_REG_25,                         0x00},
    726	{WCD938X_DIGITAL_EFUSE_REG_26,                         0x00},
    727	{WCD938X_DIGITAL_EFUSE_REG_27,                         0x00},
    728	{WCD938X_DIGITAL_EFUSE_REG_28,                         0x00},
    729	{WCD938X_DIGITAL_EFUSE_REG_29,                         0x00},
    730	{WCD938X_DIGITAL_EFUSE_REG_30,                         0x00},
    731	{WCD938X_DIGITAL_EFUSE_REG_31,                         0x00},
    732	{WCD938X_DIGITAL_TX_REQ_FB_CTL_0,                      0x88},
    733	{WCD938X_DIGITAL_TX_REQ_FB_CTL_1,                      0x88},
    734	{WCD938X_DIGITAL_TX_REQ_FB_CTL_2,                      0x88},
    735	{WCD938X_DIGITAL_TX_REQ_FB_CTL_3,                      0x88},
    736	{WCD938X_DIGITAL_TX_REQ_FB_CTL_4,                      0x88},
    737	{WCD938X_DIGITAL_DEM_BYPASS_DATA0,                     0x55},
    738	{WCD938X_DIGITAL_DEM_BYPASS_DATA1,                     0x55},
    739	{WCD938X_DIGITAL_DEM_BYPASS_DATA2,                     0x55},
    740	{WCD938X_DIGITAL_DEM_BYPASS_DATA3,                     0x01},
    741};
    742
    743static bool wcd938x_rdwr_register(struct device *dev, unsigned int reg)
    744{
    745	switch (reg) {
    746	case WCD938X_ANA_PAGE_REGISTER:
    747	case WCD938X_ANA_BIAS:
    748	case WCD938X_ANA_RX_SUPPLIES:
    749	case WCD938X_ANA_HPH:
    750	case WCD938X_ANA_EAR:
    751	case WCD938X_ANA_EAR_COMPANDER_CTL:
    752	case WCD938X_ANA_TX_CH1:
    753	case WCD938X_ANA_TX_CH2:
    754	case WCD938X_ANA_TX_CH3:
    755	case WCD938X_ANA_TX_CH4:
    756	case WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC:
    757	case WCD938X_ANA_MICB3_DSP_EN_LOGIC:
    758	case WCD938X_ANA_MBHC_MECH:
    759	case WCD938X_ANA_MBHC_ELECT:
    760	case WCD938X_ANA_MBHC_ZDET:
    761	case WCD938X_ANA_MBHC_BTN0:
    762	case WCD938X_ANA_MBHC_BTN1:
    763	case WCD938X_ANA_MBHC_BTN2:
    764	case WCD938X_ANA_MBHC_BTN3:
    765	case WCD938X_ANA_MBHC_BTN4:
    766	case WCD938X_ANA_MBHC_BTN5:
    767	case WCD938X_ANA_MBHC_BTN6:
    768	case WCD938X_ANA_MBHC_BTN7:
    769	case WCD938X_ANA_MICB1:
    770	case WCD938X_ANA_MICB2:
    771	case WCD938X_ANA_MICB2_RAMP:
    772	case WCD938X_ANA_MICB3:
    773	case WCD938X_ANA_MICB4:
    774	case WCD938X_BIAS_CTL:
    775	case WCD938X_BIAS_VBG_FINE_ADJ:
    776	case WCD938X_LDOL_VDDCX_ADJUST:
    777	case WCD938X_LDOL_DISABLE_LDOL:
    778	case WCD938X_MBHC_CTL_CLK:
    779	case WCD938X_MBHC_CTL_ANA:
    780	case WCD938X_MBHC_CTL_SPARE_1:
    781	case WCD938X_MBHC_CTL_SPARE_2:
    782	case WCD938X_MBHC_CTL_BCS:
    783	case WCD938X_MBHC_TEST_CTL:
    784	case WCD938X_LDOH_MODE:
    785	case WCD938X_LDOH_BIAS:
    786	case WCD938X_LDOH_STB_LOADS:
    787	case WCD938X_LDOH_SLOWRAMP:
    788	case WCD938X_MICB1_TEST_CTL_1:
    789	case WCD938X_MICB1_TEST_CTL_2:
    790	case WCD938X_MICB1_TEST_CTL_3:
    791	case WCD938X_MICB2_TEST_CTL_1:
    792	case WCD938X_MICB2_TEST_CTL_2:
    793	case WCD938X_MICB2_TEST_CTL_3:
    794	case WCD938X_MICB3_TEST_CTL_1:
    795	case WCD938X_MICB3_TEST_CTL_2:
    796	case WCD938X_MICB3_TEST_CTL_3:
    797	case WCD938X_MICB4_TEST_CTL_1:
    798	case WCD938X_MICB4_TEST_CTL_2:
    799	case WCD938X_MICB4_TEST_CTL_3:
    800	case WCD938X_TX_COM_ADC_VCM:
    801	case WCD938X_TX_COM_BIAS_ATEST:
    802	case WCD938X_TX_COM_SPARE1:
    803	case WCD938X_TX_COM_SPARE2:
    804	case WCD938X_TX_COM_TXFE_DIV_CTL:
    805	case WCD938X_TX_COM_TXFE_DIV_START:
    806	case WCD938X_TX_COM_SPARE3:
    807	case WCD938X_TX_COM_SPARE4:
    808	case WCD938X_TX_1_2_TEST_EN:
    809	case WCD938X_TX_1_2_ADC_IB:
    810	case WCD938X_TX_1_2_ATEST_REFCTL:
    811	case WCD938X_TX_1_2_TEST_CTL:
    812	case WCD938X_TX_1_2_TEST_BLK_EN1:
    813	case WCD938X_TX_1_2_TXFE1_CLKDIV:
    814	case WCD938X_TX_3_4_TEST_EN:
    815	case WCD938X_TX_3_4_ADC_IB:
    816	case WCD938X_TX_3_4_ATEST_REFCTL:
    817	case WCD938X_TX_3_4_TEST_CTL:
    818	case WCD938X_TX_3_4_TEST_BLK_EN3:
    819	case WCD938X_TX_3_4_TXFE3_CLKDIV:
    820	case WCD938X_TX_3_4_TEST_BLK_EN2:
    821	case WCD938X_TX_3_4_TXFE2_CLKDIV:
    822	case WCD938X_TX_3_4_SPARE1:
    823	case WCD938X_TX_3_4_TEST_BLK_EN4:
    824	case WCD938X_TX_3_4_TXFE4_CLKDIV:
    825	case WCD938X_TX_3_4_SPARE2:
    826	case WCD938X_CLASSH_MODE_1:
    827	case WCD938X_CLASSH_MODE_2:
    828	case WCD938X_CLASSH_MODE_3:
    829	case WCD938X_CLASSH_CTRL_VCL_1:
    830	case WCD938X_CLASSH_CTRL_VCL_2:
    831	case WCD938X_CLASSH_CTRL_CCL_1:
    832	case WCD938X_CLASSH_CTRL_CCL_2:
    833	case WCD938X_CLASSH_CTRL_CCL_3:
    834	case WCD938X_CLASSH_CTRL_CCL_4:
    835	case WCD938X_CLASSH_CTRL_CCL_5:
    836	case WCD938X_CLASSH_BUCK_TMUX_A_D:
    837	case WCD938X_CLASSH_BUCK_SW_DRV_CNTL:
    838	case WCD938X_CLASSH_SPARE:
    839	case WCD938X_FLYBACK_EN:
    840	case WCD938X_FLYBACK_VNEG_CTRL_1:
    841	case WCD938X_FLYBACK_VNEG_CTRL_2:
    842	case WCD938X_FLYBACK_VNEG_CTRL_3:
    843	case WCD938X_FLYBACK_VNEG_CTRL_4:
    844	case WCD938X_FLYBACK_VNEG_CTRL_5:
    845	case WCD938X_FLYBACK_VNEG_CTRL_6:
    846	case WCD938X_FLYBACK_VNEG_CTRL_7:
    847	case WCD938X_FLYBACK_VNEG_CTRL_8:
    848	case WCD938X_FLYBACK_VNEG_CTRL_9:
    849	case WCD938X_FLYBACK_VNEGDAC_CTRL_1:
    850	case WCD938X_FLYBACK_VNEGDAC_CTRL_2:
    851	case WCD938X_FLYBACK_VNEGDAC_CTRL_3:
    852	case WCD938X_FLYBACK_CTRL_1:
    853	case WCD938X_FLYBACK_TEST_CTL:
    854	case WCD938X_RX_AUX_SW_CTL:
    855	case WCD938X_RX_PA_AUX_IN_CONN:
    856	case WCD938X_RX_TIMER_DIV:
    857	case WCD938X_RX_OCP_CTL:
    858	case WCD938X_RX_OCP_COUNT:
    859	case WCD938X_RX_BIAS_EAR_DAC:
    860	case WCD938X_RX_BIAS_EAR_AMP:
    861	case WCD938X_RX_BIAS_HPH_LDO:
    862	case WCD938X_RX_BIAS_HPH_PA:
    863	case WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2:
    864	case WCD938X_RX_BIAS_HPH_RDAC_LDO:
    865	case WCD938X_RX_BIAS_HPH_CNP1:
    866	case WCD938X_RX_BIAS_HPH_LOWPOWER:
    867	case WCD938X_RX_BIAS_AUX_DAC:
    868	case WCD938X_RX_BIAS_AUX_AMP:
    869	case WCD938X_RX_BIAS_VNEGDAC_BLEEDER:
    870	case WCD938X_RX_BIAS_MISC:
    871	case WCD938X_RX_BIAS_BUCK_RST:
    872	case WCD938X_RX_BIAS_BUCK_VREF_ERRAMP:
    873	case WCD938X_RX_BIAS_FLYB_ERRAMP:
    874	case WCD938X_RX_BIAS_FLYB_BUFF:
    875	case WCD938X_RX_BIAS_FLYB_MID_RST:
    876	case WCD938X_HPH_CNP_EN:
    877	case WCD938X_HPH_CNP_WG_CTL:
    878	case WCD938X_HPH_CNP_WG_TIME:
    879	case WCD938X_HPH_OCP_CTL:
    880	case WCD938X_HPH_AUTO_CHOP:
    881	case WCD938X_HPH_CHOP_CTL:
    882	case WCD938X_HPH_PA_CTL1:
    883	case WCD938X_HPH_PA_CTL2:
    884	case WCD938X_HPH_L_EN:
    885	case WCD938X_HPH_L_TEST:
    886	case WCD938X_HPH_L_ATEST:
    887	case WCD938X_HPH_R_EN:
    888	case WCD938X_HPH_R_TEST:
    889	case WCD938X_HPH_R_ATEST:
    890	case WCD938X_HPH_RDAC_CLK_CTL1:
    891	case WCD938X_HPH_RDAC_CLK_CTL2:
    892	case WCD938X_HPH_RDAC_LDO_CTL:
    893	case WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL:
    894	case WCD938X_HPH_REFBUFF_UHQA_CTL:
    895	case WCD938X_HPH_REFBUFF_LP_CTL:
    896	case WCD938X_HPH_L_DAC_CTL:
    897	case WCD938X_HPH_R_DAC_CTL:
    898	case WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL:
    899	case WCD938X_HPH_SURGE_HPHLR_SURGE_EN:
    900	case WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1:
    901	case WCD938X_EAR_EAR_EN_REG:
    902	case WCD938X_EAR_EAR_PA_CON:
    903	case WCD938X_EAR_EAR_SP_CON:
    904	case WCD938X_EAR_EAR_DAC_CON:
    905	case WCD938X_EAR_EAR_CNP_FSM_CON:
    906	case WCD938X_EAR_TEST_CTL:
    907	case WCD938X_ANA_NEW_PAGE_REGISTER:
    908	case WCD938X_HPH_NEW_ANA_HPH2:
    909	case WCD938X_HPH_NEW_ANA_HPH3:
    910	case WCD938X_SLEEP_CTL:
    911	case WCD938X_SLEEP_WATCHDOG_CTL:
    912	case WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL:
    913	case WCD938X_MBHC_NEW_CTL_1:
    914	case WCD938X_MBHC_NEW_CTL_2:
    915	case WCD938X_MBHC_NEW_PLUG_DETECT_CTL:
    916	case WCD938X_MBHC_NEW_ZDET_ANA_CTL:
    917	case WCD938X_MBHC_NEW_ZDET_RAMP_CTL:
    918	case WCD938X_TX_NEW_AMIC_MUX_CFG:
    919	case WCD938X_AUX_AUXPA:
    920	case WCD938X_LDORXTX_MODE:
    921	case WCD938X_LDORXTX_CONFIG:
    922	case WCD938X_DIE_CRACK_DIE_CRK_DET_EN:
    923	case WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL:
    924	case WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L:
    925	case WCD938X_HPH_NEW_INT_RDAC_VREF_CTL:
    926	case WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL:
    927	case WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R:
    928	case WCD938X_HPH_NEW_INT_PA_MISC1:
    929	case WCD938X_HPH_NEW_INT_PA_MISC2:
    930	case WCD938X_HPH_NEW_INT_PA_RDAC_MISC:
    931	case WCD938X_HPH_NEW_INT_HPH_TIMER1:
    932	case WCD938X_HPH_NEW_INT_HPH_TIMER2:
    933	case WCD938X_HPH_NEW_INT_HPH_TIMER3:
    934	case WCD938X_HPH_NEW_INT_HPH_TIMER4:
    935	case WCD938X_HPH_NEW_INT_PA_RDAC_MISC2:
    936	case WCD938X_HPH_NEW_INT_PA_RDAC_MISC3:
    937	case WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW:
    938	case WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW:
    939	case WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI:
    940	case WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP:
    941	case WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP:
    942	case WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL:
    943	case WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL:
    944	case WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT:
    945	case WCD938X_MBHC_NEW_INT_SPARE_2:
    946	case WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON:
    947	case WCD938X_EAR_INT_NEW_CNP_VCM_CON1:
    948	case WCD938X_EAR_INT_NEW_CNP_VCM_CON2:
    949	case WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS:
    950	case WCD938X_AUX_INT_EN_REG:
    951	case WCD938X_AUX_INT_PA_CTRL:
    952	case WCD938X_AUX_INT_SP_CTRL:
    953	case WCD938X_AUX_INT_DAC_CTRL:
    954	case WCD938X_AUX_INT_CLK_CTRL:
    955	case WCD938X_AUX_INT_TEST_CTRL:
    956	case WCD938X_AUX_INT_MISC:
    957	case WCD938X_LDORXTX_INT_BIAS:
    958	case WCD938X_LDORXTX_INT_STB_LOADS_DTEST:
    959	case WCD938X_LDORXTX_INT_TEST0:
    960	case WCD938X_LDORXTX_INT_STARTUP_TIMER:
    961	case WCD938X_LDORXTX_INT_TEST1:
    962	case WCD938X_SLEEP_INT_WATCHDOG_CTL_1:
    963	case WCD938X_SLEEP_INT_WATCHDOG_CTL_2:
    964	case WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1:
    965	case WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2:
    966	case WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2:
    967	case WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1:
    968	case WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0:
    969	case WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M:
    970	case WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M:
    971	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1:
    972	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0:
    973	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP:
    974	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1:
    975	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0:
    976	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP:
    977	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0:
    978	case WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP:
    979	case WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1:
    980	case WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP:
    981	case WCD938X_TX_COM_NEW_INT_TXADC_INT_L2:
    982	case WCD938X_TX_COM_NEW_INT_TXADC_INT_L1:
    983	case WCD938X_TX_COM_NEW_INT_TXADC_INT_L0:
    984	case WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP:
    985	case WCD938X_DIGITAL_PAGE_REGISTER:
    986	case WCD938X_DIGITAL_SWR_TX_CLK_RATE:
    987	case WCD938X_DIGITAL_CDC_RST_CTL:
    988	case WCD938X_DIGITAL_TOP_CLK_CFG:
    989	case WCD938X_DIGITAL_CDC_ANA_CLK_CTL:
    990	case WCD938X_DIGITAL_CDC_DIG_CLK_CTL:
    991	case WCD938X_DIGITAL_SWR_RST_EN:
    992	case WCD938X_DIGITAL_CDC_PATH_MODE:
    993	case WCD938X_DIGITAL_CDC_RX_RST:
    994	case WCD938X_DIGITAL_CDC_RX0_CTL:
    995	case WCD938X_DIGITAL_CDC_RX1_CTL:
    996	case WCD938X_DIGITAL_CDC_RX2_CTL:
    997	case WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1:
    998	case WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3:
    999	case WCD938X_DIGITAL_CDC_COMP_CTL_0:
   1000	case WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL:
   1001	case WCD938X_DIGITAL_CDC_HPH_DSM_A1_0:
   1002	case WCD938X_DIGITAL_CDC_HPH_DSM_A1_1:
   1003	case WCD938X_DIGITAL_CDC_HPH_DSM_A2_0:
   1004	case WCD938X_DIGITAL_CDC_HPH_DSM_A2_1:
   1005	case WCD938X_DIGITAL_CDC_HPH_DSM_A3_0:
   1006	case WCD938X_DIGITAL_CDC_HPH_DSM_A3_1:
   1007	case WCD938X_DIGITAL_CDC_HPH_DSM_A4_0:
   1008	case WCD938X_DIGITAL_CDC_HPH_DSM_A4_1:
   1009	case WCD938X_DIGITAL_CDC_HPH_DSM_A5_0:
   1010	case WCD938X_DIGITAL_CDC_HPH_DSM_A5_1:
   1011	case WCD938X_DIGITAL_CDC_HPH_DSM_A6_0:
   1012	case WCD938X_DIGITAL_CDC_HPH_DSM_A7_0:
   1013	case WCD938X_DIGITAL_CDC_HPH_DSM_C_0:
   1014	case WCD938X_DIGITAL_CDC_HPH_DSM_C_1:
   1015	case WCD938X_DIGITAL_CDC_HPH_DSM_C_2:
   1016	case WCD938X_DIGITAL_CDC_HPH_DSM_C_3:
   1017	case WCD938X_DIGITAL_CDC_HPH_DSM_R1:
   1018	case WCD938X_DIGITAL_CDC_HPH_DSM_R2:
   1019	case WCD938X_DIGITAL_CDC_HPH_DSM_R3:
   1020	case WCD938X_DIGITAL_CDC_HPH_DSM_R4:
   1021	case WCD938X_DIGITAL_CDC_HPH_DSM_R5:
   1022	case WCD938X_DIGITAL_CDC_HPH_DSM_R6:
   1023	case WCD938X_DIGITAL_CDC_HPH_DSM_R7:
   1024	case WCD938X_DIGITAL_CDC_AUX_DSM_A1_0:
   1025	case WCD938X_DIGITAL_CDC_AUX_DSM_A1_1:
   1026	case WCD938X_DIGITAL_CDC_AUX_DSM_A2_0:
   1027	case WCD938X_DIGITAL_CDC_AUX_DSM_A2_1:
   1028	case WCD938X_DIGITAL_CDC_AUX_DSM_A3_0:
   1029	case WCD938X_DIGITAL_CDC_AUX_DSM_A3_1:
   1030	case WCD938X_DIGITAL_CDC_AUX_DSM_A4_0:
   1031	case WCD938X_DIGITAL_CDC_AUX_DSM_A4_1:
   1032	case WCD938X_DIGITAL_CDC_AUX_DSM_A5_0:
   1033	case WCD938X_DIGITAL_CDC_AUX_DSM_A5_1:
   1034	case WCD938X_DIGITAL_CDC_AUX_DSM_A6_0:
   1035	case WCD938X_DIGITAL_CDC_AUX_DSM_A7_0:
   1036	case WCD938X_DIGITAL_CDC_AUX_DSM_C_0:
   1037	case WCD938X_DIGITAL_CDC_AUX_DSM_C_1:
   1038	case WCD938X_DIGITAL_CDC_AUX_DSM_C_2:
   1039	case WCD938X_DIGITAL_CDC_AUX_DSM_C_3:
   1040	case WCD938X_DIGITAL_CDC_AUX_DSM_R1:
   1041	case WCD938X_DIGITAL_CDC_AUX_DSM_R2:
   1042	case WCD938X_DIGITAL_CDC_AUX_DSM_R3:
   1043	case WCD938X_DIGITAL_CDC_AUX_DSM_R4:
   1044	case WCD938X_DIGITAL_CDC_AUX_DSM_R5:
   1045	case WCD938X_DIGITAL_CDC_AUX_DSM_R6:
   1046	case WCD938X_DIGITAL_CDC_AUX_DSM_R7:
   1047	case WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0:
   1048	case WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1:
   1049	case WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0:
   1050	case WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1:
   1051	case WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2:
   1052	case WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0:
   1053	case WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1:
   1054	case WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2:
   1055	case WCD938X_DIGITAL_CDC_HPH_GAIN_CTL:
   1056	case WCD938X_DIGITAL_CDC_AUX_GAIN_CTL:
   1057	case WCD938X_DIGITAL_CDC_EAR_PATH_CTL:
   1058	case WCD938X_DIGITAL_CDC_SWR_CLH:
   1059	case WCD938X_DIGITAL_SWR_CLH_BYP:
   1060	case WCD938X_DIGITAL_CDC_TX0_CTL:
   1061	case WCD938X_DIGITAL_CDC_TX1_CTL:
   1062	case WCD938X_DIGITAL_CDC_TX2_CTL:
   1063	case WCD938X_DIGITAL_CDC_TX_RST:
   1064	case WCD938X_DIGITAL_CDC_REQ_CTL:
   1065	case WCD938X_DIGITAL_CDC_RST:
   1066	case WCD938X_DIGITAL_CDC_AMIC_CTL:
   1067	case WCD938X_DIGITAL_CDC_DMIC_CTL:
   1068	case WCD938X_DIGITAL_CDC_DMIC1_CTL:
   1069	case WCD938X_DIGITAL_CDC_DMIC2_CTL:
   1070	case WCD938X_DIGITAL_CDC_DMIC3_CTL:
   1071	case WCD938X_DIGITAL_CDC_DMIC4_CTL:
   1072	case WCD938X_DIGITAL_EFUSE_PRG_CTL:
   1073	case WCD938X_DIGITAL_EFUSE_CTL:
   1074	case WCD938X_DIGITAL_CDC_DMIC_RATE_1_2:
   1075	case WCD938X_DIGITAL_CDC_DMIC_RATE_3_4:
   1076	case WCD938X_DIGITAL_PDM_WD_CTL0:
   1077	case WCD938X_DIGITAL_PDM_WD_CTL1:
   1078	case WCD938X_DIGITAL_PDM_WD_CTL2:
   1079	case WCD938X_DIGITAL_INTR_MODE:
   1080	case WCD938X_DIGITAL_INTR_MASK_0:
   1081	case WCD938X_DIGITAL_INTR_MASK_1:
   1082	case WCD938X_DIGITAL_INTR_MASK_2:
   1083	case WCD938X_DIGITAL_INTR_CLEAR_0:
   1084	case WCD938X_DIGITAL_INTR_CLEAR_1:
   1085	case WCD938X_DIGITAL_INTR_CLEAR_2:
   1086	case WCD938X_DIGITAL_INTR_LEVEL_0:
   1087	case WCD938X_DIGITAL_INTR_LEVEL_1:
   1088	case WCD938X_DIGITAL_INTR_LEVEL_2:
   1089	case WCD938X_DIGITAL_INTR_SET_0:
   1090	case WCD938X_DIGITAL_INTR_SET_1:
   1091	case WCD938X_DIGITAL_INTR_SET_2:
   1092	case WCD938X_DIGITAL_INTR_TEST_0:
   1093	case WCD938X_DIGITAL_INTR_TEST_1:
   1094	case WCD938X_DIGITAL_INTR_TEST_2:
   1095	case WCD938X_DIGITAL_TX_MODE_DBG_EN:
   1096	case WCD938X_DIGITAL_TX_MODE_DBG_0_1:
   1097	case WCD938X_DIGITAL_TX_MODE_DBG_2_3:
   1098	case WCD938X_DIGITAL_LB_IN_SEL_CTL:
   1099	case WCD938X_DIGITAL_LOOP_BACK_MODE:
   1100	case WCD938X_DIGITAL_SWR_DAC_TEST:
   1101	case WCD938X_DIGITAL_SWR_HM_TEST_RX_0:
   1102	case WCD938X_DIGITAL_SWR_HM_TEST_TX_0:
   1103	case WCD938X_DIGITAL_SWR_HM_TEST_RX_1:
   1104	case WCD938X_DIGITAL_SWR_HM_TEST_TX_1:
   1105	case WCD938X_DIGITAL_SWR_HM_TEST_TX_2:
   1106	case WCD938X_DIGITAL_PAD_CTL_SWR_0:
   1107	case WCD938X_DIGITAL_PAD_CTL_SWR_1:
   1108	case WCD938X_DIGITAL_I2C_CTL:
   1109	case WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE:
   1110	case WCD938X_DIGITAL_EFUSE_TEST_CTL_0:
   1111	case WCD938X_DIGITAL_EFUSE_TEST_CTL_1:
   1112	case WCD938X_DIGITAL_PAD_CTL_PDM_RX0:
   1113	case WCD938X_DIGITAL_PAD_CTL_PDM_RX1:
   1114	case WCD938X_DIGITAL_PAD_CTL_PDM_TX0:
   1115	case WCD938X_DIGITAL_PAD_CTL_PDM_TX1:
   1116	case WCD938X_DIGITAL_PAD_CTL_PDM_TX2:
   1117	case WCD938X_DIGITAL_PAD_INP_DIS_0:
   1118	case WCD938X_DIGITAL_PAD_INP_DIS_1:
   1119	case WCD938X_DIGITAL_DRIVE_STRENGTH_0:
   1120	case WCD938X_DIGITAL_DRIVE_STRENGTH_1:
   1121	case WCD938X_DIGITAL_DRIVE_STRENGTH_2:
   1122	case WCD938X_DIGITAL_RX_DATA_EDGE_CTL:
   1123	case WCD938X_DIGITAL_TX_DATA_EDGE_CTL:
   1124	case WCD938X_DIGITAL_GPIO_MODE:
   1125	case WCD938X_DIGITAL_PIN_CTL_OE:
   1126	case WCD938X_DIGITAL_PIN_CTL_DATA_0:
   1127	case WCD938X_DIGITAL_PIN_CTL_DATA_1:
   1128	case WCD938X_DIGITAL_DIG_DEBUG_CTL:
   1129	case WCD938X_DIGITAL_DIG_DEBUG_EN:
   1130	case WCD938X_DIGITAL_ANA_CSR_DBG_ADD:
   1131	case WCD938X_DIGITAL_ANA_CSR_DBG_CTL:
   1132	case WCD938X_DIGITAL_SSP_DBG:
   1133	case WCD938X_DIGITAL_SPARE_0:
   1134	case WCD938X_DIGITAL_SPARE_1:
   1135	case WCD938X_DIGITAL_SPARE_2:
   1136	case WCD938X_DIGITAL_TX_REQ_FB_CTL_0:
   1137	case WCD938X_DIGITAL_TX_REQ_FB_CTL_1:
   1138	case WCD938X_DIGITAL_TX_REQ_FB_CTL_2:
   1139	case WCD938X_DIGITAL_TX_REQ_FB_CTL_3:
   1140	case WCD938X_DIGITAL_TX_REQ_FB_CTL_4:
   1141	case WCD938X_DIGITAL_DEM_BYPASS_DATA0:
   1142	case WCD938X_DIGITAL_DEM_BYPASS_DATA1:
   1143	case WCD938X_DIGITAL_DEM_BYPASS_DATA2:
   1144	case WCD938X_DIGITAL_DEM_BYPASS_DATA3:
   1145		return true;
   1146	}
   1147
   1148	return false;
   1149}
   1150
   1151static bool wcd938x_readonly_register(struct device *dev, unsigned int reg)
   1152{
   1153	switch (reg) {
   1154	case WCD938X_ANA_MBHC_RESULT_1:
   1155	case WCD938X_ANA_MBHC_RESULT_2:
   1156	case WCD938X_ANA_MBHC_RESULT_3:
   1157	case WCD938X_MBHC_MOISTURE_DET_FSM_STATUS:
   1158	case WCD938X_TX_1_2_SAR2_ERR:
   1159	case WCD938X_TX_1_2_SAR1_ERR:
   1160	case WCD938X_TX_3_4_SAR4_ERR:
   1161	case WCD938X_TX_3_4_SAR3_ERR:
   1162	case WCD938X_HPH_L_STATUS:
   1163	case WCD938X_HPH_R_STATUS:
   1164	case WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS:
   1165	case WCD938X_EAR_STATUS_REG_1:
   1166	case WCD938X_EAR_STATUS_REG_2:
   1167	case WCD938X_MBHC_NEW_FSM_STATUS:
   1168	case WCD938X_MBHC_NEW_ADC_RESULT:
   1169	case WCD938X_DIE_CRACK_DIE_CRK_DET_OUT:
   1170	case WCD938X_AUX_INT_STATUS_REG:
   1171	case WCD938X_LDORXTX_INT_STATUS:
   1172	case WCD938X_DIGITAL_CHIP_ID0:
   1173	case WCD938X_DIGITAL_CHIP_ID1:
   1174	case WCD938X_DIGITAL_CHIP_ID2:
   1175	case WCD938X_DIGITAL_CHIP_ID3:
   1176	case WCD938X_DIGITAL_INTR_STATUS_0:
   1177	case WCD938X_DIGITAL_INTR_STATUS_1:
   1178	case WCD938X_DIGITAL_INTR_STATUS_2:
   1179	case WCD938X_DIGITAL_INTR_CLEAR_0:
   1180	case WCD938X_DIGITAL_INTR_CLEAR_1:
   1181	case WCD938X_DIGITAL_INTR_CLEAR_2:
   1182	case WCD938X_DIGITAL_SWR_HM_TEST_0:
   1183	case WCD938X_DIGITAL_SWR_HM_TEST_1:
   1184	case WCD938X_DIGITAL_EFUSE_T_DATA_0:
   1185	case WCD938X_DIGITAL_EFUSE_T_DATA_1:
   1186	case WCD938X_DIGITAL_PIN_STATUS_0:
   1187	case WCD938X_DIGITAL_PIN_STATUS_1:
   1188	case WCD938X_DIGITAL_MODE_STATUS_0:
   1189	case WCD938X_DIGITAL_MODE_STATUS_1:
   1190	case WCD938X_DIGITAL_EFUSE_REG_0:
   1191	case WCD938X_DIGITAL_EFUSE_REG_1:
   1192	case WCD938X_DIGITAL_EFUSE_REG_2:
   1193	case WCD938X_DIGITAL_EFUSE_REG_3:
   1194	case WCD938X_DIGITAL_EFUSE_REG_4:
   1195	case WCD938X_DIGITAL_EFUSE_REG_5:
   1196	case WCD938X_DIGITAL_EFUSE_REG_6:
   1197	case WCD938X_DIGITAL_EFUSE_REG_7:
   1198	case WCD938X_DIGITAL_EFUSE_REG_8:
   1199	case WCD938X_DIGITAL_EFUSE_REG_9:
   1200	case WCD938X_DIGITAL_EFUSE_REG_10:
   1201	case WCD938X_DIGITAL_EFUSE_REG_11:
   1202	case WCD938X_DIGITAL_EFUSE_REG_12:
   1203	case WCD938X_DIGITAL_EFUSE_REG_13:
   1204	case WCD938X_DIGITAL_EFUSE_REG_14:
   1205	case WCD938X_DIGITAL_EFUSE_REG_15:
   1206	case WCD938X_DIGITAL_EFUSE_REG_16:
   1207	case WCD938X_DIGITAL_EFUSE_REG_17:
   1208	case WCD938X_DIGITAL_EFUSE_REG_18:
   1209	case WCD938X_DIGITAL_EFUSE_REG_19:
   1210	case WCD938X_DIGITAL_EFUSE_REG_20:
   1211	case WCD938X_DIGITAL_EFUSE_REG_21:
   1212	case WCD938X_DIGITAL_EFUSE_REG_22:
   1213	case WCD938X_DIGITAL_EFUSE_REG_23:
   1214	case WCD938X_DIGITAL_EFUSE_REG_24:
   1215	case WCD938X_DIGITAL_EFUSE_REG_25:
   1216	case WCD938X_DIGITAL_EFUSE_REG_26:
   1217	case WCD938X_DIGITAL_EFUSE_REG_27:
   1218	case WCD938X_DIGITAL_EFUSE_REG_28:
   1219	case WCD938X_DIGITAL_EFUSE_REG_29:
   1220	case WCD938X_DIGITAL_EFUSE_REG_30:
   1221	case WCD938X_DIGITAL_EFUSE_REG_31:
   1222		return true;
   1223	}
   1224	return false;
   1225}
   1226
   1227static bool wcd938x_readable_register(struct device *dev, unsigned int reg)
   1228{
   1229	bool ret;
   1230
   1231	ret = wcd938x_readonly_register(dev, reg);
   1232	if (!ret)
   1233		return wcd938x_rdwr_register(dev, reg);
   1234
   1235	return ret;
   1236}
   1237
   1238static bool wcd938x_writeable_register(struct device *dev, unsigned int reg)
   1239{
   1240	return wcd938x_rdwr_register(dev, reg);
   1241}
   1242
   1243static bool wcd938x_volatile_register(struct device *dev, unsigned int reg)
   1244{
   1245	if (reg <= WCD938X_BASE_ADDRESS)
   1246		return false;
   1247
   1248	if (reg == WCD938X_DIGITAL_SWR_TX_CLK_RATE)
   1249		return true;
   1250
   1251	if (wcd938x_readonly_register(dev, reg))
   1252		return true;
   1253
   1254	return false;
   1255}
   1256
   1257static struct regmap_config wcd938x_regmap_config = {
   1258	.name = "wcd938x_csr",
   1259	.reg_bits = 32,
   1260	.val_bits = 8,
   1261	.cache_type = REGCACHE_RBTREE,
   1262	.reg_defaults = wcd938x_defaults,
   1263	.num_reg_defaults = ARRAY_SIZE(wcd938x_defaults),
   1264	.max_register = WCD938X_MAX_REGISTER,
   1265	.readable_reg = wcd938x_readable_register,
   1266	.writeable_reg = wcd938x_writeable_register,
   1267	.volatile_reg = wcd938x_volatile_register,
   1268	.can_multi_write = true,
   1269};
   1270
   1271static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = {
   1272	REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
   1273	REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02),
   1274	REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04),
   1275	REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08),
   1276	REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_SW_DET, 0, 0x10),
   1277	REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_OCP_INT, 0, 0x20),
   1278	REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_CNP_INT, 0, 0x40),
   1279	REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_OCP_INT, 0, 0x80),
   1280	REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_CNP_INT, 1, 0x01),
   1281	REGMAP_IRQ_REG(WCD938X_IRQ_EAR_CNP_INT, 1, 0x02),
   1282	REGMAP_IRQ_REG(WCD938X_IRQ_EAR_SCD_INT, 1, 0x04),
   1283	REGMAP_IRQ_REG(WCD938X_IRQ_AUX_CNP_INT, 1, 0x08),
   1284	REGMAP_IRQ_REG(WCD938X_IRQ_AUX_SCD_INT, 1, 0x10),
   1285	REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_PDM_WD_INT, 1, 0x20),
   1286	REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_PDM_WD_INT, 1, 0x40),
   1287	REGMAP_IRQ_REG(WCD938X_IRQ_AUX_PDM_WD_INT, 1, 0x80),
   1288	REGMAP_IRQ_REG(WCD938X_IRQ_LDORT_SCD_INT, 2, 0x01),
   1289	REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_MOISTURE_INT, 2, 0x02),
   1290	REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04),
   1291	REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08),
   1292};
   1293
   1294static struct regmap_irq_chip wcd938x_regmap_irq_chip = {
   1295	.name = "wcd938x",
   1296	.irqs = wcd938x_irqs,
   1297	.num_irqs = ARRAY_SIZE(wcd938x_irqs),
   1298	.num_regs = 3,
   1299	.status_base = WCD938X_DIGITAL_INTR_STATUS_0,
   1300	.mask_base = WCD938X_DIGITAL_INTR_MASK_0,
   1301	.type_base = WCD938X_DIGITAL_INTR_LEVEL_0,
   1302	.ack_base = WCD938X_DIGITAL_INTR_CLEAR_0,
   1303	.use_ack = 1,
   1304	.runtime_pm = true,
   1305	.irq_drv_data = NULL,
   1306};
   1307
   1308static int wcd938x_get_clk_rate(int mode)
   1309{
   1310	int rate;
   1311
   1312	switch (mode) {
   1313	case ADC_MODE_ULP2:
   1314		rate = SWR_CLK_RATE_0P6MHZ;
   1315		break;
   1316	case ADC_MODE_ULP1:
   1317		rate = SWR_CLK_RATE_1P2MHZ;
   1318		break;
   1319	case ADC_MODE_LP:
   1320		rate = SWR_CLK_RATE_4P8MHZ;
   1321		break;
   1322	case ADC_MODE_NORMAL:
   1323	case ADC_MODE_LO_HIF:
   1324	case ADC_MODE_HIFI:
   1325	case ADC_MODE_INVALID:
   1326	default:
   1327		rate = SWR_CLK_RATE_9P6MHZ;
   1328		break;
   1329	}
   1330
   1331	return rate;
   1332}
   1333
   1334static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, int rate, int bank)
   1335{
   1336	u8 mask = (bank ? 0xF0 : 0x0F);
   1337	u8 val = 0;
   1338
   1339	switch (rate) {
   1340	case SWR_CLK_RATE_0P6MHZ:
   1341		val = (bank ? 0x60 : 0x06);
   1342		break;
   1343	case SWR_CLK_RATE_1P2MHZ:
   1344		val = (bank ? 0x50 : 0x05);
   1345		break;
   1346	case SWR_CLK_RATE_2P4MHZ:
   1347		val = (bank ? 0x30 : 0x03);
   1348		break;
   1349	case SWR_CLK_RATE_4P8MHZ:
   1350		val = (bank ? 0x10 : 0x01);
   1351		break;
   1352	case SWR_CLK_RATE_9P6MHZ:
   1353	default:
   1354		val = 0x00;
   1355		break;
   1356	}
   1357	snd_soc_component_update_bits(component, WCD938X_DIGITAL_SWR_TX_CLK_RATE,
   1358				      mask, val);
   1359
   1360	return 0;
   1361}
   1362
   1363static int wcd938x_io_init(struct wcd938x_priv *wcd938x)
   1364{
   1365	struct regmap *rm = wcd938x->regmap;
   1366
   1367	regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x0E, 0x0E);
   1368	regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x80, 0x80);
   1369	/* 1 msec delay as per HW requirement */
   1370	usleep_range(1000, 1010);
   1371	regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x40, 0x40);
   1372	/* 1 msec delay as per HW requirement */
   1373	usleep_range(1000, 1010);
   1374	regmap_update_bits(rm, WCD938X_LDORXTX_CONFIG, 0x10, 0x00);
   1375	regmap_update_bits(rm, WCD938X_BIAS_VBG_FINE_ADJ,
   1376								0xF0, 0x80);
   1377	regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x80, 0x80);
   1378	regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x40, 0x40);
   1379	/* 10 msec delay as per HW requirement */
   1380	usleep_range(10000, 10010);
   1381
   1382	regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x40, 0x00);
   1383	regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL,
   1384				      0xF0, 0x00);
   1385	regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW,
   1386				      0x1F, 0x15);
   1387	regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW,
   1388				      0x1F, 0x15);
   1389	regmap_update_bits(rm, WCD938X_HPH_REFBUFF_UHQA_CTL,
   1390				      0xC0, 0x80);
   1391	regmap_update_bits(rm, WCD938X_DIGITAL_CDC_DMIC_CTL,
   1392				      0x02, 0x02);
   1393
   1394	regmap_update_bits(rm, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP,
   1395			   0xFF, 0x14);
   1396	regmap_update_bits(rm, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP,
   1397			   0x1F, 0x08);
   1398
   1399	regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0xFF, 0x55);
   1400	regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0xFF, 0x44);
   1401	regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0xFF, 0x11);
   1402	regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0xFF, 0x00);
   1403	regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0xFF, 0x00);
   1404
   1405	/* Set Noise Filter Resistor value */
   1406	regmap_update_bits(rm, WCD938X_MICB1_TEST_CTL_1, 0xE0, 0xE0);
   1407	regmap_update_bits(rm, WCD938X_MICB2_TEST_CTL_1, 0xE0, 0xE0);
   1408	regmap_update_bits(rm, WCD938X_MICB3_TEST_CTL_1, 0xE0, 0xE0);
   1409	regmap_update_bits(rm, WCD938X_MICB4_TEST_CTL_1, 0xE0, 0xE0);
   1410
   1411	regmap_update_bits(rm, WCD938X_TX_3_4_TEST_BLK_EN2, 0x01, 0x00);
   1412	regmap_update_bits(rm, WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
   1413
   1414	return 0;
   1415
   1416}
   1417
   1418static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
   1419				    struct sdw_port_config *port_config,
   1420				    u8 enable)
   1421{
   1422	u8 ch_mask, port_num;
   1423
   1424	port_num = ch_info->port_num;
   1425	ch_mask = ch_info->ch_mask;
   1426
   1427	port_config->num = port_num;
   1428
   1429	if (enable)
   1430		port_config->ch_mask |= ch_mask;
   1431	else
   1432		port_config->ch_mask &= ~ch_mask;
   1433
   1434	return 0;
   1435}
   1436
   1437static int wcd938x_connect_port(struct wcd938x_sdw_priv *wcd, u8 port_num, u8 ch_id, u8 enable)
   1438{
   1439	return wcd938x_sdw_connect_port(&wcd->ch_info[ch_id],
   1440					&wcd->port_config[port_num - 1],
   1441					enable);
   1442}
   1443
   1444static int wcd938x_codec_enable_rxclk(struct snd_soc_dapm_widget *w,
   1445				      struct snd_kcontrol *kcontrol,
   1446				      int event)
   1447{
   1448	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1449
   1450	switch (event) {
   1451	case SND_SOC_DAPM_PRE_PMU:
   1452		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   1453				WCD938X_ANA_RX_CLK_EN_MASK, 1);
   1454		snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1455				WCD938X_RX_BIAS_EN_MASK, 1);
   1456		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX0_CTL,
   1457				WCD938X_DEM_DITHER_ENABLE_MASK, 0);
   1458		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX1_CTL,
   1459				WCD938X_DEM_DITHER_ENABLE_MASK, 0);
   1460		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX2_CTL,
   1461				WCD938X_DEM_DITHER_ENABLE_MASK, 0);
   1462		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   1463				WCD938X_ANA_RX_DIV2_CLK_EN_MASK, 1);
   1464		snd_soc_component_write_field(component, WCD938X_AUX_AUXPA,
   1465					      WCD938X_AUXPA_CLK_EN_MASK, 1);
   1466		break;
   1467	case SND_SOC_DAPM_POST_PMD:
   1468		snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1469				WCD938X_VNEG_EN_MASK, 0);
   1470		snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1471				WCD938X_VPOS_EN_MASK, 0);
   1472		snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1473				WCD938X_RX_BIAS_EN_MASK, 0);
   1474		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   1475				WCD938X_ANA_RX_DIV2_CLK_EN_MASK, 0);
   1476		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   1477				WCD938X_ANA_RX_CLK_EN_MASK, 0);
   1478		break;
   1479	}
   1480	return 0;
   1481}
   1482
   1483static int wcd938x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
   1484					struct snd_kcontrol *kcontrol,
   1485					int event)
   1486{
   1487	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1488	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1489
   1490	switch (event) {
   1491	case SND_SOC_DAPM_PRE_PMU:
   1492		snd_soc_component_write_field(component,
   1493				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1494				WCD938X_RXD0_CLK_EN_MASK, 0x01);
   1495		snd_soc_component_write_field(component,
   1496				WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
   1497				WCD938X_HPHL_RX_EN_MASK, 1);
   1498		snd_soc_component_write_field(component,
   1499				WCD938X_HPH_RDAC_CLK_CTL1,
   1500				WCD938X_CHOP_CLK_EN_MASK, 0);
   1501		break;
   1502	case SND_SOC_DAPM_POST_PMU:
   1503		snd_soc_component_write_field(component,
   1504				WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L,
   1505				WCD938X_HPH_RES_DIV_MASK, 0x02);
   1506		if (wcd938x->comp1_enable) {
   1507			snd_soc_component_write_field(component,
   1508				WCD938X_DIGITAL_CDC_COMP_CTL_0,
   1509				WCD938X_HPHL_COMP_EN_MASK, 1);
   1510			/* 5msec compander delay as per HW requirement */
   1511			if (!wcd938x->comp2_enable || (snd_soc_component_read(component,
   1512							 WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x01))
   1513				usleep_range(5000, 5010);
   1514			snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
   1515					      WCD938X_AUTOCHOP_TIMER_EN, 0);
   1516		} else {
   1517			snd_soc_component_write_field(component,
   1518					WCD938X_DIGITAL_CDC_COMP_CTL_0,
   1519					WCD938X_HPHL_COMP_EN_MASK, 0);
   1520			snd_soc_component_write_field(component,
   1521					WCD938X_HPH_L_EN,
   1522					WCD938X_GAIN_SRC_SEL_MASK,
   1523					WCD938X_GAIN_SRC_SEL_REGISTER);
   1524
   1525		}
   1526		break;
   1527	case SND_SOC_DAPM_POST_PMD:
   1528		snd_soc_component_write_field(component,
   1529			WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
   1530			WCD938X_HPH_RES_DIV_MASK, 0x1);
   1531		break;
   1532	}
   1533
   1534	return 0;
   1535}
   1536
   1537static int wcd938x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
   1538					struct snd_kcontrol *kcontrol,
   1539					int event)
   1540{
   1541	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1542	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1543
   1544	switch (event) {
   1545	case SND_SOC_DAPM_PRE_PMU:
   1546		snd_soc_component_write_field(component,
   1547				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1548				WCD938X_RXD1_CLK_EN_MASK, 1);
   1549		snd_soc_component_write_field(component,
   1550				WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
   1551				WCD938X_HPHR_RX_EN_MASK, 1);
   1552		snd_soc_component_write_field(component,
   1553				WCD938X_HPH_RDAC_CLK_CTL1,
   1554				WCD938X_CHOP_CLK_EN_MASK, 0);
   1555		break;
   1556	case SND_SOC_DAPM_POST_PMU:
   1557		snd_soc_component_write_field(component,
   1558				WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
   1559				WCD938X_HPH_RES_DIV_MASK, 0x02);
   1560		if (wcd938x->comp2_enable) {
   1561			snd_soc_component_write_field(component,
   1562				WCD938X_DIGITAL_CDC_COMP_CTL_0,
   1563				WCD938X_HPHR_COMP_EN_MASK, 1);
   1564			/* 5msec compander delay as per HW requirement */
   1565			if (!wcd938x->comp1_enable ||
   1566				(snd_soc_component_read(component,
   1567					WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x02))
   1568				usleep_range(5000, 5010);
   1569			snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
   1570					      WCD938X_AUTOCHOP_TIMER_EN, 0);
   1571		} else {
   1572			snd_soc_component_write_field(component,
   1573					WCD938X_DIGITAL_CDC_COMP_CTL_0,
   1574					WCD938X_HPHR_COMP_EN_MASK, 0);
   1575			snd_soc_component_write_field(component,
   1576					WCD938X_HPH_R_EN,
   1577					WCD938X_GAIN_SRC_SEL_MASK,
   1578					WCD938X_GAIN_SRC_SEL_REGISTER);
   1579		}
   1580		break;
   1581	case SND_SOC_DAPM_POST_PMD:
   1582		snd_soc_component_write_field(component,
   1583			WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
   1584			WCD938X_HPH_RES_DIV_MASK, 0x01);
   1585		break;
   1586	}
   1587
   1588	return 0;
   1589}
   1590
   1591static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
   1592				       struct snd_kcontrol *kcontrol,
   1593				       int event)
   1594{
   1595	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1596	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1597
   1598	switch (event) {
   1599	case SND_SOC_DAPM_PRE_PMU:
   1600		wcd938x->ear_rx_path =
   1601			snd_soc_component_read(
   1602				component, WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
   1603		if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
   1604			snd_soc_component_write_field(component,
   1605				WCD938X_EAR_EAR_DAC_CON,
   1606				WCD938X_DAC_SAMPLE_EDGE_SEL_MASK, 0);
   1607			snd_soc_component_write_field(component,
   1608				WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
   1609				WCD938X_AUX_EN_MASK, 1);
   1610			snd_soc_component_write_field(component,
   1611				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1612				WCD938X_RXD2_CLK_EN_MASK, 1);
   1613			snd_soc_component_write_field(component,
   1614				WCD938X_ANA_EAR_COMPANDER_CTL,
   1615				WCD938X_GAIN_OVRD_REG_MASK, 1);
   1616		} else {
   1617			snd_soc_component_write_field(component,
   1618				WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
   1619				WCD938X_HPHL_RX_EN_MASK, 1);
   1620			snd_soc_component_write_field(component,
   1621				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1622				WCD938X_RXD0_CLK_EN_MASK, 1);
   1623			if (wcd938x->comp1_enable)
   1624				snd_soc_component_write_field(component,
   1625					WCD938X_DIGITAL_CDC_COMP_CTL_0,
   1626					WCD938X_HPHL_COMP_EN_MASK, 1);
   1627		}
   1628		/* 5 msec delay as per HW requirement */
   1629		usleep_range(5000, 5010);
   1630		if (wcd938x->flyback_cur_det_disable == 0)
   1631			snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
   1632						      WCD938X_EN_CUR_DET_MASK, 0);
   1633		wcd938x->flyback_cur_det_disable++;
   1634		wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
   1635			     WCD_CLSH_EVENT_PRE_DAC,
   1636			     WCD_CLSH_STATE_EAR,
   1637			     wcd938x->hph_mode);
   1638		break;
   1639	case SND_SOC_DAPM_POST_PMD:
   1640		if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
   1641			snd_soc_component_write_field(component,
   1642				WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
   1643				WCD938X_AUX_EN_MASK, 0);
   1644			snd_soc_component_write_field(component,
   1645				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1646				WCD938X_RXD2_CLK_EN_MASK, 0);
   1647		} else {
   1648			snd_soc_component_write_field(component,
   1649				WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
   1650				WCD938X_HPHL_RX_EN_MASK, 0);
   1651			snd_soc_component_write_field(component,
   1652				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1653				WCD938X_RXD0_CLK_EN_MASK, 0);
   1654			if (wcd938x->comp1_enable)
   1655				snd_soc_component_write_field(component,
   1656					WCD938X_DIGITAL_CDC_COMP_CTL_0,
   1657					WCD938X_HPHL_COMP_EN_MASK, 0);
   1658		}
   1659		snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
   1660					      WCD938X_GAIN_OVRD_REG_MASK, 0);
   1661		snd_soc_component_write_field(component,
   1662				WCD938X_EAR_EAR_DAC_CON,
   1663				WCD938X_DAC_SAMPLE_EDGE_SEL_MASK, 1);
   1664		break;
   1665	}
   1666	return 0;
   1667
   1668}
   1669
   1670static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
   1671				       struct snd_kcontrol *kcontrol,
   1672				       int event)
   1673{
   1674	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1675	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1676
   1677	switch (event) {
   1678	case SND_SOC_DAPM_PRE_PMU:
   1679		snd_soc_component_write_field(component,
   1680				WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   1681				WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 1);
   1682		snd_soc_component_write_field(component,
   1683				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   1684				WCD938X_RXD2_CLK_EN_MASK, 1);
   1685		snd_soc_component_write_field(component,
   1686				WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
   1687				WCD938X_AUX_EN_MASK, 1);
   1688		if (wcd938x->flyback_cur_det_disable == 0)
   1689			snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
   1690						      WCD938X_EN_CUR_DET_MASK, 0);
   1691		wcd938x->flyback_cur_det_disable++;
   1692		wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
   1693			     WCD_CLSH_EVENT_PRE_DAC,
   1694			     WCD_CLSH_STATE_AUX,
   1695			     wcd938x->hph_mode);
   1696		break;
   1697	case SND_SOC_DAPM_POST_PMD:
   1698		snd_soc_component_write_field(component,
   1699				WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   1700				WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 0);
   1701		break;
   1702	}
   1703	return 0;
   1704
   1705}
   1706
   1707static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
   1708					struct snd_kcontrol *kcontrol, int event)
   1709{
   1710	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1711	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1712	int hph_mode = wcd938x->hph_mode;
   1713
   1714	switch (event) {
   1715	case SND_SOC_DAPM_PRE_PMU:
   1716		if (wcd938x->ldoh)
   1717			snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
   1718						      WCD938X_LDOH_EN_MASK, 1);
   1719		wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC,
   1720					WCD_CLSH_STATE_HPHR, hph_mode);
   1721		wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI);
   1722
   1723		if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
   1724		    hph_mode == CLS_H_ULP) {
   1725			snd_soc_component_write_field(component,
   1726				WCD938X_HPH_REFBUFF_LP_CTL,
   1727				WCD938X_PREREF_FLIT_BYPASS_MASK, 1);
   1728		}
   1729		snd_soc_component_write_field(component, WCD938X_ANA_HPH,
   1730					      WCD938X_HPHR_REF_EN_MASK, 1);
   1731		wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode);
   1732		/* 100 usec delay as per HW requirement */
   1733		usleep_range(100, 110);
   1734		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1735		snd_soc_component_write_field(component,
   1736					      WCD938X_DIGITAL_PDM_WD_CTL1,
   1737					      WCD938X_PDM_WD_EN_MASK, 0x3);
   1738		break;
   1739	case SND_SOC_DAPM_POST_PMU:
   1740		/*
   1741		 * 7ms sleep is required if compander is enabled as per
   1742		 * HW requirement. If compander is disabled, then
   1743		 * 20ms delay is required.
   1744		 */
   1745		if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
   1746			if (!wcd938x->comp2_enable)
   1747				usleep_range(20000, 20100);
   1748			else
   1749				usleep_range(7000, 7100);
   1750
   1751			if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
   1752			    hph_mode == CLS_H_ULP)
   1753				snd_soc_component_write_field(component,
   1754						WCD938X_HPH_REFBUFF_LP_CTL,
   1755						WCD938X_PREREF_FLIT_BYPASS_MASK, 0);
   1756			clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1757		}
   1758		snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
   1759					      WCD938X_AUTOCHOP_TIMER_EN, 1);
   1760		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
   1761			hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
   1762			snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1763					WCD938X_REGULATOR_MODE_MASK,
   1764					WCD938X_REGULATOR_MODE_CLASS_AB);
   1765		enable_irq(wcd938x->hphr_pdm_wd_int);
   1766		break;
   1767	case SND_SOC_DAPM_PRE_PMD:
   1768		disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
   1769		/*
   1770		 * 7ms sleep is required if compander is enabled as per
   1771		 * HW requirement. If compander is disabled, then
   1772		 * 20ms delay is required.
   1773		 */
   1774		if (!wcd938x->comp2_enable)
   1775			usleep_range(20000, 20100);
   1776		else
   1777			usleep_range(7000, 7100);
   1778		snd_soc_component_write_field(component, WCD938X_ANA_HPH,
   1779					      WCD938X_HPHR_EN_MASK, 0);
   1780		wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   1781					     WCD_EVENT_PRE_HPHR_PA_OFF);
   1782		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1783		break;
   1784	case SND_SOC_DAPM_POST_PMD:
   1785		/*
   1786		 * 7ms sleep is required if compander is enabled as per
   1787		 * HW requirement. If compander is disabled, then
   1788		 * 20ms delay is required.
   1789		 */
   1790		if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
   1791			if (!wcd938x->comp2_enable)
   1792				usleep_range(20000, 20100);
   1793			else
   1794				usleep_range(7000, 7100);
   1795			clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1796		}
   1797		wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   1798					     WCD_EVENT_POST_HPHR_PA_OFF);
   1799		snd_soc_component_write_field(component, WCD938X_ANA_HPH,
   1800					      WCD938X_HPHR_REF_EN_MASK, 0);
   1801		snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL1,
   1802					      WCD938X_PDM_WD_EN_MASK, 0);
   1803		wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
   1804					WCD_CLSH_STATE_HPHR, hph_mode);
   1805		if (wcd938x->ldoh)
   1806			snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
   1807						      WCD938X_LDOH_EN_MASK, 0);
   1808		break;
   1809	}
   1810
   1811	return 0;
   1812}
   1813
   1814static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
   1815					struct snd_kcontrol *kcontrol, int event)
   1816{
   1817	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1818	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1819	int hph_mode = wcd938x->hph_mode;
   1820
   1821	switch (event) {
   1822	case SND_SOC_DAPM_PRE_PMU:
   1823		if (wcd938x->ldoh)
   1824			snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
   1825						      WCD938X_LDOH_EN_MASK, 1);
   1826		wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC,
   1827					WCD_CLSH_STATE_HPHL, hph_mode);
   1828		wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI);
   1829		if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
   1830		    hph_mode == CLS_H_ULP) {
   1831			snd_soc_component_write_field(component,
   1832					WCD938X_HPH_REFBUFF_LP_CTL,
   1833					WCD938X_PREREF_FLIT_BYPASS_MASK, 1);
   1834		}
   1835		snd_soc_component_write_field(component, WCD938X_ANA_HPH,
   1836					      WCD938X_HPHL_REF_EN_MASK, 1);
   1837		wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode);
   1838		/* 100 usec delay as per HW requirement */
   1839		usleep_range(100, 110);
   1840		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1841		snd_soc_component_write_field(component,
   1842					WCD938X_DIGITAL_PDM_WD_CTL0,
   1843					WCD938X_PDM_WD_EN_MASK, 0x3);
   1844		break;
   1845	case SND_SOC_DAPM_POST_PMU:
   1846		/*
   1847		 * 7ms sleep is required if compander is enabled as per
   1848		 * HW requirement. If compander is disabled, then
   1849		 * 20ms delay is required.
   1850		 */
   1851		if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
   1852			if (!wcd938x->comp1_enable)
   1853				usleep_range(20000, 20100);
   1854			else
   1855				usleep_range(7000, 7100);
   1856			if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
   1857			    hph_mode == CLS_H_ULP)
   1858				snd_soc_component_write_field(component,
   1859					WCD938X_HPH_REFBUFF_LP_CTL,
   1860					WCD938X_PREREF_FLIT_BYPASS_MASK, 0);
   1861			clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1862		}
   1863
   1864		snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
   1865					      WCD938X_AUTOCHOP_TIMER_EN, 1);
   1866		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
   1867			hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
   1868			snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1869					WCD938X_REGULATOR_MODE_MASK,
   1870					WCD938X_REGULATOR_MODE_CLASS_AB);
   1871		enable_irq(wcd938x->hphl_pdm_wd_int);
   1872		break;
   1873	case SND_SOC_DAPM_PRE_PMD:
   1874		disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
   1875		/*
   1876		 * 7ms sleep is required if compander is enabled as per
   1877		 * HW requirement. If compander is disabled, then
   1878		 * 20ms delay is required.
   1879		 */
   1880		if (!wcd938x->comp1_enable)
   1881			usleep_range(20000, 20100);
   1882		else
   1883			usleep_range(7000, 7100);
   1884		snd_soc_component_write_field(component, WCD938X_ANA_HPH,
   1885					      WCD938X_HPHL_EN_MASK, 0);
   1886		wcd_mbhc_event_notify(wcd938x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF);
   1887		set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1888		break;
   1889	case SND_SOC_DAPM_POST_PMD:
   1890		/*
   1891		 * 7ms sleep is required if compander is enabled as per
   1892		 * HW requirement. If compander is disabled, then
   1893		 * 20ms delay is required.
   1894		 */
   1895		if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
   1896			if (!wcd938x->comp1_enable)
   1897				usleep_range(21000, 21100);
   1898			else
   1899				usleep_range(7000, 7100);
   1900			clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
   1901		}
   1902		wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   1903					     WCD_EVENT_POST_HPHL_PA_OFF);
   1904		snd_soc_component_write_field(component, WCD938X_ANA_HPH,
   1905					      WCD938X_HPHL_REF_EN_MASK, 0);
   1906		snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
   1907					      WCD938X_PDM_WD_EN_MASK, 0);
   1908		wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
   1909					WCD_CLSH_STATE_HPHL, hph_mode);
   1910		if (wcd938x->ldoh)
   1911			snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
   1912						      WCD938X_LDOH_EN_MASK, 0);
   1913		break;
   1914	}
   1915
   1916	return 0;
   1917}
   1918
   1919static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
   1920				       struct snd_kcontrol *kcontrol, int event)
   1921{
   1922	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1923	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1924	int hph_mode = wcd938x->hph_mode;
   1925
   1926	switch (event) {
   1927	case SND_SOC_DAPM_PRE_PMU:
   1928		snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
   1929					      WCD938X_AUX_PDM_WD_EN_MASK, 1);
   1930		break;
   1931	case SND_SOC_DAPM_POST_PMU:
   1932		/* 1 msec delay as per HW requirement */
   1933		usleep_range(1000, 1010);
   1934		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
   1935			hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
   1936			snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1937					WCD938X_REGULATOR_MODE_MASK,
   1938					WCD938X_REGULATOR_MODE_CLASS_AB);
   1939		enable_irq(wcd938x->aux_pdm_wd_int);
   1940		break;
   1941	case SND_SOC_DAPM_PRE_PMD:
   1942		disable_irq_nosync(wcd938x->aux_pdm_wd_int);
   1943		break;
   1944	case SND_SOC_DAPM_POST_PMD:
   1945		/* 1 msec delay as per HW requirement */
   1946		usleep_range(1000, 1010);
   1947		snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
   1948					      WCD938X_AUX_PDM_WD_EN_MASK, 0);
   1949		wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
   1950			     WCD_CLSH_EVENT_POST_PA,
   1951			     WCD_CLSH_STATE_AUX,
   1952			     hph_mode);
   1953
   1954		wcd938x->flyback_cur_det_disable--;
   1955		if (wcd938x->flyback_cur_det_disable == 0)
   1956			snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
   1957						      WCD938X_EN_CUR_DET_MASK, 1);
   1958		break;
   1959	}
   1960	return 0;
   1961}
   1962
   1963static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
   1964				       struct snd_kcontrol *kcontrol, int event)
   1965{
   1966	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   1967	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   1968	int hph_mode = wcd938x->hph_mode;
   1969
   1970	switch (event) {
   1971	case SND_SOC_DAPM_PRE_PMU:
   1972		/*
   1973		 * Enable watchdog interrupt for HPHL or AUX
   1974		 * depending on mux value
   1975		 */
   1976		wcd938x->ear_rx_path = snd_soc_component_read(component,
   1977							      WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
   1978		if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
   1979			snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
   1980					      WCD938X_AUX_PDM_WD_EN_MASK, 1);
   1981		else
   1982			snd_soc_component_write_field(component,
   1983						      WCD938X_DIGITAL_PDM_WD_CTL0,
   1984						      WCD938X_PDM_WD_EN_MASK, 0x3);
   1985		if (!wcd938x->comp1_enable)
   1986			snd_soc_component_write_field(component,
   1987						      WCD938X_ANA_EAR_COMPANDER_CTL,
   1988						      WCD938X_GAIN_OVRD_REG_MASK, 1);
   1989
   1990		break;
   1991	case SND_SOC_DAPM_POST_PMU:
   1992		/* 6 msec delay as per HW requirement */
   1993		usleep_range(6000, 6010);
   1994		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
   1995			hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
   1996			snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
   1997					WCD938X_REGULATOR_MODE_MASK,
   1998					WCD938X_REGULATOR_MODE_CLASS_AB);
   1999		if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
   2000			enable_irq(wcd938x->aux_pdm_wd_int);
   2001		else
   2002			enable_irq(wcd938x->hphl_pdm_wd_int);
   2003		break;
   2004	case SND_SOC_DAPM_PRE_PMD:
   2005		if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
   2006			disable_irq_nosync(wcd938x->aux_pdm_wd_int);
   2007		else
   2008			disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
   2009		break;
   2010	case SND_SOC_DAPM_POST_PMD:
   2011		if (!wcd938x->comp1_enable)
   2012			snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
   2013						      WCD938X_GAIN_OVRD_REG_MASK, 0);
   2014		/* 7 msec delay as per HW requirement */
   2015		usleep_range(7000, 7010);
   2016		if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
   2017			snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
   2018					      WCD938X_AUX_PDM_WD_EN_MASK, 0);
   2019		else
   2020			snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
   2021					WCD938X_PDM_WD_EN_MASK, 0);
   2022
   2023		wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
   2024					WCD_CLSH_STATE_EAR, hph_mode);
   2025
   2026		wcd938x->flyback_cur_det_disable--;
   2027		if (wcd938x->flyback_cur_det_disable == 0)
   2028			snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
   2029						      WCD938X_EN_CUR_DET_MASK, 1);
   2030		break;
   2031	}
   2032
   2033	return 0;
   2034}
   2035
   2036static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
   2037				     struct snd_kcontrol *kcontrol,
   2038				     int event)
   2039{
   2040	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   2041	u16 dmic_clk_reg, dmic_clk_en_reg;
   2042	u8 dmic_sel_mask, dmic_clk_mask;
   2043
   2044	switch (w->shift) {
   2045	case 0:
   2046	case 1:
   2047		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
   2048		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL;
   2049		dmic_clk_mask = WCD938X_DMIC1_RATE_MASK;
   2050		dmic_sel_mask = WCD938X_AMIC1_IN_SEL_MASK;
   2051		break;
   2052	case 2:
   2053	case 3:
   2054		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
   2055		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL;
   2056		dmic_clk_mask = WCD938X_DMIC2_RATE_MASK;
   2057		dmic_sel_mask = WCD938X_AMIC3_IN_SEL_MASK;
   2058		break;
   2059	case 4:
   2060	case 5:
   2061		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
   2062		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL;
   2063		dmic_clk_mask = WCD938X_DMIC3_RATE_MASK;
   2064		dmic_sel_mask = WCD938X_AMIC4_IN_SEL_MASK;
   2065		break;
   2066	case 6:
   2067	case 7:
   2068		dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
   2069		dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL;
   2070		dmic_clk_mask = WCD938X_DMIC4_RATE_MASK;
   2071		dmic_sel_mask = WCD938X_AMIC5_IN_SEL_MASK;
   2072		break;
   2073	default:
   2074		dev_err(component->dev, "%s: Invalid DMIC Selection\n",
   2075			__func__);
   2076		return -EINVAL;
   2077	}
   2078
   2079	switch (event) {
   2080	case SND_SOC_DAPM_PRE_PMU:
   2081		snd_soc_component_write_field(component,
   2082				WCD938X_DIGITAL_CDC_AMIC_CTL,
   2083				dmic_sel_mask,
   2084				WCD938X_AMIC1_IN_SEL_DMIC);
   2085		/* 250us sleep as per HW requirement */
   2086		usleep_range(250, 260);
   2087		/* Setting DMIC clock rate to 2.4MHz */
   2088		snd_soc_component_write_field(component, dmic_clk_reg,
   2089					      dmic_clk_mask,
   2090					      WCD938X_DMIC4_RATE_2P4MHZ);
   2091		snd_soc_component_write_field(component, dmic_clk_en_reg,
   2092					      WCD938X_DMIC_CLK_EN_MASK, 1);
   2093		/* enable clock scaling */
   2094		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_DMIC_CTL,
   2095					      WCD938X_DMIC_CLK_SCALING_EN_MASK, 0x3);
   2096		break;
   2097	case SND_SOC_DAPM_POST_PMD:
   2098		snd_soc_component_write_field(component,
   2099				WCD938X_DIGITAL_CDC_AMIC_CTL,
   2100				dmic_sel_mask, WCD938X_AMIC1_IN_SEL_AMIC);
   2101		snd_soc_component_write_field(component, dmic_clk_en_reg,
   2102					      WCD938X_DMIC_CLK_EN_MASK, 0);
   2103		break;
   2104	}
   2105	return 0;
   2106}
   2107
   2108static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
   2109			       struct snd_kcontrol *kcontrol, int event)
   2110{
   2111	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   2112	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2113	int bank;
   2114	int rate;
   2115
   2116	bank = (wcd938x_swr_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev)) ? 0 : 1;
   2117	bank = bank ? 0 : 1;
   2118
   2119	switch (event) {
   2120	case SND_SOC_DAPM_PRE_PMU:
   2121		if (strnstr(w->name, "ADC", sizeof("ADC"))) {
   2122			int i = 0, mode = 0;
   2123
   2124			if (test_bit(WCD_ADC1, &wcd938x->status_mask))
   2125				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
   2126			if (test_bit(WCD_ADC2, &wcd938x->status_mask))
   2127				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
   2128			if (test_bit(WCD_ADC3, &wcd938x->status_mask))
   2129				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
   2130			if (test_bit(WCD_ADC4, &wcd938x->status_mask))
   2131				mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];
   2132
   2133			if (mode != 0) {
   2134				for (i = 0; i < ADC_MODE_ULP2; i++) {
   2135					if (mode & (1 << i)) {
   2136						i++;
   2137						break;
   2138					}
   2139				}
   2140			}
   2141			rate = wcd938x_get_clk_rate(i);
   2142			wcd938x_set_swr_clk_rate(component, rate, bank);
   2143			/* Copy clk settings to active bank */
   2144			wcd938x_set_swr_clk_rate(component, rate, !bank);
   2145		}
   2146		break;
   2147	case SND_SOC_DAPM_POST_PMD:
   2148		if (strnstr(w->name, "ADC", sizeof("ADC"))) {
   2149			rate = wcd938x_get_clk_rate(ADC_MODE_INVALID);
   2150			wcd938x_set_swr_clk_rate(component, rate, !bank);
   2151			wcd938x_set_swr_clk_rate(component, rate, bank);
   2152		}
   2153		break;
   2154	}
   2155
   2156	return 0;
   2157}
   2158
   2159static int wcd938x_get_adc_mode(int val)
   2160{
   2161	int ret = 0;
   2162
   2163	switch (val) {
   2164	case ADC_MODE_INVALID:
   2165		ret = ADC_MODE_VAL_NORMAL;
   2166		break;
   2167	case ADC_MODE_HIFI:
   2168		ret = ADC_MODE_VAL_HIFI;
   2169		break;
   2170	case ADC_MODE_LO_HIF:
   2171		ret = ADC_MODE_VAL_LO_HIF;
   2172		break;
   2173	case ADC_MODE_NORMAL:
   2174		ret = ADC_MODE_VAL_NORMAL;
   2175		break;
   2176	case ADC_MODE_LP:
   2177		ret = ADC_MODE_VAL_LP;
   2178		break;
   2179	case ADC_MODE_ULP1:
   2180		ret = ADC_MODE_VAL_ULP1;
   2181		break;
   2182	case ADC_MODE_ULP2:
   2183		ret = ADC_MODE_VAL_ULP2;
   2184		break;
   2185	default:
   2186		ret = -EINVAL;
   2187		break;
   2188	}
   2189	return ret;
   2190}
   2191
   2192static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
   2193				    struct snd_kcontrol *kcontrol, int event)
   2194{
   2195	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   2196	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2197
   2198	switch (event) {
   2199	case SND_SOC_DAPM_PRE_PMU:
   2200		snd_soc_component_write_field(component,
   2201					      WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   2202					      WCD938X_ANA_TX_CLK_EN_MASK, 1);
   2203		snd_soc_component_write_field(component,
   2204					      WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   2205					      WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 1);
   2206		set_bit(w->shift, &wcd938x->status_mask);
   2207		break;
   2208	case SND_SOC_DAPM_POST_PMD:
   2209		snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   2210					      WCD938X_ANA_TX_CLK_EN_MASK, 0);
   2211		clear_bit(w->shift, &wcd938x->status_mask);
   2212		break;
   2213	}
   2214
   2215	return 0;
   2216}
   2217
   2218static void wcd938x_tx_channel_config(struct snd_soc_component *component,
   2219				     int channel, int mode)
   2220{
   2221	int reg, mask;
   2222
   2223	switch (channel) {
   2224	case 0:
   2225		reg = WCD938X_ANA_TX_CH2;
   2226		mask = WCD938X_HPF1_INIT_MASK;
   2227		break;
   2228	case 1:
   2229		reg = WCD938X_ANA_TX_CH2;
   2230		mask = WCD938X_HPF2_INIT_MASK;
   2231		break;
   2232	case 2:
   2233		reg = WCD938X_ANA_TX_CH4;
   2234		mask = WCD938X_HPF3_INIT_MASK;
   2235		break;
   2236	case 3:
   2237		reg = WCD938X_ANA_TX_CH4;
   2238		mask = WCD938X_HPF4_INIT_MASK;
   2239		break;
   2240	default:
   2241		return;
   2242	}
   2243
   2244	snd_soc_component_write_field(component, reg, mask, mode);
   2245}
   2246
   2247static int wcd938x_adc_enable_req(struct snd_soc_dapm_widget *w,
   2248				  struct snd_kcontrol *kcontrol, int event)
   2249{
   2250	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   2251	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2252	int mode;
   2253
   2254	switch (event) {
   2255	case SND_SOC_DAPM_PRE_PMU:
   2256		snd_soc_component_write_field(component,
   2257				WCD938X_DIGITAL_CDC_REQ_CTL,
   2258				WCD938X_FS_RATE_4P8_MASK, 1);
   2259		snd_soc_component_write_field(component,
   2260				WCD938X_DIGITAL_CDC_REQ_CTL,
   2261				WCD938X_NO_NOTCH_MASK, 0);
   2262		wcd938x_tx_channel_config(component, w->shift, 1);
   2263		mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]);
   2264		if (mode < 0) {
   2265			dev_info(component->dev, "Invalid ADC mode\n");
   2266			return -EINVAL;
   2267		}
   2268		switch (w->shift) {
   2269		case 0:
   2270			snd_soc_component_write_field(component,
   2271				WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
   2272				WCD938X_TXD0_MODE_MASK, mode);
   2273			snd_soc_component_write_field(component,
   2274						WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2275						WCD938X_TXD0_CLK_EN_MASK, 1);
   2276			break;
   2277		case 1:
   2278			snd_soc_component_write_field(component,
   2279				WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
   2280				WCD938X_TXD1_MODE_MASK, mode);
   2281			snd_soc_component_write_field(component,
   2282					      WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2283					      WCD938X_TXD1_CLK_EN_MASK, 1);
   2284			break;
   2285		case 2:
   2286			snd_soc_component_write_field(component,
   2287				WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
   2288				WCD938X_TXD2_MODE_MASK, mode);
   2289			snd_soc_component_write_field(component,
   2290				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2291				WCD938X_TXD2_CLK_EN_MASK, 1);
   2292			break;
   2293		case 3:
   2294			snd_soc_component_write_field(component,
   2295				WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
   2296				WCD938X_TXD3_MODE_MASK, mode);
   2297			snd_soc_component_write_field(component,
   2298				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2299				WCD938X_TXD3_CLK_EN_MASK, 1);
   2300			break;
   2301		default:
   2302			break;
   2303		}
   2304
   2305		wcd938x_tx_channel_config(component, w->shift, 0);
   2306		break;
   2307	case SND_SOC_DAPM_POST_PMD:
   2308		switch (w->shift) {
   2309		case 0:
   2310			snd_soc_component_write_field(component,
   2311				WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
   2312				WCD938X_TXD0_MODE_MASK, 0);
   2313			snd_soc_component_write_field(component,
   2314				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2315				WCD938X_TXD0_CLK_EN_MASK, 0);
   2316			break;
   2317		case 1:
   2318			snd_soc_component_write_field(component,
   2319				WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
   2320				WCD938X_TXD1_MODE_MASK, 0);
   2321			snd_soc_component_write_field(component,
   2322				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2323				WCD938X_TXD1_CLK_EN_MASK, 0);
   2324			break;
   2325		case 2:
   2326			snd_soc_component_write_field(component,
   2327				WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
   2328				WCD938X_TXD2_MODE_MASK, 0);
   2329			snd_soc_component_write_field(component,
   2330				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2331				WCD938X_TXD2_CLK_EN_MASK, 0);
   2332			break;
   2333		case 3:
   2334			snd_soc_component_write_field(component,
   2335				WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
   2336				WCD938X_TXD3_MODE_MASK, 0);
   2337			snd_soc_component_write_field(component,
   2338				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2339				WCD938X_TXD3_CLK_EN_MASK, 0);
   2340			break;
   2341		default:
   2342			break;
   2343		}
   2344		snd_soc_component_write_field(component,
   2345				WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   2346				WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 0);
   2347		break;
   2348	}
   2349
   2350	return 0;
   2351}
   2352
   2353static int wcd938x_micbias_control(struct snd_soc_component *component,
   2354				   int micb_num, int req, bool is_dapm)
   2355{
   2356	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2357	int micb_index = micb_num - 1;
   2358	u16 micb_reg;
   2359
   2360	switch (micb_num) {
   2361	case MIC_BIAS_1:
   2362		micb_reg = WCD938X_ANA_MICB1;
   2363		break;
   2364	case MIC_BIAS_2:
   2365		micb_reg = WCD938X_ANA_MICB2;
   2366		break;
   2367	case MIC_BIAS_3:
   2368		micb_reg = WCD938X_ANA_MICB3;
   2369		break;
   2370	case MIC_BIAS_4:
   2371		micb_reg = WCD938X_ANA_MICB4;
   2372		break;
   2373	default:
   2374		dev_err(component->dev, "%s: Invalid micbias number: %d\n",
   2375			__func__, micb_num);
   2376		return -EINVAL;
   2377	}
   2378
   2379	switch (req) {
   2380	case MICB_PULLUP_ENABLE:
   2381		wcd938x->pullup_ref[micb_index]++;
   2382		if ((wcd938x->pullup_ref[micb_index] == 1) &&
   2383		    (wcd938x->micb_ref[micb_index] == 0))
   2384			snd_soc_component_write_field(component, micb_reg,
   2385						      WCD938X_MICB_EN_MASK,
   2386						      WCD938X_MICB_PULL_UP);
   2387		break;
   2388	case MICB_PULLUP_DISABLE:
   2389		if (wcd938x->pullup_ref[micb_index] > 0)
   2390			wcd938x->pullup_ref[micb_index]--;
   2391
   2392		if ((wcd938x->pullup_ref[micb_index] == 0) &&
   2393		    (wcd938x->micb_ref[micb_index] == 0))
   2394			snd_soc_component_write_field(component, micb_reg,
   2395						      WCD938X_MICB_EN_MASK, 0);
   2396		break;
   2397	case MICB_ENABLE:
   2398		wcd938x->micb_ref[micb_index]++;
   2399		if (wcd938x->micb_ref[micb_index] == 1) {
   2400			snd_soc_component_write_field(component,
   2401				WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
   2402				WCD938X_TX_CLK_EN_MASK, 0xF);
   2403			snd_soc_component_write_field(component,
   2404				WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
   2405				WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 1);
   2406			snd_soc_component_write_field(component,
   2407			       WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL,
   2408			       WCD938X_TX_SC_CLK_EN_MASK, 1);
   2409
   2410			snd_soc_component_write_field(component, micb_reg,
   2411						      WCD938X_MICB_EN_MASK,
   2412						      WCD938X_MICB_ENABLE);
   2413			if (micb_num  == MIC_BIAS_2)
   2414				wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   2415						      WCD_EVENT_POST_MICBIAS_2_ON);
   2416		}
   2417		if (micb_num  == MIC_BIAS_2 && is_dapm)
   2418			wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   2419					      WCD_EVENT_POST_DAPM_MICBIAS_2_ON);
   2420
   2421
   2422		break;
   2423	case MICB_DISABLE:
   2424		if (wcd938x->micb_ref[micb_index] > 0)
   2425			wcd938x->micb_ref[micb_index]--;
   2426
   2427		if ((wcd938x->micb_ref[micb_index] == 0) &&
   2428		    (wcd938x->pullup_ref[micb_index] > 0))
   2429			snd_soc_component_write_field(component, micb_reg,
   2430						      WCD938X_MICB_EN_MASK,
   2431						      WCD938X_MICB_PULL_UP);
   2432		else if ((wcd938x->micb_ref[micb_index] == 0) &&
   2433			 (wcd938x->pullup_ref[micb_index] == 0)) {
   2434			if (micb_num  == MIC_BIAS_2)
   2435				wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   2436						      WCD_EVENT_PRE_MICBIAS_2_OFF);
   2437
   2438			snd_soc_component_write_field(component, micb_reg,
   2439						      WCD938X_MICB_EN_MASK, 0);
   2440			if (micb_num  == MIC_BIAS_2)
   2441				wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   2442						      WCD_EVENT_POST_MICBIAS_2_OFF);
   2443		}
   2444		if (is_dapm && micb_num  == MIC_BIAS_2)
   2445			wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
   2446					      WCD_EVENT_POST_DAPM_MICBIAS_2_OFF);
   2447		break;
   2448	}
   2449
   2450	return 0;
   2451}
   2452
   2453static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
   2454					struct snd_kcontrol *kcontrol,
   2455					int event)
   2456{
   2457	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   2458	int micb_num = w->shift;
   2459
   2460	switch (event) {
   2461	case SND_SOC_DAPM_PRE_PMU:
   2462		wcd938x_micbias_control(component, micb_num, MICB_ENABLE, true);
   2463		break;
   2464	case SND_SOC_DAPM_POST_PMU:
   2465		/* 1 msec delay as per HW requirement */
   2466		usleep_range(1000, 1100);
   2467		break;
   2468	case SND_SOC_DAPM_POST_PMD:
   2469		wcd938x_micbias_control(component, micb_num, MICB_DISABLE, true);
   2470		break;
   2471	}
   2472
   2473	return 0;
   2474}
   2475
   2476static int wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
   2477					       struct snd_kcontrol *kcontrol,
   2478					       int event)
   2479{
   2480	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
   2481	int micb_num = w->shift;
   2482
   2483	switch (event) {
   2484	case SND_SOC_DAPM_PRE_PMU:
   2485		wcd938x_micbias_control(component, micb_num,
   2486					MICB_PULLUP_ENABLE, true);
   2487		break;
   2488	case SND_SOC_DAPM_POST_PMU:
   2489		/* 1 msec delay as per HW requirement */
   2490		usleep_range(1000, 1100);
   2491		break;
   2492	case SND_SOC_DAPM_POST_PMD:
   2493		wcd938x_micbias_control(component, micb_num,
   2494					MICB_PULLUP_DISABLE, true);
   2495		break;
   2496	}
   2497
   2498	return 0;
   2499}
   2500
   2501static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol,
   2502			       struct snd_ctl_elem_value *ucontrol)
   2503{
   2504	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2505	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2506	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
   2507	int path = e->shift_l;
   2508
   2509	ucontrol->value.enumerated.item[0] = wcd938x->tx_mode[path];
   2510
   2511	return 0;
   2512}
   2513
   2514static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol,
   2515			       struct snd_ctl_elem_value *ucontrol)
   2516{
   2517	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2518	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2519	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
   2520	int path = e->shift_l;
   2521
   2522	if (wcd938x->tx_mode[path] == ucontrol->value.enumerated.item[0])
   2523		return 0;
   2524
   2525	wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0];
   2526
   2527	return 1;
   2528}
   2529
   2530static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
   2531				 struct snd_ctl_elem_value *ucontrol)
   2532{
   2533	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2534	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2535
   2536	ucontrol->value.enumerated.item[0] = wcd938x->hph_mode;
   2537
   2538	return 0;
   2539}
   2540
   2541static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
   2542				   struct snd_ctl_elem_value *ucontrol)
   2543{
   2544	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2545	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2546
   2547	if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0])
   2548		return 0;
   2549
   2550	wcd938x->hph_mode = ucontrol->value.enumerated.item[0];
   2551
   2552	return 1;
   2553}
   2554
   2555static int wcd938x_ear_pa_put_gain(struct snd_kcontrol *kcontrol,
   2556				   struct snd_ctl_elem_value *ucontrol)
   2557{
   2558	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2559	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2560
   2561	if (wcd938x->comp1_enable) {
   2562		dev_err(component->dev, "Can not set EAR PA Gain, compander1 is enabled\n");
   2563		return -EINVAL;
   2564	}
   2565
   2566	snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
   2567				      WCD938X_EAR_GAIN_MASK,
   2568				      ucontrol->value.integer.value[0]);
   2569
   2570	return 1;
   2571}
   2572
   2573static int wcd938x_get_compander(struct snd_kcontrol *kcontrol,
   2574				 struct snd_ctl_elem_value *ucontrol)
   2575{
   2576
   2577	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2578	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2579	struct soc_mixer_control *mc;
   2580	bool hphr;
   2581
   2582	mc = (struct soc_mixer_control *)(kcontrol->private_value);
   2583	hphr = mc->shift;
   2584
   2585	if (hphr)
   2586		ucontrol->value.integer.value[0] = wcd938x->comp2_enable;
   2587	else
   2588		ucontrol->value.integer.value[0] = wcd938x->comp1_enable;
   2589
   2590	return 0;
   2591}
   2592
   2593static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
   2594				 struct snd_ctl_elem_value *ucontrol)
   2595{
   2596	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2597	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2598	struct wcd938x_sdw_priv *wcd;
   2599	int value = ucontrol->value.integer.value[0];
   2600	int portidx;
   2601	struct soc_mixer_control *mc;
   2602	bool hphr;
   2603
   2604	mc = (struct soc_mixer_control *)(kcontrol->private_value);
   2605	hphr = mc->shift;
   2606
   2607	wcd = wcd938x->sdw_priv[AIF1_PB];
   2608
   2609	if (hphr)
   2610		wcd938x->comp2_enable = value;
   2611	else
   2612		wcd938x->comp1_enable = value;
   2613
   2614	portidx = wcd->ch_info[mc->reg].port_num;
   2615
   2616	if (value)
   2617		wcd938x_connect_port(wcd, portidx, mc->reg, true);
   2618	else
   2619		wcd938x_connect_port(wcd, portidx, mc->reg, false);
   2620
   2621	return 1;
   2622}
   2623
   2624static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol,
   2625			    struct snd_ctl_elem_value *ucontrol)
   2626{
   2627	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2628	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2629
   2630	ucontrol->value.integer.value[0] = wcd938x->ldoh;
   2631
   2632	return 0;
   2633}
   2634
   2635static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol,
   2636			    struct snd_ctl_elem_value *ucontrol)
   2637{
   2638	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2639	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2640
   2641	if (wcd938x->ldoh == ucontrol->value.integer.value[0])
   2642		return 0;
   2643
   2644	wcd938x->ldoh = ucontrol->value.integer.value[0];
   2645
   2646	return 1;
   2647}
   2648
   2649static int wcd938x_bcs_get(struct snd_kcontrol *kcontrol,
   2650			   struct snd_ctl_elem_value *ucontrol)
   2651{
   2652	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2653	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2654
   2655	ucontrol->value.integer.value[0] = wcd938x->bcs_dis;
   2656
   2657	return 0;
   2658}
   2659
   2660static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol,
   2661			   struct snd_ctl_elem_value *ucontrol)
   2662{
   2663	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   2664	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   2665
   2666	if (wcd938x->bcs_dis == ucontrol->value.integer.value[0])
   2667		return 0;
   2668
   2669	wcd938x->bcs_dis = ucontrol->value.integer.value[0];
   2670
   2671	return 1;
   2672}
   2673
   2674static const char * const tx_mode_mux_text_wcd9380[] = {
   2675	"ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
   2676};
   2677
   2678static const char * const tx_mode_mux_text[] = {
   2679	"ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
   2680	"ADC_ULP1", "ADC_ULP2",
   2681};
   2682
   2683static const char * const rx_hph_mode_mux_text_wcd9380[] = {
   2684	"CLS_H_INVALID", "CLS_H_INVALID_1", "CLS_H_LP", "CLS_AB",
   2685	"CLS_H_LOHIFI", "CLS_H_ULP", "CLS_H_INVALID_2", "CLS_AB_LP",
   2686	"CLS_AB_LOHIFI",
   2687};
   2688
   2689static const char * const rx_hph_mode_mux_text[] = {
   2690	"CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
   2691	"CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI",
   2692};
   2693
   2694static const char * const adc2_mux_text[] = {
   2695	"INP2", "INP3"
   2696};
   2697
   2698static const char * const adc3_mux_text[] = {
   2699	"INP4", "INP6"
   2700};
   2701
   2702static const char * const adc4_mux_text[] = {
   2703	"INP5", "INP7"
   2704};
   2705
   2706static const char * const rdac3_mux_text[] = {
   2707	"RX1", "RX3"
   2708};
   2709
   2710static const char * const hdr12_mux_text[] = {
   2711	"NO_HDR12", "HDR12"
   2712};
   2713
   2714static const char * const hdr34_mux_text[] = {
   2715	"NO_HDR34", "HDR34"
   2716};
   2717
   2718static const struct soc_enum tx0_mode_enum_wcd9380 =
   2719	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
   2720			tx_mode_mux_text_wcd9380);
   2721
   2722static const struct soc_enum tx1_mode_enum_wcd9380 =
   2723	SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
   2724			tx_mode_mux_text_wcd9380);
   2725
   2726static const struct soc_enum tx2_mode_enum_wcd9380 =
   2727	SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
   2728			tx_mode_mux_text_wcd9380);
   2729
   2730static const struct soc_enum tx3_mode_enum_wcd9380 =
   2731	SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
   2732			tx_mode_mux_text_wcd9380);
   2733
   2734static const struct soc_enum tx0_mode_enum_wcd9385 =
   2735	SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text),
   2736			tx_mode_mux_text);
   2737
   2738static const struct soc_enum tx1_mode_enum_wcd9385 =
   2739	SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text),
   2740			tx_mode_mux_text);
   2741
   2742static const struct soc_enum tx2_mode_enum_wcd9385 =
   2743	SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text),
   2744			tx_mode_mux_text);
   2745
   2746static const struct soc_enum tx3_mode_enum_wcd9385 =
   2747	SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text),
   2748			tx_mode_mux_text);
   2749
   2750static const struct soc_enum rx_hph_mode_mux_enum_wcd9380 =
   2751		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text_wcd9380),
   2752				    rx_hph_mode_mux_text_wcd9380);
   2753
   2754static const struct soc_enum rx_hph_mode_mux_enum =
   2755		SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
   2756				    rx_hph_mode_mux_text);
   2757
   2758static const struct soc_enum adc2_enum =
   2759		SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 7,
   2760				ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
   2761
   2762static const struct soc_enum adc3_enum =
   2763		SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 6,
   2764				ARRAY_SIZE(adc3_mux_text), adc3_mux_text);
   2765
   2766static const struct soc_enum adc4_enum =
   2767		SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 5,
   2768				ARRAY_SIZE(adc4_mux_text), adc4_mux_text);
   2769
   2770static const struct soc_enum hdr12_enum =
   2771		SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 4,
   2772				ARRAY_SIZE(hdr12_mux_text), hdr12_mux_text);
   2773
   2774static const struct soc_enum hdr34_enum =
   2775		SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 3,
   2776				ARRAY_SIZE(hdr34_mux_text), hdr34_mux_text);
   2777
   2778static const struct soc_enum rdac3_enum =
   2779		SOC_ENUM_SINGLE(WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0,
   2780				ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text);
   2781
   2782static const struct snd_kcontrol_new adc1_switch[] = {
   2783	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2784};
   2785
   2786static const struct snd_kcontrol_new adc2_switch[] = {
   2787	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2788};
   2789
   2790static const struct snd_kcontrol_new adc3_switch[] = {
   2791	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2792};
   2793
   2794static const struct snd_kcontrol_new adc4_switch[] = {
   2795	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2796};
   2797
   2798static const struct snd_kcontrol_new dmic1_switch[] = {
   2799	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2800};
   2801
   2802static const struct snd_kcontrol_new dmic2_switch[] = {
   2803	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2804};
   2805
   2806static const struct snd_kcontrol_new dmic3_switch[] = {
   2807	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2808};
   2809
   2810static const struct snd_kcontrol_new dmic4_switch[] = {
   2811	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2812};
   2813
   2814static const struct snd_kcontrol_new dmic5_switch[] = {
   2815	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2816};
   2817
   2818static const struct snd_kcontrol_new dmic6_switch[] = {
   2819	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2820};
   2821
   2822static const struct snd_kcontrol_new dmic7_switch[] = {
   2823	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2824};
   2825
   2826static const struct snd_kcontrol_new dmic8_switch[] = {
   2827	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2828};
   2829
   2830static const struct snd_kcontrol_new ear_rdac_switch[] = {
   2831	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2832};
   2833
   2834static const struct snd_kcontrol_new aux_rdac_switch[] = {
   2835	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2836};
   2837
   2838static const struct snd_kcontrol_new hphl_rdac_switch[] = {
   2839	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2840};
   2841
   2842static const struct snd_kcontrol_new hphr_rdac_switch[] = {
   2843	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
   2844};
   2845
   2846static const struct snd_kcontrol_new tx_adc2_mux =
   2847	SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum);
   2848
   2849static const struct snd_kcontrol_new tx_adc3_mux =
   2850	SOC_DAPM_ENUM("ADC3 MUX Mux", adc3_enum);
   2851
   2852static const struct snd_kcontrol_new tx_adc4_mux =
   2853	SOC_DAPM_ENUM("ADC4 MUX Mux", adc4_enum);
   2854
   2855static const struct snd_kcontrol_new tx_hdr12_mux =
   2856	SOC_DAPM_ENUM("HDR12 MUX Mux", hdr12_enum);
   2857
   2858static const struct snd_kcontrol_new tx_hdr34_mux =
   2859	SOC_DAPM_ENUM("HDR34 MUX Mux", hdr34_enum);
   2860
   2861static const struct snd_kcontrol_new rx_rdac3_mux =
   2862	SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum);
   2863
   2864static const struct snd_kcontrol_new wcd9380_snd_controls[] = {
   2865	SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum_wcd9380,
   2866		     wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
   2867	SOC_ENUM_EXT("TX0 MODE", tx0_mode_enum_wcd9380,
   2868		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2869	SOC_ENUM_EXT("TX1 MODE", tx1_mode_enum_wcd9380,
   2870		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2871	SOC_ENUM_EXT("TX2 MODE", tx2_mode_enum_wcd9380,
   2872		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2873	SOC_ENUM_EXT("TX3 MODE", tx3_mode_enum_wcd9380,
   2874		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2875};
   2876
   2877static const struct snd_kcontrol_new wcd9385_snd_controls[] = {
   2878	SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
   2879		     wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
   2880	SOC_ENUM_EXT("TX0 MODE", tx0_mode_enum_wcd9385,
   2881		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2882	SOC_ENUM_EXT("TX1 MODE", tx1_mode_enum_wcd9385,
   2883		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2884	SOC_ENUM_EXT("TX2 MODE", tx2_mode_enum_wcd9385,
   2885		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2886	SOC_ENUM_EXT("TX3 MODE", tx3_mode_enum_wcd9385,
   2887		     wcd938x_tx_mode_get, wcd938x_tx_mode_put),
   2888};
   2889
   2890static int wcd938x_get_swr_port(struct snd_kcontrol *kcontrol,
   2891			    struct snd_ctl_elem_value *ucontrol)
   2892{
   2893	struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
   2894	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp);
   2895	struct wcd938x_sdw_priv *wcd;
   2896	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
   2897	int dai_id = mixer->shift;
   2898	int portidx, ch_idx = mixer->reg;
   2899
   2900
   2901	wcd = wcd938x->sdw_priv[dai_id];
   2902	portidx = wcd->ch_info[ch_idx].port_num;
   2903
   2904	ucontrol->value.integer.value[0] = wcd->port_enable[portidx];
   2905
   2906	return 0;
   2907}
   2908
   2909static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol,
   2910			    struct snd_ctl_elem_value *ucontrol)
   2911{
   2912	struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
   2913	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp);
   2914	struct wcd938x_sdw_priv *wcd;
   2915	struct soc_mixer_control *mixer =
   2916		(struct soc_mixer_control *)kcontrol->private_value;
   2917	int ch_idx = mixer->reg;
   2918	int portidx;
   2919	int dai_id = mixer->shift;
   2920	bool enable;
   2921
   2922	wcd = wcd938x->sdw_priv[dai_id];
   2923
   2924	portidx = wcd->ch_info[ch_idx].port_num;
   2925	if (ucontrol->value.integer.value[0])
   2926		enable = true;
   2927	else
   2928		enable = false;
   2929
   2930	wcd->port_enable[portidx] = enable;
   2931
   2932	wcd938x_connect_port(wcd, portidx, ch_idx, enable);
   2933
   2934	return 1;
   2935
   2936}
   2937
   2938/* MBHC related */
   2939static void wcd938x_mbhc_clk_setup(struct snd_soc_component *component,
   2940				   bool enable)
   2941{
   2942	snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_1,
   2943				      WCD938X_MBHC_CTL_RCO_EN_MASK, enable);
   2944}
   2945
   2946static void wcd938x_mbhc_mbhc_bias_control(struct snd_soc_component *component,
   2947					   bool enable)
   2948{
   2949	snd_soc_component_write_field(component, WCD938X_ANA_MBHC_ELECT,
   2950				      WCD938X_ANA_MBHC_BIAS_EN, enable);
   2951}
   2952
   2953static void wcd938x_mbhc_program_btn_thr(struct snd_soc_component *component,
   2954					 int *btn_low, int *btn_high,
   2955					 int num_btn, bool is_micbias)
   2956{
   2957	int i, vth;
   2958
   2959	if (num_btn > WCD_MBHC_DEF_BUTTONS) {
   2960		dev_err(component->dev, "%s: invalid number of buttons: %d\n",
   2961			__func__, num_btn);
   2962		return;
   2963	}
   2964
   2965	for (i = 0; i < num_btn; i++) {
   2966		vth = ((btn_high[i] * 2) / 25) & 0x3F;
   2967		snd_soc_component_write_field(component, WCD938X_ANA_MBHC_BTN0 + i,
   2968					   WCD938X_MBHC_BTN_VTH_MASK, vth);
   2969		dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n",
   2970			__func__, i, btn_high[i], vth);
   2971	}
   2972}
   2973
   2974static bool wcd938x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num)
   2975{
   2976	u8 val;
   2977
   2978	if (micb_num == MIC_BIAS_2) {
   2979		val = snd_soc_component_read_field(component,
   2980						   WCD938X_ANA_MICB2,
   2981						   WCD938X_ANA_MICB2_ENABLE_MASK);
   2982		if (val == WCD938X_MICB_ENABLE)
   2983			return true;
   2984	}
   2985	return false;
   2986}
   2987
   2988static void wcd938x_mbhc_hph_l_pull_up_control(struct snd_soc_component *component,
   2989							int pull_up_cur)
   2990{
   2991	/* Default pull up current to 2uA */
   2992	if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA)
   2993		pull_up_cur = HS_PULLUP_I_2P0_UA;
   2994
   2995	snd_soc_component_write_field(component,
   2996				      WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT,
   2997				      WCD938X_HSDET_PULLUP_C_MASK, pull_up_cur);
   2998}
   2999
   3000static int wcd938x_mbhc_request_micbias(struct snd_soc_component *component,
   3001					int micb_num, int req)
   3002{
   3003	return wcd938x_micbias_control(component, micb_num, req, false);
   3004}
   3005
   3006static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component,
   3007					   bool enable)
   3008{
   3009	if (enable) {
   3010		snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
   3011				    WCD938X_RAMP_SHIFT_CTRL_MASK, 0x0C);
   3012		snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
   3013				    WCD938X_RAMP_EN_MASK, 1);
   3014	} else {
   3015		snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
   3016				    WCD938X_RAMP_EN_MASK, 0);
   3017		snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
   3018				    WCD938X_RAMP_SHIFT_CTRL_MASK, 0);
   3019	}
   3020}
   3021
   3022static int wcd938x_get_micb_vout_ctl_val(u32 micb_mv)
   3023{
   3024	/* min micbias voltage is 1V and maximum is 2.85V */
   3025	if (micb_mv < 1000 || micb_mv > 2850)
   3026		return -EINVAL;
   3027
   3028	return (micb_mv - 1000) / 50;
   3029}
   3030
   3031static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
   3032					    int req_volt, int micb_num)
   3033{
   3034	struct wcd938x_priv *wcd938x =  snd_soc_component_get_drvdata(component);
   3035	int cur_vout_ctl, req_vout_ctl, micb_reg, micb_en, ret = 0;
   3036
   3037	switch (micb_num) {
   3038	case MIC_BIAS_1:
   3039		micb_reg = WCD938X_ANA_MICB1;
   3040		break;
   3041	case MIC_BIAS_2:
   3042		micb_reg = WCD938X_ANA_MICB2;
   3043		break;
   3044	case MIC_BIAS_3:
   3045		micb_reg = WCD938X_ANA_MICB3;
   3046		break;
   3047	case MIC_BIAS_4:
   3048		micb_reg = WCD938X_ANA_MICB4;
   3049		break;
   3050	default:
   3051		return -EINVAL;
   3052	}
   3053	mutex_lock(&wcd938x->micb_lock);
   3054	/*
   3055	 * If requested micbias voltage is same as current micbias
   3056	 * voltage, then just return. Otherwise, adjust voltage as
   3057	 * per requested value. If micbias is already enabled, then
   3058	 * to avoid slow micbias ramp-up or down enable pull-up
   3059	 * momentarily, change the micbias value and then re-enable
   3060	 * micbias.
   3061	 */
   3062	micb_en = snd_soc_component_read_field(component, micb_reg,
   3063						WCD938X_MICB_EN_MASK);
   3064	cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
   3065						    WCD938X_MICB_VOUT_MASK);
   3066
   3067	req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt);
   3068	if (req_vout_ctl < 0) {
   3069		ret = -EINVAL;
   3070		goto exit;
   3071	}
   3072
   3073	if (cur_vout_ctl == req_vout_ctl) {
   3074		ret = 0;
   3075		goto exit;
   3076	}
   3077
   3078	if (micb_en == WCD938X_MICB_ENABLE)
   3079		snd_soc_component_write_field(component, micb_reg,
   3080					      WCD938X_MICB_EN_MASK,
   3081					      WCD938X_MICB_PULL_UP);
   3082
   3083	snd_soc_component_write_field(component, micb_reg,
   3084				      WCD938X_MICB_VOUT_MASK,
   3085				      req_vout_ctl);
   3086
   3087	if (micb_en == WCD938X_MICB_ENABLE) {
   3088		snd_soc_component_write_field(component, micb_reg,
   3089					      WCD938X_MICB_EN_MASK,
   3090					      WCD938X_MICB_ENABLE);
   3091		/*
   3092		 * Add 2ms delay as per HW requirement after enabling
   3093		 * micbias
   3094		 */
   3095		usleep_range(2000, 2100);
   3096	}
   3097exit:
   3098	mutex_unlock(&wcd938x->micb_lock);
   3099	return ret;
   3100}
   3101
   3102static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component,
   3103						int micb_num, bool req_en)
   3104{
   3105	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3106	int micb_mv;
   3107
   3108	if (micb_num != MIC_BIAS_2)
   3109		return -EINVAL;
   3110	/*
   3111	 * If device tree micbias level is already above the minimum
   3112	 * voltage needed to detect threshold microphone, then do
   3113	 * not change the micbias, just return.
   3114	 */
   3115	if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
   3116		return 0;
   3117
   3118	micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv;
   3119
   3120	return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
   3121}
   3122
   3123static inline void wcd938x_mbhc_get_result_params(struct wcd938x_priv *wcd938x,
   3124						s16 *d1_a, u16 noff,
   3125						int32_t *zdet)
   3126{
   3127	int i;
   3128	int val, val1;
   3129	s16 c1;
   3130	s32 x1, d1;
   3131	int32_t denom;
   3132	int minCode_param[] = {
   3133			3277, 1639, 820, 410, 205, 103, 52, 26
   3134	};
   3135
   3136	regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x20);
   3137	for (i = 0; i < WCD938X_ZDET_NUM_MEASUREMENTS; i++) {
   3138		regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_2, &val);
   3139		if (val & 0x80)
   3140			break;
   3141	}
   3142	val = val << 0x8;
   3143	regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_1, &val1);
   3144	val |= val1;
   3145	regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x00);
   3146	x1 = WCD938X_MBHC_GET_X1(val);
   3147	c1 = WCD938X_MBHC_GET_C1(val);
   3148	/* If ramp is not complete, give additional 5ms */
   3149	if ((c1 < 2) && x1)
   3150		usleep_range(5000, 5050);
   3151
   3152	if (!c1 || !x1) {
   3153		pr_err("%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
   3154			__func__, c1, x1);
   3155		goto ramp_down;
   3156	}
   3157	d1 = d1_a[c1];
   3158	denom = (x1 * d1) - (1 << (14 - noff));
   3159	if (denom > 0)
   3160		*zdet = (WCD938X_MBHC_ZDET_CONST * 1000) / denom;
   3161	else if (x1 < minCode_param[noff])
   3162		*zdet = WCD938X_ZDET_FLOATING_IMPEDANCE;
   3163
   3164	pr_err("%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
   3165		__func__, d1, c1, x1, *zdet);
   3166ramp_down:
   3167	i = 0;
   3168	while (x1) {
   3169		regmap_read(wcd938x->regmap,
   3170				 WCD938X_ANA_MBHC_RESULT_1, &val);
   3171		regmap_read(wcd938x->regmap,
   3172				 WCD938X_ANA_MBHC_RESULT_2, &val1);
   3173		val = val << 0x08;
   3174		val |= val1;
   3175		x1 = WCD938X_MBHC_GET_X1(val);
   3176		i++;
   3177		if (i == WCD938X_ZDET_NUM_MEASUREMENTS)
   3178			break;
   3179	}
   3180}
   3181
   3182static void wcd938x_mbhc_zdet_ramp(struct snd_soc_component *component,
   3183				 struct wcd938x_mbhc_zdet_param *zdet_param,
   3184				 int32_t *zl, int32_t *zr, s16 *d1_a)
   3185{
   3186	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3187	int32_t zdet = 0;
   3188
   3189	snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
   3190				WCD938X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl);
   3191	snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN5,
   3192				    WCD938X_VTH_MASK, zdet_param->btn5);
   3193	snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN6,
   3194				      WCD938X_VTH_MASK, zdet_param->btn6);
   3195	snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN7,
   3196				     WCD938X_VTH_MASK, zdet_param->btn7);
   3197	snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
   3198				WCD938X_ZDET_RANGE_CTL_MASK, zdet_param->noff);
   3199	snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_RAMP_CTL,
   3200				0x0F, zdet_param->nshift);
   3201
   3202	if (!zl)
   3203		goto z_right;
   3204	/* Start impedance measurement for HPH_L */
   3205	regmap_update_bits(wcd938x->regmap,
   3206			   WCD938X_ANA_MBHC_ZDET, 0x80, 0x80);
   3207	dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n",
   3208		__func__, zdet_param->noff);
   3209	wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet);
   3210	regmap_update_bits(wcd938x->regmap,
   3211			   WCD938X_ANA_MBHC_ZDET, 0x80, 0x00);
   3212
   3213	*zl = zdet;
   3214
   3215z_right:
   3216	if (!zr)
   3217		return;
   3218	/* Start impedance measurement for HPH_R */
   3219	regmap_update_bits(wcd938x->regmap,
   3220			   WCD938X_ANA_MBHC_ZDET, 0x40, 0x40);
   3221	dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n",
   3222		__func__, zdet_param->noff);
   3223	wcd938x_mbhc_get_result_params(wcd938x, d1_a, zdet_param->noff, &zdet);
   3224	regmap_update_bits(wcd938x->regmap,
   3225			   WCD938X_ANA_MBHC_ZDET, 0x40, 0x00);
   3226
   3227	*zr = zdet;
   3228}
   3229
   3230static inline void wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component,
   3231					      int32_t *z_val, int flag_l_r)
   3232{
   3233	s16 q1;
   3234	int q1_cal;
   3235
   3236	if (*z_val < (WCD938X_ZDET_VAL_400/1000))
   3237		q1 = snd_soc_component_read(component,
   3238			WCD938X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
   3239	else
   3240		q1 = snd_soc_component_read(component,
   3241			WCD938X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
   3242	if (q1 & 0x80)
   3243		q1_cal = (10000 - ((q1 & 0x7F) * 25));
   3244	else
   3245		q1_cal = (10000 + (q1 * 25));
   3246	if (q1_cal > 0)
   3247		*z_val = ((*z_val) * 10000) / q1_cal;
   3248}
   3249
   3250static void wcd938x_wcd_mbhc_calc_impedance(struct snd_soc_component *component,
   3251					    uint32_t *zl, uint32_t *zr)
   3252{
   3253	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3254	s16 reg0, reg1, reg2, reg3, reg4;
   3255	int32_t z1L, z1R, z1Ls;
   3256	int zMono, z_diff1, z_diff2;
   3257	bool is_fsm_disable = false;
   3258	struct wcd938x_mbhc_zdet_param zdet_param[] = {
   3259		{4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
   3260		{2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
   3261		{1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
   3262		{1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
   3263	};
   3264	struct wcd938x_mbhc_zdet_param *zdet_param_ptr = NULL;
   3265	s16 d1_a[][4] = {
   3266		{0, 30, 90, 30},
   3267		{0, 30, 30, 5},
   3268		{0, 30, 30, 5},
   3269		{0, 30, 30, 5},
   3270	};
   3271	s16 *d1 = NULL;
   3272
   3273	reg0 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN5);
   3274	reg1 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN6);
   3275	reg2 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN7);
   3276	reg3 = snd_soc_component_read(component, WCD938X_MBHC_CTL_CLK);
   3277	reg4 = snd_soc_component_read(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL);
   3278
   3279	if (snd_soc_component_read(component, WCD938X_ANA_MBHC_ELECT) & 0x80) {
   3280		is_fsm_disable = true;
   3281		regmap_update_bits(wcd938x->regmap,
   3282				   WCD938X_ANA_MBHC_ELECT, 0x80, 0x00);
   3283	}
   3284
   3285	/* For NO-jack, disable L_DET_EN before Z-det measurements */
   3286	if (wcd938x->mbhc_cfg.hphl_swh)
   3287		regmap_update_bits(wcd938x->regmap,
   3288				   WCD938X_ANA_MBHC_MECH, 0x80, 0x00);
   3289
   3290	/* Turn off 100k pull down on HPHL */
   3291	regmap_update_bits(wcd938x->regmap,
   3292			   WCD938X_ANA_MBHC_MECH, 0x01, 0x00);
   3293
   3294	/* Disable surge protection before impedance detection.
   3295	 * This is done to give correct value for high impedance.
   3296	 */
   3297	regmap_update_bits(wcd938x->regmap,
   3298			   WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
   3299	/* 1ms delay needed after disable surge protection */
   3300	usleep_range(1000, 1010);
   3301
   3302	/* First get impedance on Left */
   3303	d1 = d1_a[1];
   3304	zdet_param_ptr = &zdet_param[1];
   3305	wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
   3306
   3307	if (!WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
   3308		goto left_ch_impedance;
   3309
   3310	/* Second ramp for left ch */
   3311	if (z1L < WCD938X_ZDET_VAL_32) {
   3312		zdet_param_ptr = &zdet_param[0];
   3313		d1 = d1_a[0];
   3314	} else if ((z1L > WCD938X_ZDET_VAL_400) &&
   3315		  (z1L <= WCD938X_ZDET_VAL_1200)) {
   3316		zdet_param_ptr = &zdet_param[2];
   3317		d1 = d1_a[2];
   3318	} else if (z1L > WCD938X_ZDET_VAL_1200) {
   3319		zdet_param_ptr = &zdet_param[3];
   3320		d1 = d1_a[3];
   3321	}
   3322	wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
   3323
   3324left_ch_impedance:
   3325	if ((z1L == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
   3326		(z1L > WCD938X_ZDET_VAL_100K)) {
   3327		*zl = WCD938X_ZDET_FLOATING_IMPEDANCE;
   3328		zdet_param_ptr = &zdet_param[1];
   3329		d1 = d1_a[1];
   3330	} else {
   3331		*zl = z1L/1000;
   3332		wcd938x_wcd_mbhc_qfuse_cal(component, zl, 0);
   3333	}
   3334	dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
   3335		__func__, *zl);
   3336
   3337	/* Start of right impedance ramp and calculation */
   3338	wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
   3339	if (WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
   3340		if (((z1R > WCD938X_ZDET_VAL_1200) &&
   3341			(zdet_param_ptr->noff == 0x6)) ||
   3342			((*zl) != WCD938X_ZDET_FLOATING_IMPEDANCE))
   3343			goto right_ch_impedance;
   3344		/* Second ramp for right ch */
   3345		if (z1R < WCD938X_ZDET_VAL_32) {
   3346			zdet_param_ptr = &zdet_param[0];
   3347			d1 = d1_a[0];
   3348		} else if ((z1R > WCD938X_ZDET_VAL_400) &&
   3349			(z1R <= WCD938X_ZDET_VAL_1200)) {
   3350			zdet_param_ptr = &zdet_param[2];
   3351			d1 = d1_a[2];
   3352		} else if (z1R > WCD938X_ZDET_VAL_1200) {
   3353			zdet_param_ptr = &zdet_param[3];
   3354			d1 = d1_a[3];
   3355		}
   3356		wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
   3357	}
   3358right_ch_impedance:
   3359	if ((z1R == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
   3360		(z1R > WCD938X_ZDET_VAL_100K)) {
   3361		*zr = WCD938X_ZDET_FLOATING_IMPEDANCE;
   3362	} else {
   3363		*zr = z1R/1000;
   3364		wcd938x_wcd_mbhc_qfuse_cal(component, zr, 1);
   3365	}
   3366	dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
   3367		__func__, *zr);
   3368
   3369	/* Mono/stereo detection */
   3370	if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) &&
   3371		(*zr == WCD938X_ZDET_FLOATING_IMPEDANCE)) {
   3372		dev_dbg(component->dev,
   3373			"%s: plug type is invalid or extension cable\n",
   3374			__func__);
   3375		goto zdet_complete;
   3376	}
   3377	if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
   3378	    (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
   3379	    ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
   3380	    ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
   3381		dev_dbg(component->dev,
   3382			"%s: Mono plug type with one ch floating or shorted to GND\n",
   3383			__func__);
   3384		wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
   3385		goto zdet_complete;
   3386	}
   3387	snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
   3388				      WCD938X_HPHPA_GND_OVR_MASK, 1);
   3389	snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
   3390				      WCD938X_HPHPA_GND_R_MASK, 1);
   3391	if (*zl < (WCD938X_ZDET_VAL_32/1000))
   3392		wcd938x_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, NULL, d1);
   3393	else
   3394		wcd938x_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, NULL, d1);
   3395	snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
   3396				      WCD938X_HPHPA_GND_R_MASK, 0);
   3397	snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
   3398				      WCD938X_HPHPA_GND_OVR_MASK, 0);
   3399	z1Ls /= 1000;
   3400	wcd938x_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
   3401	/* Parallel of left Z and 9 ohm pull down resistor */
   3402	zMono = ((*zl) * 9) / ((*zl) + 9);
   3403	z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
   3404	z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
   3405	if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
   3406		dev_dbg(component->dev, "%s: stereo plug type detected\n",
   3407			__func__);
   3408		wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_STEREO);
   3409	} else {
   3410		dev_dbg(component->dev, "%s: MONO plug type detected\n",
   3411			__func__);
   3412		wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
   3413	}
   3414
   3415	/* Enable surge protection again after impedance detection */
   3416	regmap_update_bits(wcd938x->regmap,
   3417			   WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
   3418zdet_complete:
   3419	snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN5, reg0);
   3420	snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN6, reg1);
   3421	snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN7, reg2);
   3422	/* Turn on 100k pull down on HPHL */
   3423	regmap_update_bits(wcd938x->regmap,
   3424			   WCD938X_ANA_MBHC_MECH, 0x01, 0x01);
   3425
   3426	/* For NO-jack, re-enable L_DET_EN after Z-det measurements */
   3427	if (wcd938x->mbhc_cfg.hphl_swh)
   3428		regmap_update_bits(wcd938x->regmap,
   3429				   WCD938X_ANA_MBHC_MECH, 0x80, 0x80);
   3430
   3431	snd_soc_component_write(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, reg4);
   3432	snd_soc_component_write(component, WCD938X_MBHC_CTL_CLK, reg3);
   3433	if (is_fsm_disable)
   3434		regmap_update_bits(wcd938x->regmap,
   3435				   WCD938X_ANA_MBHC_ELECT, 0x80, 0x80);
   3436}
   3437
   3438static void wcd938x_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
   3439			bool enable)
   3440{
   3441	if (enable) {
   3442		snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
   3443					      WCD938X_MBHC_HSG_PULLUP_COMP_EN, 1);
   3444		snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
   3445					      WCD938X_MBHC_GND_DET_EN_MASK, 1);
   3446	} else {
   3447		snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
   3448					      WCD938X_MBHC_GND_DET_EN_MASK, 0);
   3449		snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
   3450					      WCD938X_MBHC_HSG_PULLUP_COMP_EN, 0);
   3451	}
   3452}
   3453
   3454static void wcd938x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
   3455					  bool enable)
   3456{
   3457	snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
   3458				      WCD938X_HPHPA_GND_R_MASK, enable);
   3459	snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
   3460				      WCD938X_HPHPA_GND_L_MASK, enable);
   3461}
   3462
   3463static void wcd938x_mbhc_moisture_config(struct snd_soc_component *component)
   3464{
   3465	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3466
   3467	if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
   3468		snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3469				    WCD938X_M_RTH_CTL_MASK, R_OFF);
   3470		return;
   3471	}
   3472
   3473	/* Do not enable moisture detection if jack type is NC */
   3474	if (!wcd938x->mbhc_cfg.hphl_swh) {
   3475		dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
   3476			__func__);
   3477		snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3478				    WCD938X_M_RTH_CTL_MASK, R_OFF);
   3479		return;
   3480	}
   3481
   3482	snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3483			    WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
   3484}
   3485
   3486static void wcd938x_mbhc_moisture_detect_en(struct snd_soc_component *component, bool enable)
   3487{
   3488	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3489
   3490	if (enable)
   3491		snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3492					WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
   3493	else
   3494		snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3495				    WCD938X_M_RTH_CTL_MASK, R_OFF);
   3496}
   3497
   3498static bool wcd938x_mbhc_get_moisture_status(struct snd_soc_component *component)
   3499{
   3500	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3501	bool ret = false;
   3502
   3503	if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
   3504		snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3505				    WCD938X_M_RTH_CTL_MASK, R_OFF);
   3506		goto done;
   3507	}
   3508
   3509	/* Do not enable moisture detection if jack type is NC */
   3510	if (!wcd938x->mbhc_cfg.hphl_swh) {
   3511		dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
   3512			__func__);
   3513		snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
   3514				    WCD938X_M_RTH_CTL_MASK, R_OFF);
   3515		goto done;
   3516	}
   3517
   3518	/*
   3519	 * If moisture_en is already enabled, then skip to plug type
   3520	 * detection.
   3521	 */
   3522	if (snd_soc_component_read_field(component, WCD938X_MBHC_NEW_CTL_2, WCD938X_M_RTH_CTL_MASK))
   3523		goto done;
   3524
   3525	wcd938x_mbhc_moisture_detect_en(component, true);
   3526	/* Read moisture comparator status */
   3527	ret = ((snd_soc_component_read(component, WCD938X_MBHC_NEW_FSM_STATUS)
   3528				& 0x20) ? 0 : 1);
   3529
   3530done:
   3531	return ret;
   3532
   3533}
   3534
   3535static void wcd938x_mbhc_moisture_polling_ctrl(struct snd_soc_component *component,
   3536						bool enable)
   3537{
   3538	snd_soc_component_write_field(component,
   3539			      WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL,
   3540			      WCD938X_MOISTURE_EN_POLLING_MASK, enable);
   3541}
   3542
   3543static const struct wcd_mbhc_cb mbhc_cb = {
   3544	.clk_setup = wcd938x_mbhc_clk_setup,
   3545	.mbhc_bias = wcd938x_mbhc_mbhc_bias_control,
   3546	.set_btn_thr = wcd938x_mbhc_program_btn_thr,
   3547	.micbias_enable_status = wcd938x_mbhc_micb_en_status,
   3548	.hph_pull_up_control_v2 = wcd938x_mbhc_hph_l_pull_up_control,
   3549	.mbhc_micbias_control = wcd938x_mbhc_request_micbias,
   3550	.mbhc_micb_ramp_control = wcd938x_mbhc_micb_ramp_control,
   3551	.mbhc_micb_ctrl_thr_mic = wcd938x_mbhc_micb_ctrl_threshold_mic,
   3552	.compute_impedance = wcd938x_wcd_mbhc_calc_impedance,
   3553	.mbhc_gnd_det_ctrl = wcd938x_mbhc_gnd_det_ctrl,
   3554	.hph_pull_down_ctrl = wcd938x_mbhc_hph_pull_down_ctrl,
   3555	.mbhc_moisture_config = wcd938x_mbhc_moisture_config,
   3556	.mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
   3557	.mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
   3558	.mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
   3559};
   3560
   3561static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
   3562			      struct snd_ctl_elem_value *ucontrol)
   3563{
   3564	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
   3565	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3566
   3567	ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd938x->wcd_mbhc);
   3568
   3569	return 0;
   3570}
   3571
   3572static int wcd938x_hph_impedance_get(struct snd_kcontrol *kcontrol,
   3573				   struct snd_ctl_elem_value *ucontrol)
   3574{
   3575	uint32_t zl, zr;
   3576	bool hphr;
   3577	struct soc_mixer_control *mc;
   3578	struct snd_soc_component *component =
   3579					snd_soc_kcontrol_component(kcontrol);
   3580	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3581
   3582	mc = (struct soc_mixer_control *)(kcontrol->private_value);
   3583	hphr = mc->shift;
   3584	wcd_mbhc_get_impedance(wcd938x->wcd_mbhc, &zl, &zr);
   3585	dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
   3586	ucontrol->value.integer.value[0] = hphr ? zr : zl;
   3587
   3588	return 0;
   3589}
   3590
   3591static const struct snd_kcontrol_new hph_type_detect_controls[] = {
   3592	SOC_SINGLE_EXT("HPH Type", 0, 0, WCD_MBHC_HPH_STEREO, 0,
   3593		       wcd938x_get_hph_type, NULL),
   3594};
   3595
   3596static const struct snd_kcontrol_new impedance_detect_controls[] = {
   3597	SOC_SINGLE_EXT("HPHL Impedance", 0, 0, INT_MAX, 0,
   3598		       wcd938x_hph_impedance_get, NULL),
   3599	SOC_SINGLE_EXT("HPHR Impedance", 0, 1, INT_MAX, 0,
   3600		       wcd938x_hph_impedance_get, NULL),
   3601};
   3602
   3603static int wcd938x_mbhc_init(struct snd_soc_component *component)
   3604{
   3605	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   3606	struct wcd_mbhc_intr *intr_ids = &wcd938x->intr_ids;
   3607
   3608	intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd938x->irq_chip,
   3609						    WCD938X_IRQ_MBHC_SW_DET);
   3610	intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd938x->irq_chip,
   3611							   WCD938X_IRQ_MBHC_BUTTON_PRESS_DET);
   3612	intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd938x->irq_chip,
   3613							     WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET);
   3614	intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd938x->irq_chip,
   3615							WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET);
   3616	intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd938x->irq_chip,
   3617							WCD938X_IRQ_MBHC_ELECT_INS_REM_DET);
   3618	intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
   3619						    WCD938X_IRQ_HPHL_OCP_INT);
   3620	intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
   3621						     WCD938X_IRQ_HPHR_OCP_INT);
   3622
   3623	wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
   3624
   3625	snd_soc_add_component_controls(component, impedance_detect_controls,
   3626				       ARRAY_SIZE(impedance_detect_controls));
   3627	snd_soc_add_component_controls(component, hph_type_detect_controls,
   3628				       ARRAY_SIZE(hph_type_detect_controls));
   3629
   3630	return 0;
   3631}
   3632/* END MBHC */
   3633
   3634static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
   3635	SOC_SINGLE_EXT("HPHL_COMP Switch", WCD938X_COMP_L, 0, 1, 0,
   3636		       wcd938x_get_compander, wcd938x_set_compander),
   3637	SOC_SINGLE_EXT("HPHR_COMP Switch", WCD938X_COMP_R, 1, 1, 0,
   3638		       wcd938x_get_compander, wcd938x_set_compander),
   3639	SOC_SINGLE_EXT("HPHL Switch", WCD938X_HPH_L, 0, 1, 0,
   3640		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3641	SOC_SINGLE_EXT("HPHR Switch", WCD938X_HPH_R, 0, 1, 0,
   3642		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3643	SOC_SINGLE_EXT("CLSH Switch", WCD938X_CLSH, 0, 1, 0,
   3644		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3645	SOC_SINGLE_EXT("LO Switch", WCD938X_LO, 0, 1, 0,
   3646		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3647	SOC_SINGLE_EXT("DSD_L Switch", WCD938X_DSD_L, 0, 1, 0,
   3648		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3649	SOC_SINGLE_EXT("DSD_R Switch", WCD938X_DSD_R, 0, 1, 0,
   3650		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3651	SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 0x18, 0, line_gain),
   3652	SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 0x18, 0, line_gain),
   3653	WCD938X_EAR_PA_GAIN_TLV("EAR_PA Volume", WCD938X_ANA_EAR_COMPANDER_CTL,
   3654				2, 0x10, 0, ear_pa_gain),
   3655	SOC_SINGLE_EXT("ADC1 Switch", WCD938X_ADC1, 1, 1, 0,
   3656		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3657	SOC_SINGLE_EXT("ADC2 Switch", WCD938X_ADC2, 1, 1, 0,
   3658		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3659	SOC_SINGLE_EXT("ADC3 Switch", WCD938X_ADC3, 1, 1, 0,
   3660		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3661	SOC_SINGLE_EXT("ADC4 Switch", WCD938X_ADC4, 1, 1, 0,
   3662		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3663	SOC_SINGLE_EXT("DMIC0 Switch", WCD938X_DMIC0, 1, 1, 0,
   3664		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3665	SOC_SINGLE_EXT("DMIC1 Switch", WCD938X_DMIC1, 1, 1, 0,
   3666		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3667	SOC_SINGLE_EXT("MBHC Switch", WCD938X_MBHC, 1, 1, 0,
   3668		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3669	SOC_SINGLE_EXT("DMIC2 Switch", WCD938X_DMIC2, 1, 1, 0,
   3670		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3671	SOC_SINGLE_EXT("DMIC3 Switch", WCD938X_DMIC3, 1, 1, 0,
   3672		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3673	SOC_SINGLE_EXT("DMIC4 Switch", WCD938X_DMIC4, 1, 1, 0,
   3674		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3675	SOC_SINGLE_EXT("DMIC5 Switch", WCD938X_DMIC5, 1, 1, 0,
   3676		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3677	SOC_SINGLE_EXT("DMIC6 Switch", WCD938X_DMIC6, 1, 1, 0,
   3678		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3679	SOC_SINGLE_EXT("DMIC7 Switch", WCD938X_DMIC7, 1, 1, 0,
   3680		       wcd938x_get_swr_port, wcd938x_set_swr_port),
   3681	SOC_SINGLE_EXT("LDOH Enable Switch", SND_SOC_NOPM, 0, 1, 0,
   3682		       wcd938x_ldoh_get, wcd938x_ldoh_put),
   3683	SOC_SINGLE_EXT("ADC2_BCS Disable Switch", SND_SOC_NOPM, 0, 1, 0,
   3684		       wcd938x_bcs_get, wcd938x_bcs_put),
   3685
   3686	SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, analog_gain),
   3687	SOC_SINGLE_TLV("ADC2 Volume", WCD938X_ANA_TX_CH2, 0, 20, 0, analog_gain),
   3688	SOC_SINGLE_TLV("ADC3 Volume", WCD938X_ANA_TX_CH3, 0, 20, 0, analog_gain),
   3689	SOC_SINGLE_TLV("ADC4 Volume", WCD938X_ANA_TX_CH4, 0, 20, 0, analog_gain),
   3690};
   3691
   3692static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
   3693
   3694	/*input widgets*/
   3695	SND_SOC_DAPM_INPUT("AMIC1"),
   3696	SND_SOC_DAPM_INPUT("AMIC2"),
   3697	SND_SOC_DAPM_INPUT("AMIC3"),
   3698	SND_SOC_DAPM_INPUT("AMIC4"),
   3699	SND_SOC_DAPM_INPUT("AMIC5"),
   3700	SND_SOC_DAPM_INPUT("AMIC6"),
   3701	SND_SOC_DAPM_INPUT("AMIC7"),
   3702	SND_SOC_DAPM_MIC("Analog Mic1", NULL),
   3703	SND_SOC_DAPM_MIC("Analog Mic2", NULL),
   3704	SND_SOC_DAPM_MIC("Analog Mic3", NULL),
   3705	SND_SOC_DAPM_MIC("Analog Mic4", NULL),
   3706	SND_SOC_DAPM_MIC("Analog Mic5", NULL),
   3707
   3708	/*tx widgets*/
   3709	SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
   3710			   wcd938x_codec_enable_adc,
   3711			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3712	SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0,
   3713			   wcd938x_codec_enable_adc,
   3714			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3715	SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0,
   3716			   wcd938x_codec_enable_adc,
   3717			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3718	SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 3, 0,
   3719			   wcd938x_codec_enable_adc,
   3720			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3721	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
   3722			   wcd938x_codec_enable_dmic,
   3723			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3724	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0,
   3725			   wcd938x_codec_enable_dmic,
   3726			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3727	SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0,
   3728			   wcd938x_codec_enable_dmic,
   3729			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3730	SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0,
   3731			   wcd938x_codec_enable_dmic,
   3732			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3733	SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0,
   3734			   wcd938x_codec_enable_dmic,
   3735			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3736	SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0,
   3737			   wcd938x_codec_enable_dmic,
   3738			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3739	SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 6, 0,
   3740			   wcd938x_codec_enable_dmic,
   3741			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3742	SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 7, 0,
   3743			   wcd938x_codec_enable_dmic,
   3744			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3745
   3746	SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0,
   3747			     NULL, 0, wcd938x_adc_enable_req,
   3748			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3749	SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 1, 0,
   3750			     NULL, 0, wcd938x_adc_enable_req,
   3751			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3752	SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 2, 0,
   3753			     NULL, 0, wcd938x_adc_enable_req,
   3754			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3755	SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 3, 0, NULL, 0,
   3756			     wcd938x_adc_enable_req,
   3757			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3758
   3759	SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
   3760	SND_SOC_DAPM_MUX("ADC3 MUX", SND_SOC_NOPM, 0, 0, &tx_adc3_mux),
   3761	SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux),
   3762	SND_SOC_DAPM_MUX("HDR12 MUX", SND_SOC_NOPM, 0, 0, &tx_hdr12_mux),
   3763	SND_SOC_DAPM_MUX("HDR34 MUX", SND_SOC_NOPM, 0, 0, &tx_hdr34_mux),
   3764
   3765	/*tx mixers*/
   3766	SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch,
   3767			     ARRAY_SIZE(adc1_switch), wcd938x_tx_swr_ctrl,
   3768			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3769	SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, adc2_switch,
   3770			     ARRAY_SIZE(adc2_switch), wcd938x_tx_swr_ctrl,
   3771			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3772	SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, adc3_switch,
   3773			     ARRAY_SIZE(adc3_switch), wcd938x_tx_swr_ctrl,
   3774			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3775	SND_SOC_DAPM_MIXER_E("ADC4_MIXER", SND_SOC_NOPM, 0, 0, adc4_switch,
   3776			     ARRAY_SIZE(adc4_switch), wcd938x_tx_swr_ctrl,
   3777			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3778	SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, 0, dmic1_switch,
   3779			     ARRAY_SIZE(dmic1_switch), wcd938x_tx_swr_ctrl,
   3780			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3781	SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, 0, dmic2_switch,
   3782			     ARRAY_SIZE(dmic2_switch), wcd938x_tx_swr_ctrl,
   3783			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3784	SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0, 0, dmic3_switch,
   3785			     ARRAY_SIZE(dmic3_switch), wcd938x_tx_swr_ctrl,
   3786			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3787	SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0, 0, dmic4_switch,
   3788			     ARRAY_SIZE(dmic4_switch), wcd938x_tx_swr_ctrl,
   3789			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3790	SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0, 0, dmic5_switch,
   3791			     ARRAY_SIZE(dmic5_switch), wcd938x_tx_swr_ctrl,
   3792			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3793	SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0, 0, dmic6_switch,
   3794			     ARRAY_SIZE(dmic6_switch), wcd938x_tx_swr_ctrl,
   3795			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3796	SND_SOC_DAPM_MIXER_E("DMIC7_MIXER", SND_SOC_NOPM, 0, 0, dmic7_switch,
   3797			     ARRAY_SIZE(dmic7_switch), wcd938x_tx_swr_ctrl,
   3798			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3799	SND_SOC_DAPM_MIXER_E("DMIC8_MIXER", SND_SOC_NOPM, 0, 0, dmic8_switch,
   3800			     ARRAY_SIZE(dmic8_switch), wcd938x_tx_swr_ctrl,
   3801			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
   3802	/* micbias widgets*/
   3803	SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
   3804			    wcd938x_codec_enable_micbias,
   3805			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3806			    SND_SOC_DAPM_POST_PMD),
   3807	SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
   3808			    wcd938x_codec_enable_micbias,
   3809			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3810			    SND_SOC_DAPM_POST_PMD),
   3811	SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
   3812			    wcd938x_codec_enable_micbias,
   3813			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3814			    SND_SOC_DAPM_POST_PMD),
   3815	SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0,
   3816			    wcd938x_codec_enable_micbias,
   3817			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3818			    SND_SOC_DAPM_POST_PMD),
   3819
   3820	/* micbias pull up widgets*/
   3821	SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
   3822				wcd938x_codec_enable_micbias_pullup,
   3823				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3824				SND_SOC_DAPM_POST_PMD),
   3825	SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
   3826				wcd938x_codec_enable_micbias_pullup,
   3827				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3828				SND_SOC_DAPM_POST_PMD),
   3829	SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
   3830				wcd938x_codec_enable_micbias_pullup,
   3831				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3832				SND_SOC_DAPM_POST_PMD),
   3833	SND_SOC_DAPM_SUPPLY("VA MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0,
   3834				wcd938x_codec_enable_micbias_pullup,
   3835				SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3836				SND_SOC_DAPM_POST_PMD),
   3837
   3838	/*output widgets tx*/
   3839	SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"),
   3840	SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"),
   3841	SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"),
   3842	SND_SOC_DAPM_OUTPUT("ADC4_OUTPUT"),
   3843	SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"),
   3844	SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"),
   3845	SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"),
   3846	SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"),
   3847	SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"),
   3848	SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"),
   3849	SND_SOC_DAPM_OUTPUT("DMIC7_OUTPUT"),
   3850	SND_SOC_DAPM_OUTPUT("DMIC8_OUTPUT"),
   3851
   3852	SND_SOC_DAPM_INPUT("IN1_HPHL"),
   3853	SND_SOC_DAPM_INPUT("IN2_HPHR"),
   3854	SND_SOC_DAPM_INPUT("IN3_AUX"),
   3855
   3856	/*rx widgets*/
   3857	SND_SOC_DAPM_PGA_E("EAR PGA", WCD938X_ANA_EAR, 7, 0, NULL, 0,
   3858			   wcd938x_codec_enable_ear_pa,
   3859			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3860			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3861	SND_SOC_DAPM_PGA_E("AUX PGA", WCD938X_AUX_AUXPA, 7, 0, NULL, 0,
   3862			   wcd938x_codec_enable_aux_pa,
   3863			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3864			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3865	SND_SOC_DAPM_PGA_E("HPHL PGA", WCD938X_ANA_HPH, 7, 0, NULL, 0,
   3866			   wcd938x_codec_enable_hphl_pa,
   3867			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3868			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3869	SND_SOC_DAPM_PGA_E("HPHR PGA", WCD938X_ANA_HPH, 6, 0, NULL, 0,
   3870			   wcd938x_codec_enable_hphr_pa,
   3871			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3872			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3873
   3874	SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0,
   3875			   wcd938x_codec_hphl_dac_event,
   3876			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3877			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3878	SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0,
   3879			   wcd938x_codec_hphr_dac_event,
   3880			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3881			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3882	SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0,
   3883			   wcd938x_codec_ear_dac_event,
   3884			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3885			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3886	SND_SOC_DAPM_DAC_E("RDAC4", NULL, SND_SOC_NOPM, 0, 0,
   3887			   wcd938x_codec_aux_dac_event,
   3888			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3889			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
   3890
   3891	SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux),
   3892
   3893	SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, NULL, 0),
   3894	SND_SOC_DAPM_SUPPLY("RXCLK", SND_SOC_NOPM, 0, 0,
   3895			    wcd938x_codec_enable_rxclk,
   3896			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
   3897			    SND_SOC_DAPM_POST_PMD),
   3898
   3899	SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, NULL, 0),
   3900
   3901	SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
   3902	SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
   3903	SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
   3904
   3905	/* rx mixer widgets*/
   3906	SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0,
   3907			   ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)),
   3908	SND_SOC_DAPM_MIXER("AUX_RDAC", SND_SOC_NOPM, 0, 0,
   3909			   aux_rdac_switch, ARRAY_SIZE(aux_rdac_switch)),
   3910	SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0,
   3911			   hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)),
   3912	SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0,
   3913			   hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)),
   3914
   3915	/*output widgets rx*/
   3916	SND_SOC_DAPM_OUTPUT("EAR"),
   3917	SND_SOC_DAPM_OUTPUT("AUX"),
   3918	SND_SOC_DAPM_OUTPUT("HPHL"),
   3919	SND_SOC_DAPM_OUTPUT("HPHR"),
   3920
   3921};
   3922
   3923static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
   3924	{"ADC1_OUTPUT", NULL, "ADC1_MIXER"},
   3925	{"ADC1_MIXER", "Switch", "ADC1 REQ"},
   3926	{"ADC1 REQ", NULL, "ADC1"},
   3927	{"ADC1", NULL, "AMIC1"},
   3928
   3929	{"ADC2_OUTPUT", NULL, "ADC2_MIXER"},
   3930	{"ADC2_MIXER", "Switch", "ADC2 REQ"},
   3931	{"ADC2 REQ", NULL, "ADC2"},
   3932	{"ADC2", NULL, "HDR12 MUX"},
   3933	{"HDR12 MUX", "NO_HDR12", "ADC2 MUX"},
   3934	{"HDR12 MUX", "HDR12", "AMIC1"},
   3935	{"ADC2 MUX", "INP3", "AMIC3"},
   3936	{"ADC2 MUX", "INP2", "AMIC2"},
   3937
   3938	{"ADC3_OUTPUT", NULL, "ADC3_MIXER"},
   3939	{"ADC3_MIXER", "Switch", "ADC3 REQ"},
   3940	{"ADC3 REQ", NULL, "ADC3"},
   3941	{"ADC3", NULL, "HDR34 MUX"},
   3942	{"HDR34 MUX", "NO_HDR34", "ADC3 MUX"},
   3943	{"HDR34 MUX", "HDR34", "AMIC5"},
   3944	{"ADC3 MUX", "INP4", "AMIC4"},
   3945	{"ADC3 MUX", "INP6", "AMIC6"},
   3946
   3947	{"ADC4_OUTPUT", NULL, "ADC4_MIXER"},
   3948	{"ADC4_MIXER", "Switch", "ADC4 REQ"},
   3949	{"ADC4 REQ", NULL, "ADC4"},
   3950	{"ADC4", NULL, "ADC4 MUX"},
   3951	{"ADC4 MUX", "INP5", "AMIC5"},
   3952	{"ADC4 MUX", "INP7", "AMIC7"},
   3953
   3954	{"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"},
   3955	{"DMIC1_MIXER", "Switch", "DMIC1"},
   3956
   3957	{"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"},
   3958	{"DMIC2_MIXER", "Switch", "DMIC2"},
   3959
   3960	{"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"},
   3961	{"DMIC3_MIXER", "Switch", "DMIC3"},
   3962
   3963	{"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"},
   3964	{"DMIC4_MIXER", "Switch", "DMIC4"},
   3965
   3966	{"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"},
   3967	{"DMIC5_MIXER", "Switch", "DMIC5"},
   3968
   3969	{"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"},
   3970	{"DMIC6_MIXER", "Switch", "DMIC6"},
   3971
   3972	{"DMIC7_OUTPUT", NULL, "DMIC7_MIXER"},
   3973	{"DMIC7_MIXER", "Switch", "DMIC7"},
   3974
   3975	{"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"},
   3976	{"DMIC8_MIXER", "Switch", "DMIC8"},
   3977
   3978	{"IN1_HPHL", NULL, "VDD_BUCK"},
   3979	{"IN1_HPHL", NULL, "CLS_H_PORT"},
   3980
   3981	{"RX1", NULL, "IN1_HPHL"},
   3982	{"RX1", NULL, "RXCLK"},
   3983	{"RDAC1", NULL, "RX1"},
   3984	{"HPHL_RDAC", "Switch", "RDAC1"},
   3985	{"HPHL PGA", NULL, "HPHL_RDAC"},
   3986	{"HPHL", NULL, "HPHL PGA"},
   3987
   3988	{"IN2_HPHR", NULL, "VDD_BUCK"},
   3989	{"IN2_HPHR", NULL, "CLS_H_PORT"},
   3990	{"RX2", NULL, "IN2_HPHR"},
   3991	{"RDAC2", NULL, "RX2"},
   3992	{"RX2", NULL, "RXCLK"},
   3993	{"HPHR_RDAC", "Switch", "RDAC2"},
   3994	{"HPHR PGA", NULL, "HPHR_RDAC"},
   3995	{"HPHR", NULL, "HPHR PGA"},
   3996
   3997	{"IN3_AUX", NULL, "VDD_BUCK"},
   3998	{"IN3_AUX", NULL, "CLS_H_PORT"},
   3999	{"RX3", NULL, "IN3_AUX"},
   4000	{"RDAC4", NULL, "RX3"},
   4001	{"RX3", NULL, "RXCLK"},
   4002	{"AUX_RDAC", "Switch", "RDAC4"},
   4003	{"AUX PGA", NULL, "AUX_RDAC"},
   4004	{"AUX", NULL, "AUX PGA"},
   4005
   4006	{"RDAC3_MUX", "RX3", "RX3"},
   4007	{"RDAC3_MUX", "RX1", "RX1"},
   4008	{"RDAC3", NULL, "RDAC3_MUX"},
   4009	{"EAR_RDAC", "Switch", "RDAC3"},
   4010	{"EAR PGA", NULL, "EAR_RDAC"},
   4011	{"EAR", NULL, "EAR PGA"},
   4012};
   4013
   4014static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x)
   4015{
   4016	int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
   4017
   4018	/* set micbias voltage */
   4019	vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv);
   4020	vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv);
   4021	vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv);
   4022	vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv);
   4023	if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
   4024		return -EINVAL;
   4025
   4026	regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1,
   4027			   WCD938X_MICB_VOUT_MASK, vout_ctl_1);
   4028	regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2,
   4029			   WCD938X_MICB_VOUT_MASK, vout_ctl_2);
   4030	regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3,
   4031			   WCD938X_MICB_VOUT_MASK, vout_ctl_3);
   4032	regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4,
   4033			   WCD938X_MICB_VOUT_MASK, vout_ctl_4);
   4034
   4035	return 0;
   4036}
   4037
   4038static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data)
   4039{
   4040	return IRQ_HANDLED;
   4041}
   4042
   4043static struct irq_chip wcd_irq_chip = {
   4044	.name = "WCD938x",
   4045};
   4046
   4047static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq,
   4048			irq_hw_number_t hw)
   4049{
   4050	irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq);
   4051	irq_set_nested_thread(virq, 1);
   4052	irq_set_noprobe(virq);
   4053
   4054	return 0;
   4055}
   4056
   4057static const struct irq_domain_ops wcd_domain_ops = {
   4058	.map = wcd_irq_chip_map,
   4059};
   4060
   4061static int wcd938x_irq_init(struct wcd938x_priv *wcd, struct device *dev)
   4062{
   4063
   4064	wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL);
   4065	if (!(wcd->virq)) {
   4066		dev_err(dev, "%s: Failed to add IRQ domain\n", __func__);
   4067		return -EINVAL;
   4068	}
   4069
   4070	return devm_regmap_add_irq_chip(dev, wcd->regmap,
   4071					irq_create_mapping(wcd->virq, 0),
   4072					IRQF_ONESHOT, 0, &wcd938x_regmap_irq_chip,
   4073					&wcd->irq_chip);
   4074}
   4075
   4076static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
   4077{
   4078	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
   4079	struct device *dev = component->dev;
   4080	int ret, i;
   4081
   4082	snd_soc_component_init_regmap(component, wcd938x->regmap);
   4083
   4084	wcd938x->variant = snd_soc_component_read_field(component,
   4085						 WCD938X_DIGITAL_EFUSE_REG_0,
   4086						 WCD938X_ID_MASK);
   4087
   4088	wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X);
   4089
   4090	wcd938x_io_init(wcd938x);
   4091	/* Set all interrupts as edge triggered */
   4092	for (i = 0; i < wcd938x_regmap_irq_chip.num_regs; i++) {
   4093		regmap_write(wcd938x->regmap,
   4094			     (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0);
   4095	}
   4096
   4097	wcd938x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
   4098						       WCD938X_IRQ_HPHR_PDM_WD_INT);
   4099	wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
   4100						       WCD938X_IRQ_HPHL_PDM_WD_INT);
   4101	wcd938x->aux_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
   4102						       WCD938X_IRQ_AUX_PDM_WD_INT);
   4103
   4104	/* Request for watchdog interrupt */
   4105	ret = request_threaded_irq(wcd938x->hphr_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
   4106				   IRQF_ONESHOT | IRQF_TRIGGER_RISING,
   4107				   "HPHR PDM WD INT", wcd938x);
   4108	if (ret)
   4109		dev_err(dev, "Failed to request HPHR WD interrupt (%d)\n", ret);
   4110
   4111	ret = request_threaded_irq(wcd938x->hphl_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
   4112				   IRQF_ONESHOT | IRQF_TRIGGER_RISING,
   4113				   "HPHL PDM WD INT", wcd938x);
   4114	if (ret)
   4115		dev_err(dev, "Failed to request HPHL WD interrupt (%d)\n", ret);
   4116
   4117	ret = request_threaded_irq(wcd938x->aux_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
   4118				   IRQF_ONESHOT | IRQF_TRIGGER_RISING,
   4119				   "AUX PDM WD INT", wcd938x);
   4120	if (ret)
   4121		dev_err(dev, "Failed to request Aux WD interrupt (%d)\n", ret);
   4122
   4123	/* Disable watchdog interrupt for HPH and AUX */
   4124	disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
   4125	disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
   4126	disable_irq_nosync(wcd938x->aux_pdm_wd_int);
   4127
   4128	switch (wcd938x->variant) {
   4129	case WCD9380:
   4130		ret = snd_soc_add_component_controls(component, wcd9380_snd_controls,
   4131					ARRAY_SIZE(wcd9380_snd_controls));
   4132		if (ret < 0) {
   4133			dev_err(component->dev,
   4134				"%s: Failed to add snd ctrls for variant: %d\n",
   4135				__func__, wcd938x->variant);
   4136			goto err;
   4137		}
   4138		break;
   4139	case WCD9385:
   4140		ret = snd_soc_add_component_controls(component, wcd9385_snd_controls,
   4141					ARRAY_SIZE(wcd9385_snd_controls));
   4142		if (ret < 0) {
   4143			dev_err(component->dev,
   4144				"%s: Failed to add snd ctrls for variant: %d\n",
   4145				__func__, wcd938x->variant);
   4146			goto err;
   4147		}
   4148		break;
   4149	default:
   4150		break;
   4151	}
   4152
   4153	ret = wcd938x_mbhc_init(component);
   4154	if (ret)
   4155		dev_err(component->dev,  "mbhc initialization failed\n");
   4156err:
   4157	return ret;
   4158}
   4159
   4160static int wcd938x_codec_set_jack(struct snd_soc_component *comp,
   4161				  struct snd_soc_jack *jack, void *data)
   4162{
   4163	struct wcd938x_priv *wcd = dev_get_drvdata(comp->dev);
   4164
   4165	if (jack)
   4166		return wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack);
   4167	else
   4168		wcd_mbhc_stop(wcd->wcd_mbhc);
   4169
   4170	return 0;
   4171}
   4172
   4173static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
   4174	.name = "wcd938x_codec",
   4175	.probe = wcd938x_soc_codec_probe,
   4176	.controls = wcd938x_snd_controls,
   4177	.num_controls = ARRAY_SIZE(wcd938x_snd_controls),
   4178	.dapm_widgets = wcd938x_dapm_widgets,
   4179	.num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
   4180	.dapm_routes = wcd938x_audio_map,
   4181	.num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
   4182	.set_jack = wcd938x_codec_set_jack,
   4183	.endianness = 1,
   4184};
   4185
   4186static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd)
   4187{
   4188	struct device_node *np = dev->of_node;
   4189	u32 prop_val = 0;
   4190	int rc = 0;
   4191
   4192	rc = of_property_read_u32(np, "qcom,micbias1-microvolt",  &prop_val);
   4193	if (!rc)
   4194		wcd->micb1_mv = prop_val/1000;
   4195	else
   4196		dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
   4197
   4198	rc = of_property_read_u32(np, "qcom,micbias2-microvolt",  &prop_val);
   4199	if (!rc)
   4200		wcd->micb2_mv = prop_val/1000;
   4201	else
   4202		dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
   4203
   4204	rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
   4205	if (!rc)
   4206		wcd->micb3_mv = prop_val/1000;
   4207	else
   4208		dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
   4209
   4210	rc = of_property_read_u32(np, "qcom,micbias4-microvolt",  &prop_val);
   4211	if (!rc)
   4212		wcd->micb4_mv = prop_val/1000;
   4213	else
   4214		dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
   4215}
   4216
   4217static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component, bool active)
   4218{
   4219	int value;
   4220
   4221	struct wcd938x_priv *wcd938x;
   4222
   4223	wcd938x = snd_soc_component_get_drvdata(component);
   4224
   4225	value = gpiod_get_value(wcd938x->us_euro_gpio);
   4226
   4227	gpiod_set_value(wcd938x->us_euro_gpio, !value);
   4228
   4229	return true;
   4230}
   4231
   4232
   4233static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device *dev)
   4234{
   4235	struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg;
   4236	int ret;
   4237
   4238	wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0);
   4239	if (wcd938x->reset_gpio < 0) {
   4240		dev_err(dev, "Failed to get reset gpio: err = %d\n",
   4241			wcd938x->reset_gpio);
   4242		return wcd938x->reset_gpio;
   4243	}
   4244
   4245	wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro",
   4246						GPIOD_OUT_LOW);
   4247	if (IS_ERR(wcd938x->us_euro_gpio)) {
   4248		dev_err(dev, "us-euro swap Control GPIO not found\n");
   4249		return PTR_ERR(wcd938x->us_euro_gpio);
   4250	}
   4251
   4252	cfg->swap_gnd_mic = wcd938x_swap_gnd_mic;
   4253
   4254	wcd938x->supplies[0].supply = "vdd-rxtx";
   4255	wcd938x->supplies[1].supply = "vdd-io";
   4256	wcd938x->supplies[2].supply = "vdd-buck";
   4257	wcd938x->supplies[3].supply = "vdd-mic-bias";
   4258
   4259	ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies);
   4260	if (ret) {
   4261		dev_err(dev, "Failed to get supplies: err = %d\n", ret);
   4262		return ret;
   4263	}
   4264
   4265	ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
   4266	if (ret) {
   4267		dev_err(dev, "Failed to enable supplies: err = %d\n", ret);
   4268		return ret;
   4269	}
   4270
   4271	wcd938x_dt_parse_micbias_info(dev, wcd938x);
   4272
   4273	cfg->mbhc_micbias = MIC_BIAS_2;
   4274	cfg->anc_micbias = MIC_BIAS_2;
   4275	cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
   4276	cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS;
   4277	cfg->micb_mv = wcd938x->micb2_mv;
   4278	cfg->linein_th = 5000;
   4279	cfg->hs_thr = 1700;
   4280	cfg->hph_thr = 50;
   4281
   4282	wcd_dt_parse_mbhc_data(dev, cfg);
   4283
   4284	return 0;
   4285}
   4286
   4287static int wcd938x_reset(struct wcd938x_priv *wcd938x)
   4288{
   4289	gpio_direction_output(wcd938x->reset_gpio, 0);
   4290	/* 20us sleep required after pulling the reset gpio to LOW */
   4291	usleep_range(20, 30);
   4292	gpio_set_value(wcd938x->reset_gpio, 1);
   4293	/* 20us sleep required after pulling the reset gpio to HIGH */
   4294	usleep_range(20, 30);
   4295
   4296	return 0;
   4297}
   4298
   4299static int wcd938x_codec_hw_params(struct snd_pcm_substream *substream,
   4300				struct snd_pcm_hw_params *params,
   4301				struct snd_soc_dai *dai)
   4302{
   4303	struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
   4304	struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
   4305
   4306	return wcd938x_sdw_hw_params(wcd, substream, params, dai);
   4307}
   4308
   4309static int wcd938x_codec_free(struct snd_pcm_substream *substream,
   4310			      struct snd_soc_dai *dai)
   4311{
   4312	struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
   4313	struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
   4314
   4315	return wcd938x_sdw_free(wcd, substream, dai);
   4316}
   4317
   4318static int wcd938x_codec_set_sdw_stream(struct snd_soc_dai *dai,
   4319				  void *stream, int direction)
   4320{
   4321	struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
   4322	struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
   4323
   4324	return wcd938x_sdw_set_sdw_stream(wcd, dai, stream, direction);
   4325
   4326}
   4327
   4328static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = {
   4329	.hw_params = wcd938x_codec_hw_params,
   4330	.hw_free = wcd938x_codec_free,
   4331	.set_stream = wcd938x_codec_set_sdw_stream,
   4332};
   4333
   4334static struct snd_soc_dai_driver wcd938x_dais[] = {
   4335	[0] = {
   4336		.name = "wcd938x-sdw-rx",
   4337		.playback = {
   4338			.stream_name = "WCD AIF1 Playback",
   4339			.rates = WCD938X_RATES_MASK | WCD938X_FRAC_RATES_MASK,
   4340			.formats = WCD938X_FORMATS_S16_S24_LE,
   4341			.rate_max = 192000,
   4342			.rate_min = 8000,
   4343			.channels_min = 1,
   4344			.channels_max = 2,
   4345		},
   4346		.ops = &wcd938x_sdw_dai_ops,
   4347	},
   4348	[1] = {
   4349		.name = "wcd938x-sdw-tx",
   4350		.capture = {
   4351			.stream_name = "WCD AIF1 Capture",
   4352			.rates = WCD938X_RATES_MASK,
   4353			.formats = SNDRV_PCM_FMTBIT_S16_LE,
   4354			.rate_min = 8000,
   4355			.rate_max = 192000,
   4356			.channels_min = 1,
   4357			.channels_max = 4,
   4358		},
   4359		.ops = &wcd938x_sdw_dai_ops,
   4360	},
   4361};
   4362
   4363static int wcd938x_bind(struct device *dev)
   4364{
   4365	struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
   4366	int ret;
   4367
   4368	ret = component_bind_all(dev, wcd938x);
   4369	if (ret) {
   4370		dev_err(dev, "%s: Slave bind failed, ret = %d\n",
   4371			__func__, ret);
   4372		return ret;
   4373	}
   4374
   4375	wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode);
   4376	if (!wcd938x->rxdev) {
   4377		dev_err(dev, "could not find slave with matching of node\n");
   4378		return -EINVAL;
   4379	}
   4380	wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev);
   4381	wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x;
   4382
   4383	wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode);
   4384	if (!wcd938x->txdev) {
   4385		dev_err(dev, "could not find txslave with matching of node\n");
   4386		return -EINVAL;
   4387	}
   4388	wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev);
   4389	wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x;
   4390	wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev);
   4391	if (!wcd938x->tx_sdw_dev) {
   4392		dev_err(dev, "could not get txslave with matching of dev\n");
   4393		return -EINVAL;
   4394	}
   4395
   4396	/* As TX is main CSR reg interface, which should not be suspended first.
   4397	 * expicilty add the dependency link */
   4398	if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS |
   4399			    DL_FLAG_PM_RUNTIME)) {
   4400		dev_err(dev, "could not devlink tx and rx\n");
   4401		return -EINVAL;
   4402	}
   4403
   4404	if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS |
   4405					DL_FLAG_PM_RUNTIME)) {
   4406		dev_err(dev, "could not devlink wcd and tx\n");
   4407		return -EINVAL;
   4408	}
   4409
   4410	if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS |
   4411					DL_FLAG_PM_RUNTIME)) {
   4412		dev_err(dev, "could not devlink wcd and rx\n");
   4413		return -EINVAL;
   4414	}
   4415
   4416	wcd938x->regmap = devm_regmap_init_sdw(wcd938x->tx_sdw_dev, &wcd938x_regmap_config);
   4417	if (IS_ERR(wcd938x->regmap)) {
   4418		dev_err(dev, "%s: tx csr regmap not found\n", __func__);
   4419		return PTR_ERR(wcd938x->regmap);
   4420	}
   4421
   4422	ret = wcd938x_irq_init(wcd938x, dev);
   4423	if (ret) {
   4424		dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret);
   4425		return ret;
   4426	}
   4427
   4428	wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq;
   4429	wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq;
   4430
   4431	ret = wcd938x_set_micbias_data(wcd938x);
   4432	if (ret < 0) {
   4433		dev_err(dev, "%s: bad micbias pdata\n", __func__);
   4434		return ret;
   4435	}
   4436
   4437	ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
   4438					 wcd938x_dais, ARRAY_SIZE(wcd938x_dais));
   4439	if (ret)
   4440		dev_err(dev, "%s: Codec registration failed\n",
   4441				__func__);
   4442
   4443	return ret;
   4444
   4445}
   4446
   4447static void wcd938x_unbind(struct device *dev)
   4448{
   4449	struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
   4450
   4451	device_link_remove(dev, wcd938x->txdev);
   4452	device_link_remove(dev, wcd938x->rxdev);
   4453	device_link_remove(wcd938x->rxdev, wcd938x->txdev);
   4454	snd_soc_unregister_component(dev);
   4455	component_unbind_all(dev, wcd938x);
   4456}
   4457
   4458static const struct component_master_ops wcd938x_comp_ops = {
   4459	.bind   = wcd938x_bind,
   4460	.unbind = wcd938x_unbind,
   4461};
   4462
   4463static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
   4464					struct device *dev,
   4465					struct component_match **matchptr)
   4466{
   4467	struct device_node *np;
   4468
   4469	np = dev->of_node;
   4470
   4471	wcd938x->rxnode = of_parse_phandle(np, "qcom,rx-device", 0);
   4472	if (!wcd938x->rxnode) {
   4473		dev_err(dev, "%s: Rx-device node not defined\n", __func__);
   4474		return -ENODEV;
   4475	}
   4476
   4477	of_node_get(wcd938x->rxnode);
   4478	component_match_add_release(dev, matchptr, component_release_of,
   4479				    component_compare_of, wcd938x->rxnode);
   4480
   4481	wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
   4482	if (!wcd938x->txnode) {
   4483		dev_err(dev, "%s: Tx-device node not defined\n", __func__);
   4484		return -ENODEV;
   4485	}
   4486	of_node_get(wcd938x->txnode);
   4487	component_match_add_release(dev, matchptr, component_release_of,
   4488				    component_compare_of, wcd938x->txnode);
   4489	return 0;
   4490}
   4491
   4492static int wcd938x_probe(struct platform_device *pdev)
   4493{
   4494	struct component_match *match = NULL;
   4495	struct wcd938x_priv *wcd938x = NULL;
   4496	struct device *dev = &pdev->dev;
   4497	int ret;
   4498
   4499	wcd938x = devm_kzalloc(dev, sizeof(struct wcd938x_priv),
   4500				GFP_KERNEL);
   4501	if (!wcd938x)
   4502		return -ENOMEM;
   4503
   4504	dev_set_drvdata(dev, wcd938x);
   4505	mutex_init(&wcd938x->micb_lock);
   4506
   4507	ret = wcd938x_populate_dt_data(wcd938x, dev);
   4508	if (ret) {
   4509		dev_err(dev, "%s: Fail to obtain platform data\n", __func__);
   4510		return -EINVAL;
   4511	}
   4512
   4513	ret = wcd938x_add_slave_components(wcd938x, dev, &match);
   4514	if (ret)
   4515		return ret;
   4516
   4517	wcd938x_reset(wcd938x);
   4518
   4519	ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match);
   4520	if (ret)
   4521		return ret;
   4522
   4523	pm_runtime_set_autosuspend_delay(dev, 1000);
   4524	pm_runtime_use_autosuspend(dev);
   4525	pm_runtime_mark_last_busy(dev);
   4526	pm_runtime_set_active(dev);
   4527	pm_runtime_enable(dev);
   4528	pm_runtime_idle(dev);
   4529
   4530	return 0;
   4531}
   4532
   4533static int wcd938x_remove(struct platform_device *pdev)
   4534{
   4535	component_master_del(&pdev->dev, &wcd938x_comp_ops);
   4536
   4537	return 0;
   4538}
   4539
   4540#if defined(CONFIG_OF)
   4541static const struct of_device_id wcd938x_dt_match[] = {
   4542	{ .compatible = "qcom,wcd9380-codec" },
   4543	{ .compatible = "qcom,wcd9385-codec" },
   4544	{}
   4545};
   4546MODULE_DEVICE_TABLE(of, wcd938x_dt_match);
   4547#endif
   4548
   4549static struct platform_driver wcd938x_codec_driver = {
   4550	.probe = wcd938x_probe,
   4551	.remove = wcd938x_remove,
   4552	.driver = {
   4553		.name = "wcd938x_codec",
   4554		.of_match_table = of_match_ptr(wcd938x_dt_match),
   4555		.suppress_bind_attrs = true,
   4556	},
   4557};
   4558
   4559module_platform_driver(wcd938x_codec_driver);
   4560MODULE_DESCRIPTION("WCD938X Codec driver");
   4561MODULE_LICENSE("GPL");