Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
   1// SPDX-License-Identifier: GPL-2.0-only
   2// Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
   3
   4#include <linux/component.h>
   5#include <linux/delay.h>
   6#include <linux/device.h>
   7#include <linux/gpio/consumer.h>
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/of.h>
  11#include <linux/platform_device.h>
  12#include <linux/pm_runtime.h>
  13#include <linux/regmap.h>
  14#include <linux/regulator/consumer.h>
  15#include <linux/slab.h>
  16#include <sound/jack.h>
  17#include <sound/pcm_params.h>
  18#include <sound/pcm.h>
  19#include <sound/soc-dapm.h>
  20#include <sound/soc.h>
  21#include <sound/tlv.h>
  22
  23#include "wcd-clsh-v2.h"
  24#include "wcd-mbhc-v2.h"
  25#include "wcd937x.h"
  26
  27enum {
  28	CHIPID_WCD9370 = 0,
  29	CHIPID_WCD9375 = 5,
  30};
  31
  32/* Z value defined in milliohm */
  33#define WCD937X_ZDET_VAL_32		(32000)
  34#define WCD937X_ZDET_VAL_400		(400000)
  35#define WCD937X_ZDET_VAL_1200		(1200000)
  36#define WCD937X_ZDET_VAL_100K		(100000000)
  37/* Z floating defined in ohms */
  38#define WCD937X_ZDET_FLOATING_IMPEDANCE	(0x0FFFFFFE)
  39#define WCD937X_ZDET_NUM_MEASUREMENTS	(900)
  40#define WCD937X_MBHC_GET_C1(c)		(((c) & 0xC000) >> 14)
  41#define WCD937X_MBHC_GET_X1(x)		((x) & 0x3FFF)
  42/* Z value compared in milliOhm */
  43#define WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z)	(((z) > 400000) || ((z) < 32000))
  44#define WCD937X_MBHC_ZDET_CONST		(86 * 16384)
  45#define WCD937X_MBHC_MOISTURE_RREF	R_24_KOHM
  46#define WCD_MBHC_HS_V_MAX		1600
  47#define EAR_RX_PATH_AUX			1
  48#define WCD937X_MBHC_MAX_BUTTONS	8
  49
  50#define WCD937X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
  51		       SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
  52		       SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
  53		       SNDRV_PCM_RATE_384000)
  54
  55/* Fractional Rates */
  56#define WCD937X_FRAC_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
  57			    SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800)
  58
  59#define WCD937X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
  60			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
  61
  62enum {
  63	ALLOW_BUCK_DISABLE,
  64	HPH_COMP_DELAY,
  65	HPH_PA_DELAY,
  66	AMIC2_BCS_ENABLE,
  67};
  68
  69enum {
  70	AIF1_PB = 0,
  71	AIF1_CAP,
  72	NUM_CODEC_DAIS,
  73};
  74
  75struct wcd937x_priv {
  76	struct sdw_slave *tx_sdw_dev;
  77	struct wcd937x_sdw_priv *sdw_priv[NUM_CODEC_DAIS];
  78	struct device *txdev;
  79	struct device *rxdev;
  80	struct device_node *rxnode;
  81	struct device_node *txnode;
  82	struct regmap *regmap;
  83	/* micb setup lock */
  84	struct mutex micb_lock;
  85	/* mbhc module */
  86	struct wcd_mbhc *wcd_mbhc;
  87	struct wcd_mbhc_config mbhc_cfg;
  88	struct wcd_mbhc_intr intr_ids;
  89	struct wcd_clsh_ctrl *clsh_info;
  90	struct irq_domain *virq;
  91	struct regmap_irq_chip *wcd_regmap_irq_chip;
  92	struct regmap_irq_chip_data *irq_chip;
  93	struct regulator_bulk_data supplies[WCD937X_MAX_BULK_SUPPLY];
  94	struct regulator *buck_supply;
  95	struct snd_soc_jack *jack;
  96	unsigned long status_mask;
  97	s32 micb_ref[WCD937X_MAX_MICBIAS];
  98	s32 pullup_ref[WCD937X_MAX_MICBIAS];
  99	u32 hph_mode;
 100	int ear_rx_path;
 101	u32 micb1_mv;
 102	u32 micb2_mv;
 103	u32 micb3_mv;
 104	int hphr_pdm_wd_int;
 105	int hphl_pdm_wd_int;
 106	int aux_pdm_wd_int;
 107	bool comp1_enable;
 108	bool comp2_enable;
 109
 110	struct gpio_desc *us_euro_gpio;
 111	struct gpio_desc *reset_gpio;
 112
 113	atomic_t rx_clk_cnt;
 114	atomic_t ana_clk_count;
 115};
 116
 117static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
 118static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
 119static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
 120
 121struct wcd937x_mbhc_zdet_param {
 122	u16 ldo_ctl;
 123	u16 noff;
 124	u16 nshift;
 125	u16 btn5;
 126	u16 btn6;
 127	u16 btn7;
 128};
 129
 130static const struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = {
 131	WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD937X_ANA_MBHC_MECH, 0x80),
 132	WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD937X_ANA_MBHC_MECH, 0x40),
 133	WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD937X_ANA_MBHC_MECH, 0x20),
 134	WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0x30),
 135	WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, WCD937X_ANA_MBHC_ELECT, 0x08),
 136	WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F),
 137	WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, WCD937X_ANA_MBHC_MECH, 0x04),
 138	WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, WCD937X_ANA_MBHC_MECH, 0x10),
 139	WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, WCD937X_ANA_MBHC_MECH, 0x08),
 140	WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, WCD937X_ANA_MBHC_MECH, 0x01),
 141	WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, WCD937X_ANA_MBHC_ELECT, 0x06),
 142	WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, WCD937X_ANA_MBHC_ELECT, 0x80),
 143	WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F),
 144	WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, WCD937X_MBHC_NEW_CTL_1, 0x03),
 145	WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, WCD937X_MBHC_NEW_CTL_2, 0x03),
 146	WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, WCD937X_ANA_MBHC_RESULT_3, 0x08),
 147	WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, WCD937X_ANA_MBHC_RESULT_3, 0x10),
 148	WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, WCD937X_ANA_MBHC_RESULT_3, 0x20),
 149	WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, WCD937X_ANA_MBHC_RESULT_3, 0x80),
 150	WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, WCD937X_ANA_MBHC_RESULT_3, 0x40),
 151	WCD_MBHC_FIELD(WCD_MBHC_OCP_FSM_EN, WCD937X_HPH_OCP_CTL, 0x10),
 152	WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, WCD937X_ANA_MBHC_RESULT_3, 0x07),
 153	WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, WCD937X_ANA_MBHC_ELECT, 0x70),
 154	WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, WCD937X_ANA_MBHC_RESULT_3, 0xFF),
 155	WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, WCD937X_ANA_MICB2, 0xC0),
 156	WCD_MBHC_FIELD(WCD_MBHC_HPH_CNP_WG_TIME, WCD937X_HPH_CNP_WG_TIME, 0xFF),
 157	WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, WCD937X_ANA_HPH, 0x40),
 158	WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, WCD937X_ANA_HPH, 0x80),
 159	WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, WCD937X_ANA_HPH, 0xC0),
 160	WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, WCD937X_ANA_MBHC_RESULT_3, 0x10),
 161	WCD_MBHC_FIELD(WCD_MBHC_ANC_DET_EN, WCD937X_MBHC_CTL_BCS, 0x02),
 162	WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, WCD937X_MBHC_NEW_FSM_STATUS, 0x01),
 163	WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, WCD937X_MBHC_NEW_CTL_2, 0x70),
 164	WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, WCD937X_MBHC_NEW_FSM_STATUS, 0x20),
 165	WCD_MBHC_FIELD(WCD_MBHC_HPHR_GND, WCD937X_HPH_PA_CTL2, 0x40),
 166	WCD_MBHC_FIELD(WCD_MBHC_HPHL_GND, WCD937X_HPH_PA_CTL2, 0x10),
 167	WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, WCD937X_HPH_L_TEST, 0x01),
 168	WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, WCD937X_HPH_R_TEST, 0x01),
 169	WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, WCD937X_DIGITAL_INTR_STATUS_0, 0x80),
 170	WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, WCD937X_DIGITAL_INTR_STATUS_0, 0x20),
 171	WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, WCD937X_MBHC_NEW_CTL_1, 0x08),
 172	WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, WCD937X_MBHC_NEW_FSM_STATUS, 0x40),
 173	WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, WCD937X_MBHC_NEW_FSM_STATUS, 0x80),
 174	WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, WCD937X_MBHC_NEW_ADC_RESULT, 0xFF),
 175	WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, WCD937X_ANA_MICB2, 0x3F),
 176	WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, WCD937X_MBHC_NEW_CTL_1, 0x10),
 177	WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, WCD937X_MBHC_NEW_CTL_1, 0x04),
 178	WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, WCD937X_ANA_MBHC_ZDET, 0x02),
 179};
 180
 181static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = {
 182	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, BIT(0)),
 183	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, BIT(1)),
 184	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_ELECT_INS_REM_DET, 0, BIT(2)),
 185	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, BIT(3)),
 186	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_SW_DET, 0, BIT(4)),
 187	REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_OCP_INT, 0, BIT(5)),
 188	REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_CNP_INT, 0, BIT(6)),
 189	REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_OCP_INT, 0, BIT(7)),
 190	REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_CNP_INT, 1, BIT(0)),
 191	REGMAP_IRQ_REG(WCD937X_IRQ_EAR_CNP_INT, 1, BIT(1)),
 192	REGMAP_IRQ_REG(WCD937X_IRQ_EAR_SCD_INT, 1, BIT(2)),
 193	REGMAP_IRQ_REG(WCD937X_IRQ_AUX_CNP_INT, 1, BIT(3)),
 194	REGMAP_IRQ_REG(WCD937X_IRQ_AUX_SCD_INT, 1, BIT(4)),
 195	REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_PDM_WD_INT, 1, BIT(5)),
 196	REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_PDM_WD_INT, 1, BIT(6)),
 197	REGMAP_IRQ_REG(WCD937X_IRQ_AUX_PDM_WD_INT, 1, BIT(7)),
 198	REGMAP_IRQ_REG(WCD937X_IRQ_LDORT_SCD_INT, 2, BIT(0)),
 199	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_MOISTURE_INT, 2, BIT(1)),
 200	REGMAP_IRQ_REG(WCD937X_IRQ_HPHL_SURGE_DET_INT, 2, BIT(2)),
 201	REGMAP_IRQ_REG(WCD937X_IRQ_HPHR_SURGE_DET_INT, 2, BIT(3)),
 202};
 203
 204static int wcd937x_handle_post_irq(void *data)
 205{
 206	struct wcd937x_priv *wcd937x;
 207
 208	if (data)
 209		wcd937x = (struct wcd937x_priv *)data;
 210	else
 211		return IRQ_HANDLED;
 212
 213	regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_0, 0);
 214	regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_1, 0);
 215	regmap_write(wcd937x->regmap, WCD937X_DIGITAL_INTR_CLEAR_2, 0);
 216
 217	return IRQ_HANDLED;
 218}
 219
 220static const u32 wcd937x_config_regs[] = {
 221	WCD937X_DIGITAL_INTR_LEVEL_0,
 222};
 223
 224static const struct regmap_irq_chip wcd937x_regmap_irq_chip = {
 225	.name = "wcd937x",
 226	.irqs = wcd937x_irqs,
 227	.num_irqs = ARRAY_SIZE(wcd937x_irqs),
 228	.num_regs = 3,
 229	.status_base = WCD937X_DIGITAL_INTR_STATUS_0,
 230	.mask_base = WCD937X_DIGITAL_INTR_MASK_0,
 231	.ack_base = WCD937X_DIGITAL_INTR_CLEAR_0,
 232	.use_ack = 1,
 233	.clear_ack = 1,
 234	.config_base = wcd937x_config_regs,
 235	.num_config_bases = ARRAY_SIZE(wcd937x_config_regs),
 236	.num_config_regs = 1,
 237	.runtime_pm = true,
 238	.handle_post_irq = wcd937x_handle_post_irq,
 239	.irq_drv_data = NULL,
 240};
 241
 242static void wcd937x_reset(struct wcd937x_priv *wcd937x)
 243{
 244	gpiod_set_value(wcd937x->reset_gpio, 1);
 245	usleep_range(20, 30);
 246	gpiod_set_value(wcd937x->reset_gpio, 0);
 247	usleep_range(20, 30);
 248}
 249
 250static void wcd937x_io_init(struct regmap *regmap)
 251{
 252	u32 val = 0, temp = 0, temp1 = 0;
 253
 254	regmap_read(regmap, WCD937X_DIGITAL_EFUSE_REG_29, &val);
 255
 256	val = val & 0x0F;
 257
 258	regmap_read(regmap, WCD937X_DIGITAL_EFUSE_REG_16, &temp);
 259	regmap_read(regmap, WCD937X_DIGITAL_EFUSE_REG_17, &temp1);
 260
 261	if (temp == 0x02 || temp1 > 0x09)
 262		regmap_update_bits(regmap, WCD937X_SLEEP_CTL, 0x0E, val);
 263	else
 264		regmap_update_bits(regmap, WCD937X_SLEEP_CTL, 0x0e, 0x0e);
 265
 266	regmap_update_bits(regmap, WCD937X_SLEEP_CTL, 0x80, 0x80);
 267	usleep_range(1000, 1010);
 268
 269	regmap_update_bits(regmap, WCD937X_SLEEP_CTL, 0x40, 0x40);
 270	usleep_range(1000, 1010);
 271
 272	regmap_update_bits(regmap, WCD937X_LDORXTX_CONFIG, BIT(4), 0x00);
 273	regmap_update_bits(regmap, WCD937X_BIAS_VBG_FINE_ADJ, 0xf0, BIT(7));
 274	regmap_update_bits(regmap, WCD937X_ANA_BIAS, BIT(7), BIT(7));
 275	regmap_update_bits(regmap, WCD937X_ANA_BIAS, BIT(6), BIT(6));
 276	usleep_range(10000, 10010);
 277
 278	regmap_update_bits(regmap, WCD937X_ANA_BIAS, BIT(6), 0x00);
 279	regmap_update_bits(regmap, WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xff, 0xd9);
 280	regmap_update_bits(regmap, WCD937X_MICB1_TEST_CTL_1, 0xff, 0xfa);
 281	regmap_update_bits(regmap, WCD937X_MICB2_TEST_CTL_1, 0xff, 0xfa);
 282	regmap_update_bits(regmap, WCD937X_MICB3_TEST_CTL_1, 0xff, 0xfa);
 283
 284	regmap_update_bits(regmap, WCD937X_MICB1_TEST_CTL_2, 0x38, 0x00);
 285	regmap_update_bits(regmap, WCD937X_MICB2_TEST_CTL_2, 0x38, 0x00);
 286	regmap_update_bits(regmap, WCD937X_MICB3_TEST_CTL_2, 0x38, 0x00);
 287
 288	/* Set Bandgap Fine Adjustment to +5mV for Tanggu SMIC part */
 289	regmap_read(regmap, WCD937X_DIGITAL_EFUSE_REG_16, &val);
 290	if (val == 0x01) {
 291		regmap_update_bits(regmap, WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0xB0);
 292	} else if (val == 0x02) {
 293		regmap_update_bits(regmap, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x1F, 0x04);
 294		regmap_update_bits(regmap, WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x1F, 0x04);
 295		regmap_update_bits(regmap, WCD937X_BIAS_VBG_FINE_ADJ, 0xF0, 0xB0);
 296		regmap_update_bits(regmap, WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x50);
 297	}
 298}
 299
 300static int wcd937x_rx_clk_enable(struct snd_soc_component *component)
 301{
 302	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 303
 304	if (atomic_read(&wcd937x->rx_clk_cnt))
 305		return 0;
 306
 307	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_DIG_CLK_CTL, BIT(3), BIT(3));
 308	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(0), BIT(0));
 309	snd_soc_component_update_bits(component, WCD937X_ANA_RX_SUPPLIES, BIT(0), BIT(0));
 310	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_RX0_CTL, BIT(6), 0x00);
 311	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_RX1_CTL, BIT(6), 0x00);
 312	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_RX2_CTL, BIT(6), 0x00);
 313	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(1), BIT(1));
 314
 315	atomic_inc(&wcd937x->rx_clk_cnt);
 316
 317	return 0;
 318}
 319
 320static int wcd937x_rx_clk_disable(struct snd_soc_component *component)
 321{
 322	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 323
 324	if (!atomic_read(&wcd937x->rx_clk_cnt)) {
 325		dev_err(component->dev, "clk already disabled\n");
 326		return 0;
 327	}
 328
 329	atomic_dec(&wcd937x->rx_clk_cnt);
 330
 331	snd_soc_component_update_bits(component, WCD937X_ANA_RX_SUPPLIES, BIT(0), 0x00);
 332	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(1), 0x00);
 333	snd_soc_component_update_bits(component, WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(0), 0x00);
 334
 335	return 0;
 336}
 337
 338static int wcd937x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
 339					struct snd_kcontrol *kcontrol,
 340					int event)
 341{
 342	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 343	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 344	int hph_mode = wcd937x->hph_mode;
 345
 346	switch (event) {
 347	case SND_SOC_DAPM_PRE_PMU:
 348		wcd937x_rx_clk_enable(component);
 349		snd_soc_component_update_bits(component,
 350					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 351					      BIT(0), BIT(0));
 352		snd_soc_component_update_bits(component,
 353					      WCD937X_DIGITAL_CDC_HPH_GAIN_CTL,
 354					      BIT(2), BIT(2));
 355		snd_soc_component_update_bits(component,
 356					      WCD937X_HPH_RDAC_CLK_CTL1,
 357					      BIT(7), 0x00);
 358		set_bit(HPH_COMP_DELAY, &wcd937x->status_mask);
 359		break;
 360	case SND_SOC_DAPM_POST_PMU:
 361		if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
 362			snd_soc_component_update_bits(component,
 363						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
 364						      0x0f, BIT(1));
 365		else if (hph_mode == CLS_H_LOHIFI)
 366			snd_soc_component_update_bits(component,
 367						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
 368						      0x0f, 0x06);
 369
 370		if (wcd937x->comp1_enable) {
 371			snd_soc_component_update_bits(component,
 372						      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 373						      BIT(1), BIT(1));
 374			snd_soc_component_update_bits(component,
 375						      WCD937X_HPH_L_EN,
 376						      BIT(5), 0x00);
 377
 378			if (wcd937x->comp2_enable) {
 379				snd_soc_component_update_bits(component,
 380							      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 381							      BIT(0), BIT(0));
 382				snd_soc_component_update_bits(component,
 383							      WCD937X_HPH_R_EN, BIT(5), 0x00);
 384			}
 385
 386			if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) {
 387				usleep_range(5000, 5110);
 388				clear_bit(HPH_COMP_DELAY, &wcd937x->status_mask);
 389			}
 390		} else {
 391			snd_soc_component_update_bits(component,
 392						      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 393						      BIT(1), 0x00);
 394			snd_soc_component_update_bits(component,
 395						      WCD937X_HPH_L_EN,
 396						      BIT(5), BIT(5));
 397		}
 398
 399		snd_soc_component_update_bits(component,
 400					      WCD937X_HPH_NEW_INT_HPH_TIMER1,
 401					      BIT(1), 0x00);
 402		break;
 403	case SND_SOC_DAPM_POST_PMD:
 404		snd_soc_component_update_bits(component,
 405					      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
 406					      0x0f, BIT(0));
 407		break;
 408	}
 409
 410	return 0;
 411}
 412
 413static int wcd937x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
 414					struct snd_kcontrol *kcontrol,
 415					int event)
 416{
 417	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 418	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 419	int hph_mode = wcd937x->hph_mode;
 420
 421	switch (event) {
 422	case SND_SOC_DAPM_PRE_PMU:
 423		wcd937x_rx_clk_enable(component);
 424		snd_soc_component_update_bits(component,
 425					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL, BIT(1), BIT(1));
 426		snd_soc_component_update_bits(component,
 427					      WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, BIT(3), BIT(3));
 428		snd_soc_component_update_bits(component,
 429					      WCD937X_HPH_RDAC_CLK_CTL1, BIT(7), 0x00);
 430		set_bit(HPH_COMP_DELAY, &wcd937x->status_mask);
 431		break;
 432	case SND_SOC_DAPM_POST_PMU:
 433		if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
 434			snd_soc_component_update_bits(component,
 435						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R,
 436						      0x0f, BIT(1));
 437		else if (hph_mode == CLS_H_LOHIFI)
 438			snd_soc_component_update_bits(component,
 439						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R,
 440						      0x0f, 0x06);
 441		if (wcd937x->comp2_enable) {
 442			snd_soc_component_update_bits(component,
 443						      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 444						      BIT(0), BIT(0));
 445			snd_soc_component_update_bits(component,
 446						      WCD937X_HPH_R_EN, BIT(5), 0x00);
 447			if (wcd937x->comp1_enable) {
 448				snd_soc_component_update_bits(component,
 449							      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 450							      BIT(1), BIT(1));
 451				snd_soc_component_update_bits(component,
 452							      WCD937X_HPH_L_EN,
 453							      BIT(5), 0x00);
 454			}
 455
 456			if (test_bit(HPH_COMP_DELAY, &wcd937x->status_mask)) {
 457				usleep_range(5000, 5110);
 458				clear_bit(HPH_COMP_DELAY, &wcd937x->status_mask);
 459			}
 460		} else {
 461			snd_soc_component_update_bits(component,
 462						      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 463						      BIT(0), 0x00);
 464			snd_soc_component_update_bits(component,
 465						      WCD937X_HPH_R_EN,
 466						      BIT(5), BIT(5));
 467		}
 468		snd_soc_component_update_bits(component,
 469					      WCD937X_HPH_NEW_INT_HPH_TIMER1,
 470					      BIT(1), 0x00);
 471		break;
 472	case SND_SOC_DAPM_POST_PMD:
 473		snd_soc_component_update_bits(component,
 474					      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R,
 475					      0x0f, BIT(0));
 476		break;
 477	}
 478
 479	return 0;
 480}
 481
 482static int wcd937x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
 483				       struct snd_kcontrol *kcontrol,
 484				       int event)
 485{
 486	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 487	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 488	int hph_mode = wcd937x->hph_mode;
 489
 490	switch (event) {
 491	case SND_SOC_DAPM_PRE_PMU:
 492		wcd937x_rx_clk_enable(component);
 493		snd_soc_component_update_bits(component,
 494					      WCD937X_DIGITAL_CDC_HPH_GAIN_CTL,
 495					      BIT(2), BIT(2));
 496		snd_soc_component_update_bits(component,
 497					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 498					      BIT(0), BIT(0));
 499
 500		if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_HIFI)
 501			snd_soc_component_update_bits(component,
 502						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
 503						      0x0f, BIT(1));
 504		else if (hph_mode == CLS_H_LOHIFI)
 505			snd_soc_component_update_bits(component,
 506						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
 507						      0x0f, 0x06);
 508		if (wcd937x->comp1_enable)
 509			snd_soc_component_update_bits(component,
 510						      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 511						      BIT(1), BIT(1));
 512		usleep_range(5000, 5010);
 513
 514		snd_soc_component_update_bits(component, WCD937X_FLYBACK_EN, BIT(2), 0x00);
 515		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 516					WCD_CLSH_EVENT_PRE_DAC,
 517					WCD_CLSH_STATE_EAR,
 518					hph_mode);
 519
 520		break;
 521	case SND_SOC_DAPM_POST_PMD:
 522		if (hph_mode == CLS_AB_HIFI || hph_mode == CLS_H_LOHIFI ||
 523		    hph_mode == CLS_H_HIFI)
 524			snd_soc_component_update_bits(component,
 525						      WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L,
 526						      0x0f, BIT(0));
 527		if (wcd937x->comp1_enable)
 528			snd_soc_component_update_bits(component,
 529						      WCD937X_DIGITAL_CDC_COMP_CTL_0,
 530						      BIT(1), 0x00);
 531		break;
 532	}
 533
 534	return 0;
 535}
 536
 537static int wcd937x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
 538				       struct snd_kcontrol *kcontrol,
 539				       int event)
 540{
 541	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 542	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 543	int hph_mode = wcd937x->hph_mode;
 544
 545	switch (event) {
 546	case SND_SOC_DAPM_PRE_PMU:
 547		wcd937x_rx_clk_enable(component);
 548		snd_soc_component_update_bits(component,
 549					      WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
 550					      BIT(2), BIT(2));
 551		snd_soc_component_update_bits(component,
 552					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 553					      BIT(2), BIT(2));
 554		snd_soc_component_update_bits(component,
 555					      WCD937X_DIGITAL_CDC_AUX_GAIN_CTL,
 556					      BIT(0), BIT(0));
 557		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 558					WCD_CLSH_EVENT_PRE_DAC,
 559					WCD_CLSH_STATE_AUX,
 560					hph_mode);
 561
 562		break;
 563	case SND_SOC_DAPM_POST_PMD:
 564		snd_soc_component_update_bits(component,
 565					      WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
 566					      BIT(2), 0x00);
 567		break;
 568	}
 569
 570	return 0;
 571}
 572
 573static int wcd937x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
 574					struct snd_kcontrol *kcontrol,
 575					int event)
 576{
 577	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 578	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 579	int hph_mode = wcd937x->hph_mode;
 580
 581	switch (event) {
 582	case SND_SOC_DAPM_PRE_PMU:
 583		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 584					WCD_CLSH_EVENT_PRE_DAC,
 585					WCD_CLSH_STATE_HPHR,
 586					hph_mode);
 587		snd_soc_component_update_bits(component, WCD937X_ANA_HPH,
 588					      BIT(4), BIT(4));
 589		usleep_range(100, 110);
 590		set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 591		snd_soc_component_update_bits(component,
 592					      WCD937X_DIGITAL_PDM_WD_CTL1,
 593					      0x07, 0x03);
 594		break;
 595	case SND_SOC_DAPM_POST_PMU:
 596		if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) {
 597			if (wcd937x->comp2_enable)
 598				usleep_range(7000, 7100);
 599			else
 600				usleep_range(20000, 20100);
 601			clear_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 602		}
 603
 604		snd_soc_component_update_bits(component,
 605					      WCD937X_HPH_NEW_INT_HPH_TIMER1,
 606					      BIT(1), BIT(1));
 607		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
 608			snd_soc_component_update_bits(component,
 609						      WCD937X_ANA_RX_SUPPLIES,
 610						      BIT(1), BIT(1));
 611		enable_irq(wcd937x->hphr_pdm_wd_int);
 612		break;
 613	case SND_SOC_DAPM_PRE_PMD:
 614		disable_irq_nosync(wcd937x->hphr_pdm_wd_int);
 615		set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 616		wcd_mbhc_event_notify(wcd937x->wcd_mbhc, WCD_EVENT_PRE_HPHR_PA_OFF);
 617		break;
 618	case SND_SOC_DAPM_POST_PMD:
 619		if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) {
 620			if (wcd937x->comp2_enable)
 621				usleep_range(7000, 7100);
 622			else
 623				usleep_range(20000, 20100);
 624			clear_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 625		}
 626
 627		wcd_mbhc_event_notify(wcd937x->wcd_mbhc, WCD_EVENT_POST_HPHR_PA_OFF);
 628		snd_soc_component_update_bits(component,
 629					      WCD937X_DIGITAL_PDM_WD_CTL1, 0x07, 0x00);
 630		snd_soc_component_update_bits(component, WCD937X_ANA_HPH,
 631					      BIT(4), 0x00);
 632		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 633					WCD_CLSH_EVENT_POST_PA,
 634					WCD_CLSH_STATE_HPHR,
 635					hph_mode);
 636		break;
 637	}
 638
 639	return 0;
 640}
 641
 642static int wcd937x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
 643					struct snd_kcontrol *kcontrol,
 644					int event)
 645{
 646	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 647	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 648	int hph_mode = wcd937x->hph_mode;
 649
 650	switch (event) {
 651	case SND_SOC_DAPM_PRE_PMU:
 652		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 653					WCD_CLSH_EVENT_PRE_DAC,
 654					WCD_CLSH_STATE_HPHL,
 655					hph_mode);
 656		snd_soc_component_update_bits(component, WCD937X_ANA_HPH,
 657					      BIT(5), BIT(5));
 658		usleep_range(100, 110);
 659		set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 660		snd_soc_component_update_bits(component,
 661					      WCD937X_DIGITAL_PDM_WD_CTL0, 0x07, 0x03);
 662		break;
 663	case SND_SOC_DAPM_POST_PMU:
 664		if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) {
 665			if (!wcd937x->comp1_enable)
 666				usleep_range(20000, 20100);
 667			else
 668				usleep_range(7000, 7100);
 669			clear_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 670		}
 671
 672		snd_soc_component_update_bits(component,
 673					      WCD937X_HPH_NEW_INT_HPH_TIMER1,
 674					      BIT(1), BIT(1));
 675		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
 676			snd_soc_component_update_bits(component,
 677						      WCD937X_ANA_RX_SUPPLIES,
 678						      BIT(1), BIT(1));
 679		enable_irq(wcd937x->hphl_pdm_wd_int);
 680		break;
 681	case SND_SOC_DAPM_PRE_PMD:
 682		disable_irq_nosync(wcd937x->hphl_pdm_wd_int);
 683		set_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 684		wcd_mbhc_event_notify(wcd937x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF);
 685		break;
 686	case SND_SOC_DAPM_POST_PMD:
 687		if (test_bit(HPH_PA_DELAY, &wcd937x->status_mask)) {
 688			if (!wcd937x->comp1_enable)
 689				usleep_range(20000, 20100);
 690			else
 691				usleep_range(7000, 7100);
 692			clear_bit(HPH_PA_DELAY, &wcd937x->status_mask);
 693		}
 694
 695		wcd_mbhc_event_notify(wcd937x->wcd_mbhc, WCD_EVENT_POST_HPHL_PA_OFF);
 696		snd_soc_component_update_bits(component,
 697					      WCD937X_DIGITAL_PDM_WD_CTL0, 0x07, 0x00);
 698		snd_soc_component_update_bits(component,
 699					      WCD937X_ANA_HPH, BIT(5), 0x00);
 700		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 701					WCD_CLSH_EVENT_POST_PA,
 702					WCD_CLSH_STATE_HPHL,
 703					hph_mode);
 704		break;
 705	}
 706
 707	return 0;
 708}
 709
 710static int wcd937x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
 711				       struct snd_kcontrol *kcontrol,
 712				       int event)
 713{
 714	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 715	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 716	int hph_mode = wcd937x->hph_mode;
 717	u8 val;
 718
 719	switch (event) {
 720	case SND_SOC_DAPM_PRE_PMU:
 721		val = WCD937X_DIGITAL_PDM_WD_CTL2_EN |
 722		      WCD937X_DIGITAL_PDM_WD_CTL2_TIMEOUT_SEL |
 723		      WCD937X_DIGITAL_PDM_WD_CTL2_HOLD_OFF;
 724		snd_soc_component_update_bits(component,
 725					      WCD937X_DIGITAL_PDM_WD_CTL2,
 726					      WCD937X_DIGITAL_PDM_WD_CTL2_MASK,
 727					      val);
 728		break;
 729	case SND_SOC_DAPM_POST_PMU:
 730		usleep_range(1000, 1010);
 731		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
 732			snd_soc_component_update_bits(component,
 733						      WCD937X_ANA_RX_SUPPLIES,
 734						      BIT(1), BIT(1));
 735		enable_irq(wcd937x->aux_pdm_wd_int);
 736		break;
 737	case SND_SOC_DAPM_PRE_PMD:
 738		disable_irq_nosync(wcd937x->aux_pdm_wd_int);
 739		break;
 740	case SND_SOC_DAPM_POST_PMD:
 741		usleep_range(2000, 2010);
 742		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 743					WCD_CLSH_EVENT_POST_PA,
 744					WCD_CLSH_STATE_AUX,
 745					hph_mode);
 746		snd_soc_component_update_bits(component,
 747					      WCD937X_DIGITAL_PDM_WD_CTL2,
 748					      WCD937X_DIGITAL_PDM_WD_CTL2_MASK,
 749					      0x00);
 750		break;
 751	}
 752
 753	return 0;
 754}
 755
 756static int wcd937x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
 757				       struct snd_kcontrol *kcontrol,
 758				       int event)
 759{
 760	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 761	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 762	int hph_mode = wcd937x->hph_mode;
 763
 764	switch (event) {
 765	case SND_SOC_DAPM_PRE_PMU:
 766		/* Enable watchdog interrupt for HPHL or AUX depending on mux value */
 767		wcd937x->ear_rx_path = snd_soc_component_read(component,
 768							      WCD937X_DIGITAL_CDC_EAR_PATH_CTL);
 769
 770		if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
 771			snd_soc_component_update_bits(component,
 772						      WCD937X_DIGITAL_PDM_WD_CTL2,
 773						      BIT(0), BIT(0));
 774		else
 775			snd_soc_component_update_bits(component,
 776						      WCD937X_DIGITAL_PDM_WD_CTL0,
 777						      0x07, 0x03);
 778		if (!wcd937x->comp1_enable)
 779			snd_soc_component_update_bits(component,
 780						      WCD937X_ANA_EAR_COMPANDER_CTL,
 781						      BIT(7), BIT(7));
 782		break;
 783	case SND_SOC_DAPM_POST_PMU:
 784		usleep_range(6000, 6010);
 785		if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI)
 786			snd_soc_component_update_bits(component,
 787						      WCD937X_ANA_RX_SUPPLIES,
 788						      BIT(1), BIT(1));
 789
 790		if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
 791			enable_irq(wcd937x->aux_pdm_wd_int);
 792		else
 793			enable_irq(wcd937x->hphl_pdm_wd_int);
 794		break;
 795	case SND_SOC_DAPM_PRE_PMD:
 796		if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
 797			disable_irq_nosync(wcd937x->aux_pdm_wd_int);
 798		else
 799			disable_irq_nosync(wcd937x->hphl_pdm_wd_int);
 800		break;
 801	case SND_SOC_DAPM_POST_PMD:
 802		if (!wcd937x->comp1_enable)
 803			snd_soc_component_update_bits(component,
 804						      WCD937X_ANA_EAR_COMPANDER_CTL,
 805						      BIT(7), 0x00);
 806		usleep_range(7000, 7010);
 807		wcd_clsh_ctrl_set_state(wcd937x->clsh_info,
 808					WCD_CLSH_EVENT_POST_PA,
 809					WCD_CLSH_STATE_EAR,
 810					hph_mode);
 811		snd_soc_component_update_bits(component, WCD937X_FLYBACK_EN,
 812					      BIT(2), BIT(2));
 813
 814		if (wcd937x->ear_rx_path & EAR_RX_PATH_AUX)
 815			snd_soc_component_update_bits(component,
 816						      WCD937X_DIGITAL_PDM_WD_CTL2,
 817						      BIT(0), 0x00);
 818		else
 819			snd_soc_component_update_bits(component,
 820						      WCD937X_DIGITAL_PDM_WD_CTL0,
 821						      0x07, 0x00);
 822		break;
 823	}
 824
 825	return 0;
 826}
 827
 828static int wcd937x_enable_rx1(struct snd_soc_dapm_widget *w,
 829			      struct snd_kcontrol *kcontrol,
 830			      int event)
 831{
 832	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 833
 834	if (event == SND_SOC_DAPM_POST_PMD) {
 835		wcd937x_rx_clk_disable(component);
 836		snd_soc_component_update_bits(component,
 837					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 838					      BIT(0), 0x00);
 839	}
 840
 841	return 0;
 842}
 843
 844static int wcd937x_enable_rx2(struct snd_soc_dapm_widget *w,
 845			      struct snd_kcontrol *kcontrol, int event)
 846{
 847	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 848
 849	if (event == SND_SOC_DAPM_POST_PMD) {
 850		wcd937x_rx_clk_disable(component);
 851		snd_soc_component_update_bits(component,
 852					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 853					      BIT(1), 0x00);
 854	}
 855
 856	return 0;
 857}
 858
 859static int wcd937x_enable_rx3(struct snd_soc_dapm_widget *w,
 860			      struct snd_kcontrol *kcontrol,
 861			      int event)
 862{
 863	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 864
 865	if (event == SND_SOC_DAPM_POST_PMD) {
 866		usleep_range(6000, 6010);
 867		wcd937x_rx_clk_disable(component);
 868		snd_soc_component_update_bits(component,
 869					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 870					      BIT(2), 0x00);
 871	}
 872
 873	return 0;
 874}
 875
 876static int wcd937x_get_micb_vout_ctl_val(u32 micb_mv)
 877{
 878	if (micb_mv < 1000 || micb_mv > 2850) {
 879		pr_err("Unsupported micbias voltage (%u mV)\n", micb_mv);
 880		return -EINVAL;
 881	}
 882
 883	return (micb_mv - 1000) / 50;
 884}
 885
 886static int wcd937x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
 887			       struct snd_kcontrol *kcontrol, int event)
 888{
 889	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 890	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 891	bool use_amic3 = snd_soc_component_read(component, WCD937X_TX_NEW_TX_CH2_SEL) & BIT(7);
 892
 893	/* Enable BCS for Headset mic */
 894	if (event == SND_SOC_DAPM_PRE_PMU && strnstr(w->name, "ADC", sizeof("ADC")))
 895		if (w->shift == 1 && !use_amic3)
 896			set_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask);
 897
 898	return 0;
 899}
 900
 901static int wcd937x_codec_enable_adc(struct snd_soc_dapm_widget *w,
 902				    struct snd_kcontrol *kcontrol, int event)
 903{
 904	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 905	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 906
 907	switch (event) {
 908	case SND_SOC_DAPM_PRE_PMU:
 909		atomic_inc(&wcd937x->ana_clk_count);
 910		snd_soc_component_update_bits(component,
 911					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL, BIT(7), BIT(7));
 912		snd_soc_component_update_bits(component,
 913					      WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(3), BIT(3));
 914		snd_soc_component_update_bits(component,
 915					      WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(4), BIT(4));
 916		break;
 917	case SND_SOC_DAPM_POST_PMD:
 918		if (w->shift == 1 && test_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask))
 919			clear_bit(AMIC2_BCS_ENABLE, &wcd937x->status_mask);
 920
 921		snd_soc_component_update_bits(component,
 922					      WCD937X_DIGITAL_CDC_ANA_CLK_CTL, BIT(3), 0x00);
 923		break;
 924	}
 925
 926	return 0;
 927}
 928
 929static int wcd937x_enable_req(struct snd_soc_dapm_widget *w,
 930			      struct snd_kcontrol *kcontrol, int event)
 931{
 932	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 933	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 934
 935	switch (event) {
 936	case SND_SOC_DAPM_PRE_PMU:
 937		snd_soc_component_update_bits(component,
 938					      WCD937X_DIGITAL_CDC_REQ_CTL, BIT(1), BIT(1));
 939		snd_soc_component_update_bits(component,
 940					      WCD937X_DIGITAL_CDC_REQ_CTL, BIT(0), 0x00);
 941		snd_soc_component_update_bits(component,
 942					      WCD937X_ANA_TX_CH2, BIT(6), BIT(6));
 943		snd_soc_component_update_bits(component,
 944					      WCD937X_ANA_TX_CH3_HPF, BIT(6), BIT(6));
 945		snd_soc_component_update_bits(component,
 946					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x70, 0x70);
 947		snd_soc_component_update_bits(component,
 948					      WCD937X_ANA_TX_CH1, BIT(7), BIT(7));
 949		snd_soc_component_update_bits(component,
 950					      WCD937X_ANA_TX_CH2, BIT(6), 0x00);
 951		snd_soc_component_update_bits(component,
 952					      WCD937X_ANA_TX_CH2, BIT(7), BIT(7));
 953		snd_soc_component_update_bits(component,
 954					      WCD937X_ANA_TX_CH3, BIT(7), BIT(7));
 955		break;
 956	case SND_SOC_DAPM_POST_PMD:
 957		snd_soc_component_update_bits(component,
 958					      WCD937X_ANA_TX_CH1, BIT(7), 0x00);
 959		snd_soc_component_update_bits(component,
 960					      WCD937X_ANA_TX_CH2, BIT(7), 0x00);
 961		snd_soc_component_update_bits(component,
 962					      WCD937X_ANA_TX_CH3, BIT(7), 0x00);
 963		snd_soc_component_update_bits(component,
 964					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL, BIT(4), 0x00);
 965
 966		atomic_dec(&wcd937x->ana_clk_count);
 967		if (atomic_read(&wcd937x->ana_clk_count) <= 0) {
 968			snd_soc_component_update_bits(component,
 969						      WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
 970						      BIT(4), 0x00);
 971			atomic_set(&wcd937x->ana_clk_count, 0);
 972		}
 973
 974		snd_soc_component_update_bits(component,
 975					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
 976					      BIT(7), 0x00);
 977		break;
 978	}
 979
 980	return 0;
 981}
 982
 983static int wcd937x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
 984				     struct snd_kcontrol *kcontrol,
 985				     int event)
 986{
 987	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 988	u16 dmic_clk_reg;
 989
 990	switch (w->shift) {
 991	case 0:
 992	case 1:
 993		dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC1_CTL;
 994		break;
 995	case 2:
 996	case 3:
 997		dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC2_CTL;
 998		break;
 999	case 4:
1000	case 5:
1001		dmic_clk_reg = WCD937X_DIGITAL_CDC_DMIC3_CTL;
1002		break;
1003	default:
1004		dev_err(component->dev, "Invalid DMIC Selection\n");
1005		return -EINVAL;
1006	}
1007
1008	switch (event) {
1009	case SND_SOC_DAPM_PRE_PMU:
1010		snd_soc_component_update_bits(component,
1011					      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
1012					      BIT(7), BIT(7));
1013		snd_soc_component_update_bits(component,
1014					      dmic_clk_reg, 0x07, BIT(1));
1015		snd_soc_component_update_bits(component,
1016					      dmic_clk_reg, BIT(3), BIT(3));
1017		snd_soc_component_update_bits(component,
1018					      dmic_clk_reg, 0x70, BIT(5));
1019		break;
1020	}
1021
1022	return 0;
1023}
1024
1025static int wcd937x_micbias_control(struct snd_soc_component *component,
1026				   int micb_num, int req, bool is_dapm)
1027{
1028	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1029	int micb_index = micb_num - 1;
1030	u16 micb_reg;
1031
1032	if (micb_index < 0 || (micb_index > WCD937X_MAX_MICBIAS - 1)) {
1033		dev_err(component->dev, "Invalid micbias index, micb_ind:%d\n", micb_index);
1034		return -EINVAL;
1035	}
1036	switch (micb_num) {
1037	case MIC_BIAS_1:
1038		micb_reg = WCD937X_ANA_MICB1;
1039		break;
1040	case MIC_BIAS_2:
1041		micb_reg = WCD937X_ANA_MICB2;
1042		break;
1043	case MIC_BIAS_3:
1044		micb_reg = WCD937X_ANA_MICB3;
1045		break;
1046	default:
1047		dev_err(component->dev, "Invalid micbias number: %d\n", micb_num);
1048		return -EINVAL;
1049	}
1050
1051	mutex_lock(&wcd937x->micb_lock);
1052	switch (req) {
1053	case MICB_PULLUP_ENABLE:
1054		wcd937x->pullup_ref[micb_index]++;
1055		if (wcd937x->pullup_ref[micb_index] == 1 &&
1056		    wcd937x->micb_ref[micb_index] == 0)
1057			snd_soc_component_update_bits(component, micb_reg,
1058						      0xc0, BIT(7));
1059		break;
1060	case MICB_PULLUP_DISABLE:
1061		if (wcd937x->pullup_ref[micb_index] > 0)
1062			wcd937x->pullup_ref[micb_index]++;
1063		if (wcd937x->pullup_ref[micb_index] == 0 &&
1064		    wcd937x->micb_ref[micb_index] == 0)
1065			snd_soc_component_update_bits(component, micb_reg,
1066						      0xc0, 0x00);
1067		break;
1068	case MICB_ENABLE:
1069		wcd937x->micb_ref[micb_index]++;
1070		atomic_inc(&wcd937x->ana_clk_count);
1071		if (wcd937x->micb_ref[micb_index] == 1) {
1072			snd_soc_component_update_bits(component,
1073						      WCD937X_DIGITAL_CDC_DIG_CLK_CTL,
1074						      0xf0, 0xf0);
1075			snd_soc_component_update_bits(component,
1076						      WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
1077						      BIT(4), BIT(4));
1078			snd_soc_component_update_bits(component,
1079						      WCD937X_MICB1_TEST_CTL_2,
1080						      BIT(0), BIT(0));
1081			snd_soc_component_update_bits(component,
1082						      WCD937X_MICB2_TEST_CTL_2,
1083						      BIT(0), BIT(0));
1084			snd_soc_component_update_bits(component,
1085						      WCD937X_MICB3_TEST_CTL_2,
1086						      BIT(0), BIT(0));
1087			snd_soc_component_update_bits(component,
1088						      micb_reg, 0xc0, BIT(6));
1089
1090			if (micb_num == MIC_BIAS_2)
1091				wcd_mbhc_event_notify(wcd937x->wcd_mbhc,
1092						      WCD_EVENT_POST_MICBIAS_2_ON);
1093
1094			if (micb_num == MIC_BIAS_2 && is_dapm)
1095				wcd_mbhc_event_notify(wcd937x->wcd_mbhc,
1096						      WCD_EVENT_POST_DAPM_MICBIAS_2_ON);
1097		}
1098		break;
1099	case MICB_DISABLE:
1100		atomic_dec(&wcd937x->ana_clk_count);
1101		if (wcd937x->micb_ref[micb_index] > 0)
1102			wcd937x->micb_ref[micb_index]--;
1103		if (wcd937x->micb_ref[micb_index] == 0 &&
1104		    wcd937x->pullup_ref[micb_index] > 0)
1105			snd_soc_component_update_bits(component, micb_reg,
1106						      0xc0, BIT(7));
1107		else if (wcd937x->micb_ref[micb_index] == 0 &&
1108			 wcd937x->pullup_ref[micb_index] == 0) {
1109			if (micb_num == MIC_BIAS_2)
1110				wcd_mbhc_event_notify(wcd937x->wcd_mbhc,
1111						      WCD_EVENT_PRE_MICBIAS_2_OFF);
1112
1113			snd_soc_component_update_bits(component, micb_reg,
1114						      0xc0, 0x00);
1115			if (micb_num == MIC_BIAS_2)
1116				wcd_mbhc_event_notify(wcd937x->wcd_mbhc,
1117						      WCD_EVENT_POST_MICBIAS_2_OFF);
1118		}
1119
1120		if (is_dapm && micb_num == MIC_BIAS_2)
1121			wcd_mbhc_event_notify(wcd937x->wcd_mbhc,
1122					      WCD_EVENT_POST_DAPM_MICBIAS_2_OFF);
1123		if (atomic_read(&wcd937x->ana_clk_count) <= 0) {
1124			snd_soc_component_update_bits(component,
1125						      WCD937X_DIGITAL_CDC_ANA_CLK_CTL,
1126						      BIT(4), 0x00);
1127			atomic_set(&wcd937x->ana_clk_count, 0);
1128		}
1129		break;
1130	}
1131	mutex_unlock(&wcd937x->micb_lock);
1132
1133	return 0;
1134}
1135
1136static int __wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
1137					  int event)
1138{
1139	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1140	int micb_num = w->shift;
1141
1142	switch (event) {
1143	case SND_SOC_DAPM_PRE_PMU:
1144		wcd937x_micbias_control(component, micb_num,
1145					MICB_ENABLE, true);
1146		break;
1147	case SND_SOC_DAPM_POST_PMU:
1148		usleep_range(1000, 1100);
1149		break;
1150	case SND_SOC_DAPM_POST_PMD:
1151		wcd937x_micbias_control(component, micb_num,
1152					MICB_DISABLE, true);
1153		break;
1154	}
1155
1156	return 0;
1157}
1158
1159static int wcd937x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
1160					struct snd_kcontrol *kcontrol,
1161					int event)
1162{
1163	return __wcd937x_codec_enable_micbias(w, event);
1164}
1165
1166static int __wcd937x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
1167						 int event)
1168{
1169	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1170	int micb_num = w->shift;
1171
1172	switch (event) {
1173	case SND_SOC_DAPM_PRE_PMU:
1174		wcd937x_micbias_control(component, micb_num, MICB_PULLUP_ENABLE, true);
1175		break;
1176	case SND_SOC_DAPM_POST_PMU:
1177		usleep_range(1000, 1100);
1178		break;
1179	case SND_SOC_DAPM_POST_PMD:
1180		wcd937x_micbias_control(component, micb_num, MICB_PULLUP_DISABLE, true);
1181		break;
1182	}
1183
1184	return 0;
1185}
1186
1187static int wcd937x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
1188					       struct snd_kcontrol *kcontrol,
1189					       int event)
1190{
1191	return __wcd937x_codec_enable_micbias_pullup(w, event);
1192}
1193
1194static int wcd937x_connect_port(struct wcd937x_sdw_priv *wcd, u8 port_idx, u8 ch_id, bool enable)
1195{
1196	struct sdw_port_config *port_config = &wcd->port_config[port_idx - 1];
1197	const struct wcd937x_sdw_ch_info *ch_info = &wcd->ch_info[ch_id];
1198	u8 port_num = ch_info->port_num;
1199	u8 ch_mask = ch_info->ch_mask;
1200
1201	port_config->num = port_num;
1202
1203	if (enable)
1204		port_config->ch_mask |= ch_mask;
1205	else
1206		port_config->ch_mask &= ~ch_mask;
1207
1208	return 0;
1209}
1210
1211static int wcd937x_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
1212				   struct snd_ctl_elem_value *ucontrol)
1213{
1214	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1215	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1216
1217	ucontrol->value.integer.value[0] = wcd937x->hph_mode;
1218	return 0;
1219}
1220
1221static int wcd937x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
1222				   struct snd_ctl_elem_value *ucontrol)
1223{
1224	struct snd_soc_component *component =
1225				snd_soc_kcontrol_component(kcontrol);
1226	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1227	u32 mode_val;
1228
1229	mode_val = ucontrol->value.enumerated.item[0];
1230
1231	if (!mode_val)
1232		mode_val = CLS_AB;
1233
1234	if (mode_val == wcd937x->hph_mode)
1235		return 0;
1236
1237	switch (mode_val) {
1238	case CLS_H_NORMAL:
1239	case CLS_H_HIFI:
1240	case CLS_H_LP:
1241	case CLS_AB:
1242	case CLS_H_LOHIFI:
1243	case CLS_H_ULP:
1244	case CLS_AB_LP:
1245	case CLS_AB_HIFI:
1246		wcd937x->hph_mode = mode_val;
1247		return 1;
1248	}
1249
1250	dev_dbg(component->dev, "%s: Invalid HPH Mode\n", __func__);
1251	return -EINVAL;
1252}
1253
1254static int wcd937x_get_compander(struct snd_kcontrol *kcontrol,
1255				 struct snd_ctl_elem_value *ucontrol)
1256{
1257	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1258	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1259	struct soc_mixer_control *mc;
1260	bool hphr;
1261
1262	mc = (struct soc_mixer_control *)(kcontrol->private_value);
1263	hphr = mc->shift;
1264
1265	ucontrol->value.integer.value[0] = hphr ? wcd937x->comp2_enable :
1266						  wcd937x->comp1_enable;
1267	return 0;
1268}
1269
1270static int wcd937x_set_compander(struct snd_kcontrol *kcontrol,
1271				 struct snd_ctl_elem_value *ucontrol)
1272{
1273	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1274	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1275	struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[AIF1_PB];
1276	int value = ucontrol->value.integer.value[0];
1277	struct soc_mixer_control *mc;
1278	int portidx;
1279	bool hphr;
1280
1281	mc = (struct soc_mixer_control *)(kcontrol->private_value);
1282	hphr = mc->shift;
1283
1284	if (hphr) {
1285		if (value == wcd937x->comp2_enable)
1286			return 0;
1287
1288		wcd937x->comp2_enable = value;
1289	} else {
1290		if (value == wcd937x->comp1_enable)
1291			return 0;
1292
1293		wcd937x->comp1_enable = value;
1294	}
1295
1296	portidx = wcd->ch_info[mc->reg].port_num;
1297
1298	if (value)
1299		wcd937x_connect_port(wcd, portidx, mc->reg, true);
1300	else
1301		wcd937x_connect_port(wcd, portidx, mc->reg, false);
1302
1303	return 1;
1304}
1305
1306static int wcd937x_get_swr_port(struct snd_kcontrol *kcontrol,
1307				struct snd_ctl_elem_value *ucontrol)
1308{
1309	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
1310	struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
1311	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(comp);
1312	struct wcd937x_sdw_priv *wcd;
1313	int dai_id = mixer->shift;
1314	int ch_idx = mixer->reg;
1315	int portidx;
1316
1317	wcd = wcd937x->sdw_priv[dai_id];
1318	portidx = wcd->ch_info[ch_idx].port_num;
1319
1320	ucontrol->value.integer.value[0] = wcd->port_enable[portidx];
1321
1322	return 0;
1323}
1324
1325static int wcd937x_set_swr_port(struct snd_kcontrol *kcontrol,
1326				struct snd_ctl_elem_value *ucontrol)
1327{
1328	struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
1329	struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
1330	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(comp);
1331	struct wcd937x_sdw_priv *wcd;
1332	int dai_id = mixer->shift;
1333	int ch_idx = mixer->reg;
1334	int portidx;
1335	bool enable;
1336
1337	wcd = wcd937x->sdw_priv[dai_id];
1338
1339	portidx = wcd->ch_info[ch_idx].port_num;
1340
1341	enable = ucontrol->value.integer.value[0];
1342
1343	if (enable == wcd->port_enable[portidx]) {
1344		wcd937x_connect_port(wcd, portidx, ch_idx, enable);
1345		return 0;
1346	}
1347
1348	wcd->port_enable[portidx] = enable;
1349	wcd937x_connect_port(wcd, portidx, ch_idx, enable);
1350
1351	return 1;
1352}
1353
1354static const char * const rx_hph_mode_mux_text[] = {
1355	"CLS_H_NORMAL", "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB",
1356	"CLS_H_LOHIFI", "CLS_H_ULP", "CLS_AB_LP", "CLS_AB_HIFI",
1357};
1358
1359static const struct soc_enum rx_hph_mode_mux_enum =
1360	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text), rx_hph_mode_mux_text);
1361
1362/* MBHC related */
1363static void wcd937x_mbhc_clk_setup(struct snd_soc_component *component,
1364				   bool enable)
1365{
1366	snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_1,
1367				      WCD937X_MBHC_CTL_RCO_EN_MASK, enable);
1368}
1369
1370static void wcd937x_mbhc_mbhc_bias_control(struct snd_soc_component *component,
1371					   bool enable)
1372{
1373	snd_soc_component_write_field(component, WCD937X_ANA_MBHC_ELECT,
1374				      WCD937X_ANA_MBHC_BIAS_EN, enable);
1375}
1376
1377static void wcd937x_mbhc_program_btn_thr(struct snd_soc_component *component,
1378					 int *btn_low, int *btn_high,
1379					 int num_btn, bool is_micbias)
1380{
1381	int i, vth;
1382
1383	if (num_btn > WCD_MBHC_DEF_BUTTONS) {
1384		dev_err(component->dev, "%s: invalid number of buttons: %d\n",
1385			__func__, num_btn);
1386		return;
1387	}
1388
1389	for (i = 0; i < num_btn; i++) {
1390		vth = ((btn_high[i] * 2) / 25) & 0x3F;
1391		snd_soc_component_write_field(component, WCD937X_ANA_MBHC_BTN0 + i,
1392					      WCD937X_MBHC_BTN_VTH_MASK, vth);
1393	}
1394}
1395
1396static bool wcd937x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num)
1397{
1398	u8 val;
1399
1400	if (micb_num == MIC_BIAS_2) {
1401		val = snd_soc_component_read_field(component,
1402						   WCD937X_ANA_MICB2,
1403						   WCD937X_ANA_MICB2_ENABLE_MASK);
1404		if (val == WCD937X_MICB_ENABLE)
1405			return true;
1406	}
1407	return false;
1408}
1409
1410static void wcd937x_mbhc_hph_l_pull_up_control(struct snd_soc_component *component,
1411					       int pull_up_cur)
1412{
1413	/* Default pull up current to 2uA */
1414	if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA)
1415		pull_up_cur = HS_PULLUP_I_2P0_UA;
1416
1417	snd_soc_component_write_field(component,
1418				      WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT,
1419				      WCD937X_HSDET_PULLUP_C_MASK, pull_up_cur);
1420}
1421
1422static int wcd937x_mbhc_request_micbias(struct snd_soc_component *component,
1423					int micb_num, int req)
1424{
1425	return wcd937x_micbias_control(component, micb_num, req, false);
1426}
1427
1428static void wcd937x_mbhc_micb_ramp_control(struct snd_soc_component *component,
1429					   bool enable)
1430{
1431	if (enable) {
1432		snd_soc_component_write_field(component, WCD937X_ANA_MICB2_RAMP,
1433					      WCD937X_RAMP_SHIFT_CTRL_MASK, 0x0C);
1434		snd_soc_component_write_field(component, WCD937X_ANA_MICB2_RAMP,
1435					      WCD937X_RAMP_EN_MASK, 1);
1436	} else {
1437		snd_soc_component_write_field(component, WCD937X_ANA_MICB2_RAMP,
1438					      WCD937X_RAMP_EN_MASK, 0);
1439		snd_soc_component_write_field(component, WCD937X_ANA_MICB2_RAMP,
1440					      WCD937X_RAMP_SHIFT_CTRL_MASK, 0);
1441	}
1442}
1443
1444static int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
1445					    int req_volt, int micb_num)
1446{
1447	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1448	int cur_vout_ctl, req_vout_ctl, micb_reg, micb_en, ret = 0;
1449
1450	switch (micb_num) {
1451	case MIC_BIAS_1:
1452		micb_reg = WCD937X_ANA_MICB1;
1453		break;
1454	case MIC_BIAS_2:
1455		micb_reg = WCD937X_ANA_MICB2;
1456		break;
1457	case MIC_BIAS_3:
1458		micb_reg = WCD937X_ANA_MICB3;
1459		break;
1460	default:
1461		return -EINVAL;
1462	}
1463	mutex_lock(&wcd937x->micb_lock);
1464	/*
1465	 * If requested micbias voltage is same as current micbias
1466	 * voltage, then just return. Otherwise, adjust voltage as
1467	 * per requested value. If micbias is already enabled, then
1468	 * to avoid slow micbias ramp-up or down enable pull-up
1469	 * momentarily, change the micbias value and then re-enable
1470	 * micbias.
1471	 */
1472	micb_en = snd_soc_component_read_field(component, micb_reg,
1473					       WCD937X_MICB_EN_MASK);
1474	cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
1475						    WCD937X_MICB_VOUT_MASK);
1476
1477	req_vout_ctl = wcd937x_get_micb_vout_ctl_val(req_volt);
1478	if (req_vout_ctl < 0) {
1479		ret = -EINVAL;
1480		goto exit;
1481	}
1482
1483	if (cur_vout_ctl == req_vout_ctl) {
1484		ret = 0;
1485		goto exit;
1486	}
1487
1488	if (micb_en == WCD937X_MICB_ENABLE)
1489		snd_soc_component_write_field(component, micb_reg,
1490					      WCD937X_MICB_EN_MASK,
1491					      WCD937X_MICB_PULL_UP);
1492
1493	snd_soc_component_write_field(component, micb_reg,
1494				      WCD937X_MICB_VOUT_MASK,
1495				      req_vout_ctl);
1496
1497	if (micb_en == WCD937X_MICB_ENABLE) {
1498		snd_soc_component_write_field(component, micb_reg,
1499					      WCD937X_MICB_EN_MASK,
1500					      WCD937X_MICB_ENABLE);
1501		/*
1502		 * Add 2ms delay as per HW requirement after enabling
1503		 * micbias
1504		 */
1505		usleep_range(2000, 2100);
1506	}
1507exit:
1508	mutex_unlock(&wcd937x->micb_lock);
1509	return ret;
1510}
1511
1512static int wcd937x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component,
1513						int micb_num, bool req_en)
1514{
1515	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1516	int micb_mv;
1517
1518	if (micb_num != MIC_BIAS_2)
1519		return -EINVAL;
1520	/*
1521	 * If device tree micbias level is already above the minimum
1522	 * voltage needed to detect threshold microphone, then do
1523	 * not change the micbias, just return.
1524	 */
1525	if (wcd937x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
1526		return 0;
1527
1528	micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd937x->micb2_mv;
1529
1530	return wcd937x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
1531}
1532
1533static void wcd937x_mbhc_get_result_params(struct snd_soc_component *component,
1534					   s16 *d1_a, u16 noff,
1535					   int32_t *zdet)
1536{
1537	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1538	int i;
1539	int val, val1;
1540	s16 c1;
1541	s32 x1, d1;
1542	s32 denom;
1543	static const int minCode_param[] = {
1544		3277, 1639, 820, 410, 205, 103, 52, 26
1545	};
1546
1547	regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_ZDET, 0x20, 0x20);
1548	for (i = 0; i < WCD937X_ZDET_NUM_MEASUREMENTS; i++) {
1549		regmap_read(wcd937x->regmap, WCD937X_ANA_MBHC_RESULT_2, &val);
1550		if (val & 0x80)
1551			break;
1552	}
1553	val = val << 0x8;
1554	regmap_read(wcd937x->regmap, WCD937X_ANA_MBHC_RESULT_1, &val1);
1555	val |= val1;
1556	regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MBHC_ZDET, 0x20, 0x00);
1557	x1 = WCD937X_MBHC_GET_X1(val);
1558	c1 = WCD937X_MBHC_GET_C1(val);
1559	/* If ramp is not complete, give additional 5ms */
1560	if (c1 < 2 && x1)
1561		usleep_range(5000, 5050);
1562
1563	if (!c1 || !x1) {
1564		dev_err(component->dev, "Impedance detect ramp error, c1=%d, x1=0x%x\n",
1565			c1, x1);
1566		goto ramp_down;
1567	}
1568	d1 = d1_a[c1];
1569	denom = (x1 * d1) - (1 << (14 - noff));
1570	if (denom > 0)
1571		*zdet = (WCD937X_MBHC_ZDET_CONST * 1000) / denom;
1572	else if (x1 < minCode_param[noff])
1573		*zdet = WCD937X_ZDET_FLOATING_IMPEDANCE;
1574
1575	dev_err(component->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n",
1576		__func__, d1, c1, x1, *zdet);
1577ramp_down:
1578	i = 0;
1579	while (x1) {
1580		regmap_read(wcd937x->regmap,
1581			    WCD937X_ANA_MBHC_RESULT_1, &val);
1582		regmap_read(wcd937x->regmap,
1583			    WCD937X_ANA_MBHC_RESULT_2, &val1);
1584		val = val << 0x08;
1585		val |= val1;
1586		x1 = WCD937X_MBHC_GET_X1(val);
1587		i++;
1588		if (i == WCD937X_ZDET_NUM_MEASUREMENTS)
1589			break;
1590	}
1591}
1592
1593static void wcd937x_mbhc_zdet_ramp(struct snd_soc_component *component,
1594				   struct wcd937x_mbhc_zdet_param *zdet_param,
1595				   s32 *zl, s32 *zr, s16 *d1_a)
1596{
1597	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1598	s32 zdet = 0;
1599
1600	snd_soc_component_write_field(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL,
1601				      WCD937X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl);
1602	snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_BTN5,
1603				      WCD937X_VTH_MASK, zdet_param->btn5);
1604	snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_BTN6,
1605				      WCD937X_VTH_MASK, zdet_param->btn6);
1606	snd_soc_component_update_bits(component, WCD937X_ANA_MBHC_BTN7,
1607				      WCD937X_VTH_MASK, zdet_param->btn7);
1608	snd_soc_component_write_field(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL,
1609				      WCD937X_ZDET_RANGE_CTL_MASK, zdet_param->noff);
1610	snd_soc_component_update_bits(component, WCD937X_MBHC_NEW_ZDET_RAMP_CTL,
1611				      0x0F, zdet_param->nshift);
1612
1613	if (!zl)
1614		goto z_right;
1615	/* Start impedance measurement for HPH_L */
1616	regmap_update_bits(wcd937x->regmap,
1617			   WCD937X_ANA_MBHC_ZDET, 0x80, 0x80);
1618	wcd937x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet);
1619	regmap_update_bits(wcd937x->regmap,
1620			   WCD937X_ANA_MBHC_ZDET, 0x80, 0x00);
1621
1622	*zl = zdet;
1623
1624z_right:
1625	if (!zr)
1626		return;
1627	/* Start impedance measurement for HPH_R */
1628	regmap_update_bits(wcd937x->regmap,
1629			   WCD937X_ANA_MBHC_ZDET, 0x40, 0x40);
1630	wcd937x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet);
1631	regmap_update_bits(wcd937x->regmap,
1632			   WCD937X_ANA_MBHC_ZDET, 0x40, 0x00);
1633
1634	*zr = zdet;
1635}
1636
1637static void wcd937x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component,
1638				       s32 *z_val, int flag_l_r)
1639{
1640	s16 q1;
1641	int q1_cal;
1642
1643	if (*z_val < (WCD937X_ZDET_VAL_400 / 1000))
1644		q1 = snd_soc_component_read(component,
1645					    WCD937X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
1646	else
1647		q1 = snd_soc_component_read(component,
1648					    WCD937X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
1649	if (q1 & 0x80)
1650		q1_cal = (10000 - ((q1 & 0x7F) * 25));
1651	else
1652		q1_cal = (10000 + (q1 * 25));
1653	if (q1_cal > 0)
1654		*z_val = ((*z_val) * 10000) / q1_cal;
1655}
1656
1657static void wcd937x_wcd_mbhc_calc_impedance(struct snd_soc_component *component,
1658					    u32 *zl, u32 *zr)
1659{
1660	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1661	s16 reg0, reg1, reg2, reg3, reg4;
1662	s32 z1l, z1r, z1ls;
1663	int zMono, z_diff1, z_diff2;
1664	bool is_fsm_disable = false;
1665	struct wcd937x_mbhc_zdet_param zdet_param[] = {
1666		{4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
1667		{2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
1668		{1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
1669		{1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
1670	};
1671	struct wcd937x_mbhc_zdet_param *zdet_param_ptr = NULL;
1672	s16 d1_a[][4] = {
1673		{0, 30, 90, 30},
1674		{0, 30, 30, 5},
1675		{0, 30, 30, 5},
1676		{0, 30, 30, 5},
1677	};
1678	s16 *d1 = NULL;
1679
1680	reg0 = snd_soc_component_read(component, WCD937X_ANA_MBHC_BTN5);
1681	reg1 = snd_soc_component_read(component, WCD937X_ANA_MBHC_BTN6);
1682	reg2 = snd_soc_component_read(component, WCD937X_ANA_MBHC_BTN7);
1683	reg3 = snd_soc_component_read(component, WCD937X_MBHC_CTL_CLK);
1684	reg4 = snd_soc_component_read(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL);
1685
1686	if (snd_soc_component_read(component, WCD937X_ANA_MBHC_ELECT) & 0x80) {
1687		is_fsm_disable = true;
1688		regmap_update_bits(wcd937x->regmap,
1689				   WCD937X_ANA_MBHC_ELECT, 0x80, 0x00);
1690	}
1691
1692	/* For NO-jack, disable L_DET_EN before Z-det measurements */
1693	if (wcd937x->mbhc_cfg.hphl_swh)
1694		regmap_update_bits(wcd937x->regmap,
1695				   WCD937X_ANA_MBHC_MECH, 0x80, 0x00);
1696
1697	/* Turn off 100k pull down on HPHL */
1698	regmap_update_bits(wcd937x->regmap,
1699			   WCD937X_ANA_MBHC_MECH, 0x01, 0x00);
1700
1701	/* Disable surge protection before impedance detection.
1702	 * This is done to give correct value for high impedance.
1703	 */
1704	regmap_update_bits(wcd937x->regmap,
1705			   WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
1706	/* 1ms delay needed after disable surge protection */
1707	usleep_range(1000, 1010);
1708
1709	/* First get impedance on Left */
1710	d1 = d1_a[1];
1711	zdet_param_ptr = &zdet_param[1];
1712	wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1l, NULL, d1);
1713
1714	if (!WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z1l))
1715		goto left_ch_impedance;
1716
1717	/* Second ramp for left ch */
1718	if (z1l < WCD937X_ZDET_VAL_32) {
1719		zdet_param_ptr = &zdet_param[0];
1720		d1 = d1_a[0];
1721	} else if ((z1l > WCD937X_ZDET_VAL_400) &&
1722		  (z1l <= WCD937X_ZDET_VAL_1200)) {
1723		zdet_param_ptr = &zdet_param[2];
1724		d1 = d1_a[2];
1725	} else if (z1l > WCD937X_ZDET_VAL_1200) {
1726		zdet_param_ptr = &zdet_param[3];
1727		d1 = d1_a[3];
1728	}
1729	wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1l, NULL, d1);
1730
1731left_ch_impedance:
1732	if (z1l == WCD937X_ZDET_FLOATING_IMPEDANCE ||
1733	    z1l > WCD937X_ZDET_VAL_100K) {
1734		*zl = WCD937X_ZDET_FLOATING_IMPEDANCE;
1735		zdet_param_ptr = &zdet_param[1];
1736		d1 = d1_a[1];
1737	} else {
1738		*zl = z1l / 1000;
1739		wcd937x_wcd_mbhc_qfuse_cal(component, zl, 0);
1740	}
1741
1742	/* Start of right impedance ramp and calculation */
1743	wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1r, d1);
1744	if (WCD937X_MBHC_IS_SECOND_RAMP_REQUIRED(z1r)) {
1745		if ((z1r > WCD937X_ZDET_VAL_1200 &&
1746		     zdet_param_ptr->noff == 0x6) ||
1747		     ((*zl) != WCD937X_ZDET_FLOATING_IMPEDANCE))
1748			goto right_ch_impedance;
1749		/* Second ramp for right ch */
1750		if (z1r < WCD937X_ZDET_VAL_32) {
1751			zdet_param_ptr = &zdet_param[0];
1752			d1 = d1_a[0];
1753		} else if ((z1r > WCD937X_ZDET_VAL_400) &&
1754			(z1r <= WCD937X_ZDET_VAL_1200)) {
1755			zdet_param_ptr = &zdet_param[2];
1756			d1 = d1_a[2];
1757		} else if (z1r > WCD937X_ZDET_VAL_1200) {
1758			zdet_param_ptr = &zdet_param[3];
1759			d1 = d1_a[3];
1760		}
1761		wcd937x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1r, d1);
1762	}
1763right_ch_impedance:
1764	if (z1r == WCD937X_ZDET_FLOATING_IMPEDANCE ||
1765	    z1r > WCD937X_ZDET_VAL_100K) {
1766		*zr = WCD937X_ZDET_FLOATING_IMPEDANCE;
1767	} else {
1768		*zr = z1r / 1000;
1769		wcd937x_wcd_mbhc_qfuse_cal(component, zr, 1);
1770	}
1771
1772	/* Mono/stereo detection */
1773	if ((*zl == WCD937X_ZDET_FLOATING_IMPEDANCE) &&
1774	    (*zr == WCD937X_ZDET_FLOATING_IMPEDANCE)) {
1775		dev_err(component->dev,
1776			"%s: plug type is invalid or extension cable\n",
1777			__func__);
1778		goto zdet_complete;
1779	}
1780	if ((*zl == WCD937X_ZDET_FLOATING_IMPEDANCE) ||
1781	    (*zr == WCD937X_ZDET_FLOATING_IMPEDANCE) ||
1782	    ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
1783	    ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
1784		wcd_mbhc_set_hph_type(wcd937x->wcd_mbhc, WCD_MBHC_HPH_MONO);
1785		goto zdet_complete;
1786	}
1787	snd_soc_component_write_field(component, WCD937X_HPH_R_ATEST,
1788				      WCD937X_HPHPA_GND_OVR_MASK, 1);
1789	snd_soc_component_write_field(component, WCD937X_HPH_PA_CTL2,
1790				      WCD937X_HPHPA_GND_R_MASK, 1);
1791	if (*zl < (WCD937X_ZDET_VAL_32 / 1000))
1792		wcd937x_mbhc_zdet_ramp(component, &zdet_param[0], &z1ls, NULL, d1);
1793	else
1794		wcd937x_mbhc_zdet_ramp(component, &zdet_param[1], &z1ls, NULL, d1);
1795	snd_soc_component_write_field(component, WCD937X_HPH_PA_CTL2,
1796				      WCD937X_HPHPA_GND_R_MASK, 0);
1797	snd_soc_component_write_field(component, WCD937X_HPH_R_ATEST,
1798				      WCD937X_HPHPA_GND_OVR_MASK, 0);
1799	z1ls /= 1000;
1800	wcd937x_wcd_mbhc_qfuse_cal(component, &z1ls, 0);
1801	/* Parallel of left Z and 9 ohm pull down resistor */
1802	zMono = ((*zl) * 9) / ((*zl) + 9);
1803	z_diff1 = (z1ls > zMono) ? (z1ls - zMono) : (zMono - z1ls);
1804	z_diff2 = ((*zl) > z1ls) ? ((*zl) - z1ls) : (z1ls - (*zl));
1805	if ((z_diff1 * (*zl + z1ls)) > (z_diff2 * (z1ls + zMono)))
1806		wcd_mbhc_set_hph_type(wcd937x->wcd_mbhc, WCD_MBHC_HPH_STEREO);
1807	else
1808		wcd_mbhc_set_hph_type(wcd937x->wcd_mbhc, WCD_MBHC_HPH_MONO);
1809
1810	/* Enable surge protection again after impedance detection */
1811	regmap_update_bits(wcd937x->regmap,
1812			   WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
1813zdet_complete:
1814	snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN5, reg0);
1815	snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN6, reg1);
1816	snd_soc_component_write(component, WCD937X_ANA_MBHC_BTN7, reg2);
1817	/* Turn on 100k pull down on HPHL */
1818	regmap_update_bits(wcd937x->regmap,
1819			   WCD937X_ANA_MBHC_MECH, 0x01, 0x01);
1820
1821	/* For NO-jack, re-enable L_DET_EN after Z-det measurements */
1822	if (wcd937x->mbhc_cfg.hphl_swh)
1823		regmap_update_bits(wcd937x->regmap,
1824				   WCD937X_ANA_MBHC_MECH, 0x80, 0x80);
1825
1826	snd_soc_component_write(component, WCD937X_MBHC_NEW_ZDET_ANA_CTL, reg4);
1827	snd_soc_component_write(component, WCD937X_MBHC_CTL_CLK, reg3);
1828	if (is_fsm_disable)
1829		regmap_update_bits(wcd937x->regmap,
1830				   WCD937X_ANA_MBHC_ELECT, 0x80, 0x80);
1831}
1832
1833static void wcd937x_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
1834				      bool enable)
1835{
1836	if (enable) {
1837		snd_soc_component_write_field(component, WCD937X_ANA_MBHC_MECH,
1838					      WCD937X_MBHC_HSG_PULLUP_COMP_EN, 1);
1839		snd_soc_component_write_field(component, WCD937X_ANA_MBHC_MECH,
1840					      WCD937X_MBHC_GND_DET_EN_MASK, 1);
1841	} else {
1842		snd_soc_component_write_field(component, WCD937X_ANA_MBHC_MECH,
1843					      WCD937X_MBHC_GND_DET_EN_MASK, 0);
1844		snd_soc_component_write_field(component, WCD937X_ANA_MBHC_MECH,
1845					      WCD937X_MBHC_HSG_PULLUP_COMP_EN, 0);
1846	}
1847}
1848
1849static void wcd937x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
1850					    bool enable)
1851{
1852	snd_soc_component_write_field(component, WCD937X_HPH_PA_CTL2,
1853				      WCD937X_HPHPA_GND_R_MASK, enable);
1854	snd_soc_component_write_field(component, WCD937X_HPH_PA_CTL2,
1855				      WCD937X_HPHPA_GND_L_MASK, enable);
1856}
1857
1858static void wcd937x_mbhc_moisture_config(struct snd_soc_component *component)
1859{
1860	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1861
1862	if (wcd937x->mbhc_cfg.moist_rref == R_OFF) {
1863		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1864					      WCD937X_M_RTH_CTL_MASK, R_OFF);
1865		return;
1866	}
1867
1868	/* Do not enable moisture detection if jack type is NC */
1869	if (!wcd937x->mbhc_cfg.hphl_swh) {
1870		dev_err(component->dev, "%s: disable moisture detection for NC\n",
1871			__func__);
1872		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1873					      WCD937X_M_RTH_CTL_MASK, R_OFF);
1874		return;
1875	}
1876
1877	snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1878				      WCD937X_M_RTH_CTL_MASK, wcd937x->mbhc_cfg.moist_rref);
1879}
1880
1881static void wcd937x_mbhc_moisture_detect_en(struct snd_soc_component *component, bool enable)
1882{
1883	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1884
1885	if (enable)
1886		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1887					      WCD937X_M_RTH_CTL_MASK, wcd937x->mbhc_cfg.moist_rref);
1888	else
1889		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1890					      WCD937X_M_RTH_CTL_MASK, R_OFF);
1891}
1892
1893static bool wcd937x_mbhc_get_moisture_status(struct snd_soc_component *component)
1894{
1895	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1896	bool ret = false;
1897
1898	if (wcd937x->mbhc_cfg.moist_rref == R_OFF) {
1899		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1900					      WCD937X_M_RTH_CTL_MASK, R_OFF);
1901		goto done;
1902	}
1903
1904	/* Do not enable moisture detection if jack type is NC */
1905	if (!wcd937x->mbhc_cfg.hphl_swh) {
1906		dev_err(component->dev, "%s: disable moisture detection for NC\n",
1907			__func__);
1908		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
1909					      WCD937X_M_RTH_CTL_MASK, R_OFF);
1910		goto done;
1911	}
1912
1913	/*
1914	 * If moisture_en is already enabled, then skip to plug type
1915	 * detection.
1916	 */
1917	if (snd_soc_component_read_field(component, WCD937X_MBHC_NEW_CTL_2, WCD937X_M_RTH_CTL_MASK))
1918		goto done;
1919
1920	wcd937x_mbhc_moisture_detect_en(component, true);
1921	/* Read moisture comparator status */
1922	ret = ((snd_soc_component_read(component, WCD937X_MBHC_NEW_FSM_STATUS)
1923				       & 0x20) ? 0 : 1);
1924done:
1925	return ret;
1926}
1927
1928static void wcd937x_mbhc_moisture_polling_ctrl(struct snd_soc_component *component,
1929					       bool enable)
1930{
1931	snd_soc_component_write_field(component,
1932				      WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL,
1933				      WCD937X_MOISTURE_EN_POLLING_MASK, enable);
1934}
1935
1936static const struct wcd_mbhc_cb mbhc_cb = {
1937	.clk_setup = wcd937x_mbhc_clk_setup,
1938	.mbhc_bias = wcd937x_mbhc_mbhc_bias_control,
1939	.set_btn_thr = wcd937x_mbhc_program_btn_thr,
1940	.micbias_enable_status = wcd937x_mbhc_micb_en_status,
1941	.hph_pull_up_control_v2 = wcd937x_mbhc_hph_l_pull_up_control,
1942	.mbhc_micbias_control = wcd937x_mbhc_request_micbias,
1943	.mbhc_micb_ramp_control = wcd937x_mbhc_micb_ramp_control,
1944	.mbhc_micb_ctrl_thr_mic = wcd937x_mbhc_micb_ctrl_threshold_mic,
1945	.compute_impedance = wcd937x_wcd_mbhc_calc_impedance,
1946	.mbhc_gnd_det_ctrl = wcd937x_mbhc_gnd_det_ctrl,
1947	.hph_pull_down_ctrl = wcd937x_mbhc_hph_pull_down_ctrl,
1948	.mbhc_moisture_config = wcd937x_mbhc_moisture_config,
1949	.mbhc_get_moisture_status = wcd937x_mbhc_get_moisture_status,
1950	.mbhc_moisture_polling_ctrl = wcd937x_mbhc_moisture_polling_ctrl,
1951	.mbhc_moisture_detect_en = wcd937x_mbhc_moisture_detect_en,
1952};
1953
1954static int wcd937x_get_hph_type(struct snd_kcontrol *kcontrol,
1955				struct snd_ctl_elem_value *ucontrol)
1956{
1957	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1958	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1959
1960	ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd937x->wcd_mbhc);
1961
1962	return 0;
1963}
1964
1965static int wcd937x_hph_impedance_get(struct snd_kcontrol *kcontrol,
1966				     struct snd_ctl_elem_value *ucontrol)
1967{
1968	u32 zl, zr;
1969	bool hphr;
1970	struct soc_mixer_control *mc;
1971	struct snd_soc_component *component =
1972					snd_soc_kcontrol_component(kcontrol);
1973	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1974
1975	mc = (struct soc_mixer_control *)(kcontrol->private_value);
1976	hphr = mc->shift;
1977	wcd_mbhc_get_impedance(wcd937x->wcd_mbhc, &zl, &zr);
1978	ucontrol->value.integer.value[0] = hphr ? zr : zl;
1979
1980	return 0;
1981}
1982
1983static const struct snd_kcontrol_new hph_type_detect_controls[] = {
1984	SOC_SINGLE_EXT("HPH Type", 0, 0, WCD_MBHC_HPH_STEREO, 0,
1985		       wcd937x_get_hph_type, NULL),
1986};
1987
1988static const struct snd_kcontrol_new impedance_detect_controls[] = {
1989	SOC_SINGLE_EXT("HPHL Impedance", 0, 0, INT_MAX, 0,
1990		       wcd937x_hph_impedance_get, NULL),
1991	SOC_SINGLE_EXT("HPHR Impedance", 0, 1, INT_MAX, 0,
1992		       wcd937x_hph_impedance_get, NULL),
1993};
1994
1995static int wcd937x_mbhc_init(struct snd_soc_component *component)
1996{
1997	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
1998	struct wcd_mbhc_intr *intr_ids = &wcd937x->intr_ids;
1999
2000	intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd937x->irq_chip,
2001						     WCD937X_IRQ_MBHC_SW_DET);
2002	intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd937x->irq_chip,
2003							    WCD937X_IRQ_MBHC_BUTTON_PRESS_DET);
2004	intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd937x->irq_chip,
2005							      WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET);
2006	intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd937x->irq_chip,
2007							 WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET);
2008	intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd937x->irq_chip,
2009							 WCD937X_IRQ_MBHC_ELECT_INS_REM_DET);
2010	intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd937x->irq_chip,
2011						     WCD937X_IRQ_HPHL_OCP_INT);
2012	intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd937x->irq_chip,
2013						      WCD937X_IRQ_HPHR_OCP_INT);
2014
2015	wcd937x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
2016	if (IS_ERR(wcd937x->wcd_mbhc))
2017		return PTR_ERR(wcd937x->wcd_mbhc);
2018
2019	snd_soc_add_component_controls(component, impedance_detect_controls,
2020				       ARRAY_SIZE(impedance_detect_controls));
2021	snd_soc_add_component_controls(component, hph_type_detect_controls,
2022				       ARRAY_SIZE(hph_type_detect_controls));
2023
2024	return 0;
2025}
2026
2027static void wcd937x_mbhc_deinit(struct snd_soc_component *component)
2028{
2029	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
2030
2031	wcd_mbhc_deinit(wcd937x->wcd_mbhc);
2032}
2033
2034/* END MBHC */
2035
2036static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
2037	SOC_SINGLE_TLV("EAR_PA Volume", WCD937X_ANA_EAR_COMPANDER_CTL,
2038		       2, 0x10, 0, ear_pa_gain),
2039	SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
2040		     wcd937x_rx_hph_mode_get, wcd937x_rx_hph_mode_put),
2041
2042	SOC_SINGLE_EXT("HPHL_COMP Switch", SND_SOC_NOPM, 0, 1, 0,
2043		       wcd937x_get_compander, wcd937x_set_compander),
2044	SOC_SINGLE_EXT("HPHR_COMP Switch", SND_SOC_NOPM, 1, 1, 0,
2045		       wcd937x_get_compander, wcd937x_set_compander),
2046
2047	SOC_SINGLE_TLV("HPHL Volume", WCD937X_HPH_L_EN, 0, 20, 1, line_gain),
2048	SOC_SINGLE_TLV("HPHR Volume", WCD937X_HPH_R_EN, 0, 20, 1, line_gain),
2049	SOC_SINGLE_TLV("ADC1 Volume", WCD937X_ANA_TX_CH1, 0, 20, 0, analog_gain),
2050	SOC_SINGLE_TLV("ADC2 Volume", WCD937X_ANA_TX_CH2, 0, 20, 0, analog_gain),
2051	SOC_SINGLE_TLV("ADC3 Volume", WCD937X_ANA_TX_CH3, 0, 20, 0, analog_gain),
2052
2053	SOC_SINGLE_EXT("HPHL Switch", WCD937X_HPH_L, 0, 1, 0,
2054		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2055	SOC_SINGLE_EXT("HPHR Switch", WCD937X_HPH_R, 0, 1, 0,
2056		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2057	SOC_SINGLE_EXT("LO Switch", WCD937X_LO, 0, 1, 0,
2058		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2059
2060	SOC_SINGLE_EXT("ADC1 Switch", WCD937X_ADC1, 1, 1, 0,
2061		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2062	SOC_SINGLE_EXT("ADC2 Switch", WCD937X_ADC2, 1, 1, 0,
2063		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2064	SOC_SINGLE_EXT("ADC3 Switch", WCD937X_ADC3, 1, 1, 0,
2065		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2066	SOC_SINGLE_EXT("DMIC0 Switch", WCD937X_DMIC0, 1, 1, 0,
2067		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2068	SOC_SINGLE_EXT("DMIC1 Switch", WCD937X_DMIC1, 1, 1, 0,
2069		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2070	SOC_SINGLE_EXT("MBHC Switch", WCD937X_MBHC, 1, 1, 0,
2071		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2072	SOC_SINGLE_EXT("DMIC2 Switch", WCD937X_DMIC2, 1, 1, 0,
2073		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2074	SOC_SINGLE_EXT("DMIC3 Switch", WCD937X_DMIC3, 1, 1, 0,
2075		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2076	SOC_SINGLE_EXT("DMIC4 Switch", WCD937X_DMIC4, 1, 1, 0,
2077		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2078	SOC_SINGLE_EXT("DMIC5 Switch", WCD937X_DMIC5, 1, 1, 0,
2079		       wcd937x_get_swr_port, wcd937x_set_swr_port),
2080};
2081
2082static const struct snd_kcontrol_new adc1_switch[] = {
2083	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2084};
2085
2086static const struct snd_kcontrol_new adc2_switch[] = {
2087	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2088};
2089
2090static const struct snd_kcontrol_new adc3_switch[] = {
2091	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2092};
2093
2094static const struct snd_kcontrol_new dmic1_switch[] = {
2095	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2096};
2097
2098static const struct snd_kcontrol_new dmic2_switch[] = {
2099	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2100};
2101
2102static const struct snd_kcontrol_new dmic3_switch[] = {
2103	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2104};
2105
2106static const struct snd_kcontrol_new dmic4_switch[] = {
2107	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2108};
2109
2110static const struct snd_kcontrol_new dmic5_switch[] = {
2111	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2112};
2113
2114static const struct snd_kcontrol_new dmic6_switch[] = {
2115	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2116};
2117
2118static const struct snd_kcontrol_new ear_rdac_switch[] = {
2119	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2120};
2121
2122static const struct snd_kcontrol_new aux_rdac_switch[] = {
2123	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2124};
2125
2126static const struct snd_kcontrol_new hphl_rdac_switch[] = {
2127	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2128};
2129
2130static const struct snd_kcontrol_new hphr_rdac_switch[] = {
2131	SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
2132};
2133
2134static const char * const adc2_mux_text[] = {
2135	"INP2", "INP3"
2136};
2137
2138static const char * const rdac3_mux_text[] = {
2139	"RX1", "RX3"
2140};
2141
2142static const struct soc_enum adc2_enum =
2143	SOC_ENUM_SINGLE(WCD937X_TX_NEW_TX_CH2_SEL, 7,
2144			ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
2145
2146static const struct soc_enum rdac3_enum =
2147	SOC_ENUM_SINGLE(WCD937X_DIGITAL_CDC_EAR_PATH_CTL, 0,
2148			ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text);
2149
2150static const struct snd_kcontrol_new tx_adc2_mux = SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum);
2151
2152static const struct snd_kcontrol_new rx_rdac3_mux = SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum);
2153
2154static const struct snd_soc_dapm_widget wcd937x_dapm_widgets[] = {
2155	/* Input widgets */
2156	SND_SOC_DAPM_INPUT("AMIC1"),
2157	SND_SOC_DAPM_INPUT("AMIC2"),
2158	SND_SOC_DAPM_INPUT("AMIC3"),
2159	SND_SOC_DAPM_INPUT("IN1_HPHL"),
2160	SND_SOC_DAPM_INPUT("IN2_HPHR"),
2161	SND_SOC_DAPM_INPUT("IN3_AUX"),
2162
2163	/* TX widgets */
2164	SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
2165			   wcd937x_codec_enable_adc,
2166			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2167	SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0,
2168			   wcd937x_codec_enable_adc,
2169			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2170
2171	SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0,
2172			     NULL, 0, wcd937x_enable_req,
2173			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2174	SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 0, 0,
2175			     NULL, 0, wcd937x_enable_req,
2176			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2177
2178	SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
2179
2180	/* TX mixers */
2181	SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0,
2182			     adc1_switch, ARRAY_SIZE(adc1_switch),
2183			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2184			     SND_SOC_DAPM_POST_PMD),
2185	SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 1, 0,
2186			     adc2_switch, ARRAY_SIZE(adc2_switch),
2187			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2188			     SND_SOC_DAPM_POST_PMD),
2189
2190	/* MIC_BIAS widgets */
2191	SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
2192			    wcd937x_codec_enable_micbias,
2193			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2194			    SND_SOC_DAPM_POST_PMD),
2195	SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
2196			    wcd937x_codec_enable_micbias,
2197			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2198			    SND_SOC_DAPM_POST_PMD),
2199	SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
2200			    wcd937x_codec_enable_micbias,
2201			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2202			    SND_SOC_DAPM_POST_PMD),
2203
2204	SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, NULL, 0),
2205	SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, NULL, 0),
2206
2207	/* RX widgets */
2208	SND_SOC_DAPM_PGA_E("EAR PGA", WCD937X_ANA_EAR, 7, 0, NULL, 0,
2209			   wcd937x_codec_enable_ear_pa,
2210			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2211			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2212	SND_SOC_DAPM_PGA_E("AUX PGA", WCD937X_AUX_AUXPA, 7, 0, NULL, 0,
2213			   wcd937x_codec_enable_aux_pa,
2214			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2215			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2216	SND_SOC_DAPM_PGA_E("HPHL PGA", WCD937X_ANA_HPH, 7, 0, NULL, 0,
2217			   wcd937x_codec_enable_hphl_pa,
2218			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2219			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2220	SND_SOC_DAPM_PGA_E("HPHR PGA", WCD937X_ANA_HPH, 6, 0, NULL, 0,
2221			   wcd937x_codec_enable_hphr_pa,
2222			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2223			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2224
2225	SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0,
2226			   wcd937x_codec_hphl_dac_event,
2227			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2228			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2229	SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0,
2230			   wcd937x_codec_hphr_dac_event,
2231			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2232			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2233	SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0,
2234			   wcd937x_codec_ear_dac_event,
2235			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2236			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2237	SND_SOC_DAPM_DAC_E("RDAC4", NULL, SND_SOC_NOPM, 0, 0,
2238			   wcd937x_codec_aux_dac_event,
2239			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2240			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
2241
2242	SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux),
2243
2244	SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0,
2245			     wcd937x_enable_rx1, SND_SOC_DAPM_PRE_PMU |
2246			     SND_SOC_DAPM_POST_PMD),
2247	SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0,
2248			     wcd937x_enable_rx2, SND_SOC_DAPM_PRE_PMU |
2249			     SND_SOC_DAPM_POST_PMD),
2250	SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0,
2251			     wcd937x_enable_rx3, SND_SOC_DAPM_PRE_PMU |
2252			     SND_SOC_DAPM_POST_PMD),
2253
2254	/* RX mixer widgets*/
2255	SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0,
2256			   ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)),
2257	SND_SOC_DAPM_MIXER("AUX_RDAC", SND_SOC_NOPM, 0, 0,
2258			   aux_rdac_switch, ARRAY_SIZE(aux_rdac_switch)),
2259	SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0,
2260			   hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)),
2261	SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0,
2262			   hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)),
2263
2264	/* TX output widgets */
2265	SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"),
2266	SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"),
2267	SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"),
2268	SND_SOC_DAPM_OUTPUT("WCD_TX_OUTPUT"),
2269
2270	/* RX output widgets */
2271	SND_SOC_DAPM_OUTPUT("EAR"),
2272	SND_SOC_DAPM_OUTPUT("AUX"),
2273	SND_SOC_DAPM_OUTPUT("HPHL"),
2274	SND_SOC_DAPM_OUTPUT("HPHR"),
2275
2276	/* MIC_BIAS pull up widgets */
2277	SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
2278			    wcd937x_codec_enable_micbias_pullup,
2279			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2280			    SND_SOC_DAPM_POST_PMD),
2281	SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
2282			    wcd937x_codec_enable_micbias_pullup,
2283			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2284			    SND_SOC_DAPM_POST_PMD),
2285	SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
2286			    wcd937x_codec_enable_micbias_pullup,
2287			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2288			    SND_SOC_DAPM_POST_PMD),
2289};
2290
2291static const struct snd_soc_dapm_widget wcd9375_dapm_widgets[] = {
2292	/* Input widgets */
2293	SND_SOC_DAPM_INPUT("AMIC4"),
2294
2295	/* TX widgets */
2296	SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0,
2297			   wcd937x_codec_enable_adc,
2298			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2299
2300	SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 0, 0,
2301			     NULL, 0, wcd937x_enable_req,
2302			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2303
2304	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
2305			   wcd937x_codec_enable_dmic,
2306			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2307	SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0,
2308			   wcd937x_codec_enable_dmic,
2309			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2310	SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0,
2311			   wcd937x_codec_enable_dmic,
2312			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2313	SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0,
2314			   wcd937x_codec_enable_dmic,
2315			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2316	SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0,
2317			   wcd937x_codec_enable_dmic,
2318			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2319	SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0,
2320			   wcd937x_codec_enable_dmic,
2321			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2322
2323	/* TX mixer widgets */
2324	SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0,
2325			     0, dmic1_switch, ARRAY_SIZE(dmic1_switch),
2326			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2327			     SND_SOC_DAPM_POST_PMD),
2328	SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 1,
2329			     0, dmic2_switch, ARRAY_SIZE(dmic2_switch),
2330			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2331			     SND_SOC_DAPM_POST_PMD),
2332	SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 2,
2333			     0, dmic3_switch, ARRAY_SIZE(dmic3_switch),
2334			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2335			     SND_SOC_DAPM_POST_PMD),
2336	SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 3,
2337			     0, dmic4_switch, ARRAY_SIZE(dmic4_switch),
2338			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2339			     SND_SOC_DAPM_POST_PMD),
2340	SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 4,
2341			     0, dmic5_switch, ARRAY_SIZE(dmic5_switch),
2342			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2343			     SND_SOC_DAPM_POST_PMD),
2344	SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 5,
2345			     0, dmic6_switch, ARRAY_SIZE(dmic6_switch),
2346			     wcd937x_tx_swr_ctrl, SND_SOC_DAPM_PRE_PMU |
2347			     SND_SOC_DAPM_POST_PMD),
2348	SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 2, 0, adc3_switch,
2349			     ARRAY_SIZE(adc3_switch), wcd937x_tx_swr_ctrl,
2350			     SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2351
2352	/* Output widgets */
2353	SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"),
2354	SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"),
2355	SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"),
2356	SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"),
2357	SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"),
2358	SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"),
2359};
2360
2361static const struct snd_soc_dapm_route wcd937x_audio_map[] = {
2362	{ "ADC1_OUTPUT", NULL, "ADC1_MIXER" },
2363	{ "ADC1_MIXER", "Switch", "ADC1 REQ" },
2364	{ "ADC1 REQ", NULL, "ADC1" },
2365	{ "ADC1", NULL, "AMIC1" },
2366
2367	{ "ADC2_OUTPUT", NULL, "ADC2_MIXER" },
2368	{ "ADC2_MIXER", "Switch", "ADC2 REQ" },
2369	{ "ADC2 REQ", NULL, "ADC2" },
2370	{ "ADC2", NULL, "ADC2 MUX" },
2371	{ "ADC2 MUX", "INP3", "AMIC3" },
2372	{ "ADC2 MUX", "INP2", "AMIC2" },
2373
2374	{ "IN1_HPHL", NULL, "VDD_BUCK" },
2375	{ "IN1_HPHL", NULL, "CLS_H_PORT" },
2376	{ "RX1", NULL, "IN1_HPHL" },
2377	{ "RDAC1", NULL, "RX1" },
2378	{ "HPHL_RDAC", "Switch", "RDAC1" },
2379	{ "HPHL PGA", NULL, "HPHL_RDAC" },
2380	{ "HPHL", NULL, "HPHL PGA" },
2381
2382	{ "IN2_HPHR", NULL, "VDD_BUCK" },
2383	{ "IN2_HPHR", NULL, "CLS_H_PORT" },
2384	{ "RX2", NULL, "IN2_HPHR" },
2385	{ "RDAC2", NULL, "RX2" },
2386	{ "HPHR_RDAC", "Switch", "RDAC2" },
2387	{ "HPHR PGA", NULL, "HPHR_RDAC" },
2388	{ "HPHR", NULL, "HPHR PGA" },
2389
2390	{ "IN3_AUX", NULL, "VDD_BUCK" },
2391	{ "IN3_AUX", NULL, "CLS_H_PORT" },
2392	{ "RX3", NULL, "IN3_AUX" },
2393	{ "RDAC4", NULL, "RX3" },
2394	{ "AUX_RDAC", "Switch", "RDAC4" },
2395	{ "AUX PGA", NULL, "AUX_RDAC" },
2396	{ "AUX", NULL, "AUX PGA" },
2397
2398	{ "RDAC3_MUX", "RX3", "RX3" },
2399	{ "RDAC3_MUX", "RX1", "RX1" },
2400	{ "RDAC3", NULL, "RDAC3_MUX" },
2401	{ "EAR_RDAC", "Switch", "RDAC3" },
2402	{ "EAR PGA", NULL, "EAR_RDAC" },
2403	{ "EAR", NULL, "EAR PGA" },
2404};
2405
2406static const struct snd_soc_dapm_route wcd9375_audio_map[] = {
2407	{ "ADC3_OUTPUT", NULL, "ADC3_MIXER" },
2408	{ "ADC3_OUTPUT", NULL, "ADC3_MIXER" },
2409	{ "ADC3_MIXER", "Switch", "ADC3 REQ" },
2410	{ "ADC3 REQ", NULL, "ADC3" },
2411	{ "ADC3", NULL, "AMIC4" },
2412
2413	{ "DMIC1_OUTPUT", NULL, "DMIC1_MIXER" },
2414	{ "DMIC1_MIXER", "Switch", "DMIC1" },
2415
2416	{ "DMIC2_OUTPUT", NULL, "DMIC2_MIXER" },
2417	{ "DMIC2_MIXER", "Switch", "DMIC2" },
2418
2419	{ "DMIC3_OUTPUT", NULL, "DMIC3_MIXER" },
2420	{ "DMIC3_MIXER", "Switch", "DMIC3" },
2421
2422	{ "DMIC4_OUTPUT", NULL, "DMIC4_MIXER" },
2423	{ "DMIC4_MIXER", "Switch", "DMIC4" },
2424
2425	{ "DMIC5_OUTPUT", NULL, "DMIC5_MIXER" },
2426	{ "DMIC5_MIXER", "Switch", "DMIC5" },
2427
2428	{ "DMIC6_OUTPUT", NULL, "DMIC6_MIXER" },
2429	{ "DMIC6_MIXER", "Switch", "DMIC6" },
2430};
2431
2432static int wcd937x_set_micbias_data(struct wcd937x_priv *wcd937x)
2433{
2434	int vout_ctl[3];
2435
2436	/* Set micbias voltage */
2437	vout_ctl[0] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb1_mv);
2438	vout_ctl[1] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb2_mv);
2439	vout_ctl[2] = wcd937x_get_micb_vout_ctl_val(wcd937x->micb3_mv);
2440	if ((vout_ctl[0] | vout_ctl[1] | vout_ctl[2]) < 0)
2441		return -EINVAL;
2442
2443	regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB1, WCD937X_ANA_MICB_VOUT, vout_ctl[0]);
2444	regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB2, WCD937X_ANA_MICB_VOUT, vout_ctl[1]);
2445	regmap_update_bits(wcd937x->regmap, WCD937X_ANA_MICB3, WCD937X_ANA_MICB_VOUT, vout_ctl[2]);
2446
2447	return 0;
2448}
2449
2450static irqreturn_t wcd937x_wd_handle_irq(int irq, void *data)
2451{
2452	return IRQ_HANDLED;
2453}
2454
2455static const struct irq_chip wcd_irq_chip = {
2456	.name = "WCD937x",
2457};
2458
2459static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq,
2460			    irq_hw_number_t hw)
2461{
2462	irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq);
2463	irq_set_nested_thread(virq, 1);
2464	irq_set_noprobe(virq);
2465
2466	return 0;
2467}
2468
2469static const struct irq_domain_ops wcd_domain_ops = {
2470	.map = wcd_irq_chip_map,
2471};
2472
2473static int wcd937x_irq_init(struct wcd937x_priv *wcd, struct device *dev)
2474{
2475	wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL);
2476	if (!(wcd->virq)) {
2477		dev_err(dev, "%s: Failed to add IRQ domain\n", __func__);
2478		return -EINVAL;
2479	}
2480
2481	return devm_regmap_add_irq_chip(dev, wcd->regmap,
2482					irq_create_mapping(wcd->virq, 0),
2483					IRQF_ONESHOT, 0, &wcd937x_regmap_irq_chip,
2484					&wcd->irq_chip);
2485}
2486
2487static int wcd937x_soc_codec_probe(struct snd_soc_component *component)
2488{
2489	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
2490	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
2491	struct sdw_slave *tx_sdw_dev = wcd937x->tx_sdw_dev;
2492	struct device *dev = component->dev;
2493	unsigned long time_left;
2494	int i, ret;
2495	u32 chipid;
2496
2497	time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete,
2498						msecs_to_jiffies(5000));
2499	if (!time_left) {
2500		dev_err(dev, "soundwire device init timeout\n");
2501		return -ETIMEDOUT;
2502	}
2503
2504	snd_soc_component_init_regmap(component, wcd937x->regmap);
2505	ret = pm_runtime_resume_and_get(dev);
2506	if (ret < 0)
2507		return ret;
2508
2509	chipid = (snd_soc_component_read(component,
2510					 WCD937X_DIGITAL_EFUSE_REG_0) & 0x1e) >> 1;
2511	if (chipid != CHIPID_WCD9370 && chipid != CHIPID_WCD9375) {
2512		dev_err(dev, "Got unknown chip id: 0x%x\n", chipid);
2513		pm_runtime_put(dev);
2514		return -EINVAL;
2515	}
2516
2517	wcd937x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD937X);
2518	if (IS_ERR(wcd937x->clsh_info)) {
2519		pm_runtime_put(dev);
2520		return PTR_ERR(wcd937x->clsh_info);
2521	}
2522
2523	wcd937x_io_init(wcd937x->regmap);
2524	/* Set all interrupts as edge triggered */
2525	for (i = 0; i < wcd937x_regmap_irq_chip.num_regs; i++)
2526		regmap_write(wcd937x->regmap, (WCD937X_DIGITAL_INTR_LEVEL_0 + i), 0);
2527
2528	pm_runtime_put(dev);
2529
2530	wcd937x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd937x->irq_chip,
2531						       WCD937X_IRQ_HPHR_PDM_WD_INT);
2532	wcd937x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd937x->irq_chip,
2533						       WCD937X_IRQ_HPHL_PDM_WD_INT);
2534	wcd937x->aux_pdm_wd_int = regmap_irq_get_virq(wcd937x->irq_chip,
2535						      WCD937X_IRQ_AUX_PDM_WD_INT);
2536
2537	/* Request for watchdog interrupt */
2538	ret = devm_request_threaded_irq(dev, wcd937x->hphr_pdm_wd_int, NULL, wcd937x_wd_handle_irq,
2539					IRQF_ONESHOT | IRQF_TRIGGER_RISING,
2540					"HPHR PDM WDOG INT", wcd937x);
2541	if (ret)
2542		dev_err(dev, "Failed to request HPHR watchdog interrupt (%d)\n", ret);
2543
2544	ret = devm_request_threaded_irq(dev, wcd937x->hphl_pdm_wd_int, NULL, wcd937x_wd_handle_irq,
2545					IRQF_ONESHOT | IRQF_TRIGGER_RISING,
2546					"HPHL PDM WDOG INT", wcd937x);
2547	if (ret)
2548		dev_err(dev, "Failed to request HPHL watchdog interrupt (%d)\n", ret);
2549
2550	ret = devm_request_threaded_irq(dev, wcd937x->aux_pdm_wd_int, NULL, wcd937x_wd_handle_irq,
2551					IRQF_ONESHOT | IRQF_TRIGGER_RISING,
2552					"AUX PDM WDOG INT", wcd937x);
2553	if (ret)
2554		dev_err(dev, "Failed to request Aux watchdog interrupt (%d)\n", ret);
2555
2556	/* Disable watchdog interrupt for HPH and AUX */
2557	disable_irq_nosync(wcd937x->hphr_pdm_wd_int);
2558	disable_irq_nosync(wcd937x->hphl_pdm_wd_int);
2559	disable_irq_nosync(wcd937x->aux_pdm_wd_int);
2560
2561	if (chipid == CHIPID_WCD9375) {
2562		ret = snd_soc_dapm_new_controls(dapm, wcd9375_dapm_widgets,
2563						ARRAY_SIZE(wcd9375_dapm_widgets));
2564		if (ret < 0) {
2565			dev_err(component->dev, "Failed to add snd_ctls\n");
2566			return ret;
2567		}
2568
2569		ret = snd_soc_dapm_add_routes(dapm, wcd9375_audio_map,
2570					      ARRAY_SIZE(wcd9375_audio_map));
2571		if (ret < 0) {
2572			dev_err(component->dev, "Failed to add routes\n");
2573			return ret;
2574		}
2575	}
2576
2577	ret = wcd937x_mbhc_init(component);
2578	if (ret)
2579		dev_err(component->dev, "mbhc initialization failed\n");
2580
2581	return ret;
2582}
2583
2584static void wcd937x_soc_codec_remove(struct snd_soc_component *component)
2585{
2586	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
2587
2588	wcd937x_mbhc_deinit(component);
2589	free_irq(wcd937x->aux_pdm_wd_int, wcd937x);
2590	free_irq(wcd937x->hphl_pdm_wd_int, wcd937x);
2591	free_irq(wcd937x->hphr_pdm_wd_int, wcd937x);
2592
2593	wcd_clsh_ctrl_free(wcd937x->clsh_info);
2594}
2595
2596static int wcd937x_codec_set_jack(struct snd_soc_component *comp,
2597				  struct snd_soc_jack *jack, void *data)
2598{
2599	struct wcd937x_priv *wcd = dev_get_drvdata(comp->dev);
2600	int ret = 0;
2601
2602	if (jack)
2603		ret = wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack);
2604	else
2605		wcd_mbhc_stop(wcd->wcd_mbhc);
2606
2607	return ret;
2608}
2609
2610static const struct snd_soc_component_driver soc_codec_dev_wcd937x = {
2611	.name = "wcd937x_codec",
2612	.probe = wcd937x_soc_codec_probe,
2613	.remove = wcd937x_soc_codec_remove,
2614	.controls = wcd937x_snd_controls,
2615	.num_controls = ARRAY_SIZE(wcd937x_snd_controls),
2616	.dapm_widgets = wcd937x_dapm_widgets,
2617	.num_dapm_widgets = ARRAY_SIZE(wcd937x_dapm_widgets),
2618	.dapm_routes = wcd937x_audio_map,
2619	.num_dapm_routes = ARRAY_SIZE(wcd937x_audio_map),
2620	.set_jack = wcd937x_codec_set_jack,
2621	.endianness = 1,
2622};
2623
2624static void wcd937x_dt_parse_micbias_info(struct device *dev, struct wcd937x_priv *wcd)
2625{
2626	struct device_node *np = dev->of_node;
2627	u32 prop_val = 0;
2628	int ret = 0;
2629
2630	ret = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
2631	if (!ret)
2632		wcd->micb1_mv = prop_val / 1000;
2633	else
2634		dev_warn(dev, "Micbias1 DT property not found\n");
2635
2636	ret = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
2637	if (!ret)
2638		wcd->micb2_mv = prop_val / 1000;
2639	else
2640		dev_warn(dev, "Micbias2 DT property not found\n");
2641
2642	ret = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
2643	if (!ret)
2644		wcd->micb3_mv = prop_val / 1000;
2645	else
2646		dev_warn(dev, "Micbias3 DT property not found\n");
2647}
2648
2649static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component, bool active)
2650{
2651	int value;
2652	struct wcd937x_priv *wcd937x;
2653
2654	wcd937x = snd_soc_component_get_drvdata(component);
2655
2656	value = gpiod_get_value(wcd937x->us_euro_gpio);
2657	gpiod_set_value(wcd937x->us_euro_gpio, !value);
2658
2659	return true;
2660}
2661
2662static int wcd937x_codec_hw_params(struct snd_pcm_substream *substream,
2663				   struct snd_pcm_hw_params *params,
2664				   struct snd_soc_dai *dai)
2665{
2666	struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev);
2667	struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id];
2668
2669	return wcd937x_sdw_hw_params(wcd, substream, params, dai);
2670}
2671
2672static int wcd937x_codec_free(struct snd_pcm_substream *substream,
2673			      struct snd_soc_dai *dai)
2674{
2675	struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev);
2676	struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id];
2677
2678	return sdw_stream_remove_slave(wcd->sdev, wcd->sruntime);
2679}
2680
2681static int wcd937x_codec_set_sdw_stream(struct snd_soc_dai *dai,
2682					void *stream, int direction)
2683{
2684	struct wcd937x_priv *wcd937x = dev_get_drvdata(dai->dev);
2685	struct wcd937x_sdw_priv *wcd = wcd937x->sdw_priv[dai->id];
2686
2687	wcd->sruntime = stream;
2688
2689	return 0;
2690}
2691
2692static const struct snd_soc_dai_ops wcd937x_sdw_dai_ops = {
2693	.hw_params = wcd937x_codec_hw_params,
2694	.hw_free = wcd937x_codec_free,
2695	.set_stream = wcd937x_codec_set_sdw_stream,
2696};
2697
2698static struct snd_soc_dai_driver wcd937x_dais[] = {
2699	[0] = {
2700		.name = "wcd937x-sdw-rx",
2701		.playback = {
2702			.stream_name = "WCD AIF Playback",
2703			.rates = WCD937X_RATES | WCD937X_FRAC_RATES,
2704			.formats = WCD937X_FORMATS,
2705			.rate_min = 8000,
2706			.rate_max = 384000,
2707			.channels_min = 1,
2708			.channels_max = 4,
2709		},
2710		.ops = &wcd937x_sdw_dai_ops,
2711	},
2712	[1] = {
2713		.name = "wcd937x-sdw-tx",
2714		.capture = {
2715			.stream_name = "WCD AIF Capture",
2716			.rates = WCD937X_RATES,
2717			.formats = WCD937X_FORMATS,
2718			.rate_min = 8000,
2719			.rate_max = 192000,
2720			.channels_min = 1,
2721			.channels_max = 4,
2722		},
2723		.ops = &wcd937x_sdw_dai_ops,
2724	},
2725};
2726
2727static int wcd937x_bind(struct device *dev)
2728{
2729	struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);
2730	int ret;
2731
2732	/* Give the SDW subdevices some more time to settle */
2733	usleep_range(5000, 5010);
2734
2735	ret = component_bind_all(dev, wcd937x);
2736	if (ret) {
2737		dev_err(dev, "Slave bind failed, ret = %d\n", ret);
2738		return ret;
2739	}
2740
2741	wcd937x->rxdev = wcd937x_sdw_device_get(wcd937x->rxnode);
2742	if (!wcd937x->rxdev) {
2743		dev_err(dev, "could not find slave with matching of node\n");
2744		return -EINVAL;
2745	}
2746
2747	wcd937x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd937x->rxdev);
2748	wcd937x->sdw_priv[AIF1_PB]->wcd937x = wcd937x;
2749
2750	wcd937x->txdev = wcd937x_sdw_device_get(wcd937x->txnode);
2751	if (!wcd937x->txdev) {
2752		dev_err(dev, "could not find txslave with matching of node\n");
2753		return -EINVAL;
2754	}
2755
2756	wcd937x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd937x->txdev);
2757	wcd937x->sdw_priv[AIF1_CAP]->wcd937x = wcd937x;
2758	wcd937x->tx_sdw_dev = dev_to_sdw_dev(wcd937x->txdev);
2759	if (!wcd937x->tx_sdw_dev) {
2760		dev_err(dev, "could not get txslave with matching of dev\n");
2761		return -EINVAL;
2762	}
2763
2764	/*
2765	 * As TX is the main CSR reg interface, which should not be suspended first.
2766	 * expicilty add the dependency link
2767	 */
2768	if (!device_link_add(wcd937x->rxdev, wcd937x->txdev,
2769			     DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME)) {
2770		dev_err(dev, "Could not devlink TX and RX\n");
2771		return -EINVAL;
2772	}
2773
2774	if (!device_link_add(dev, wcd937x->txdev,
2775			     DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME)) {
2776		dev_err(dev, "Could not devlink WCD and TX\n");
2777		return -EINVAL;
2778	}
2779
2780	if (!device_link_add(dev, wcd937x->rxdev,
2781			     DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME)) {
2782		dev_err(dev, "Could not devlink WCD and RX\n");
2783		return -EINVAL;
2784	}
2785
2786	wcd937x->regmap = dev_get_regmap(&wcd937x->tx_sdw_dev->dev, NULL);
2787	if (!wcd937x->regmap) {
2788		dev_err(dev, "could not get TX device regmap\n");
2789		return -EINVAL;
2790	}
2791
2792	ret = wcd937x_irq_init(wcd937x, dev);
2793	if (ret) {
2794		dev_err(dev, "IRQ init failed: %d\n", ret);
2795		return ret;
2796	}
2797
2798	wcd937x->sdw_priv[AIF1_PB]->slave_irq = wcd937x->virq;
2799	wcd937x->sdw_priv[AIF1_CAP]->slave_irq = wcd937x->virq;
2800
2801	ret = wcd937x_set_micbias_data(wcd937x);
2802	if (ret < 0) {
2803		dev_err(dev, "Bad micbias pdata\n");
2804		return ret;
2805	}
2806
2807	ret = snd_soc_register_component(dev, &soc_codec_dev_wcd937x,
2808					 wcd937x_dais, ARRAY_SIZE(wcd937x_dais));
2809	if (ret)
2810		dev_err(dev, "Codec registration failed\n");
2811
2812	return ret;
2813}
2814
2815static void wcd937x_unbind(struct device *dev)
2816{
2817	struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);
2818
2819	snd_soc_unregister_component(dev);
2820	device_link_remove(dev, wcd937x->txdev);
2821	device_link_remove(dev, wcd937x->rxdev);
2822	device_link_remove(wcd937x->rxdev, wcd937x->txdev);
2823	component_unbind_all(dev, wcd937x);
2824	mutex_destroy(&wcd937x->micb_lock);
2825}
2826
2827static const struct component_master_ops wcd937x_comp_ops = {
2828	.bind = wcd937x_bind,
2829	.unbind = wcd937x_unbind,
2830};
2831
2832static int wcd937x_add_slave_components(struct wcd937x_priv *wcd937x,
2833					struct device *dev,
2834					struct component_match **matchptr)
2835{
2836	struct device_node *np = dev->of_node;
2837
2838	wcd937x->rxnode = of_parse_phandle(np, "qcom,rx-device", 0);
2839	if (!wcd937x->rxnode) {
2840		dev_err(dev, "Couldn't parse phandle to qcom,rx-device!\n");
2841		return -ENODEV;
2842	}
2843	of_node_get(wcd937x->rxnode);
2844	component_match_add_release(dev, matchptr, component_release_of,
2845				    component_compare_of, wcd937x->rxnode);
2846
2847	wcd937x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
2848	if (!wcd937x->txnode) {
2849		dev_err(dev, "Couldn't parse phandle to qcom,tx-device\n");
2850			return -ENODEV;
2851	}
2852	of_node_get(wcd937x->txnode);
2853	component_match_add_release(dev, matchptr, component_release_of,
2854				    component_compare_of, wcd937x->txnode);
2855
2856	return 0;
2857}
2858
2859static int wcd937x_probe(struct platform_device *pdev)
2860{
2861	struct component_match *match = NULL;
2862	struct device *dev = &pdev->dev;
2863	struct wcd937x_priv *wcd937x;
2864	struct wcd_mbhc_config *cfg;
2865	int ret;
2866
2867	wcd937x = devm_kzalloc(dev, sizeof(*wcd937x), GFP_KERNEL);
2868	if (!wcd937x)
2869		return -ENOMEM;
2870
2871	dev_set_drvdata(dev, wcd937x);
2872	mutex_init(&wcd937x->micb_lock);
2873
2874	wcd937x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
2875	if (IS_ERR(wcd937x->reset_gpio))
2876		return dev_err_probe(dev, PTR_ERR(wcd937x->reset_gpio),
2877				     "failed to reset wcd gpio\n");
2878
2879	wcd937x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro", GPIOD_OUT_LOW);
2880	if (IS_ERR(wcd937x->us_euro_gpio))
2881		return dev_err_probe(dev, PTR_ERR(wcd937x->us_euro_gpio),
2882				"us-euro swap Control GPIO not found\n");
2883
2884	cfg = &wcd937x->mbhc_cfg;
2885	cfg->swap_gnd_mic = wcd937x_swap_gnd_mic;
2886
2887	wcd937x->supplies[0].supply = "vdd-rxtx";
2888	wcd937x->supplies[1].supply = "vdd-px";
2889	wcd937x->supplies[2].supply = "vdd-mic-bias";
2890	wcd937x->supplies[3].supply = "vdd-buck";
2891
2892	ret = devm_regulator_bulk_get(dev, WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2893	if (ret)
2894		return dev_err_probe(dev, ret, "Failed to get supplies\n");
2895
2896	ret = regulator_bulk_enable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2897	if (ret) {
2898		regulator_bulk_free(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2899		return dev_err_probe(dev, ret, "Failed to enable supplies\n");
2900	}
2901
2902	wcd937x_dt_parse_micbias_info(dev, wcd937x);
2903
2904	cfg->mbhc_micbias = MIC_BIAS_2;
2905	cfg->anc_micbias = MIC_BIAS_2;
2906	cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
2907	cfg->num_btn = WCD937X_MBHC_MAX_BUTTONS;
2908	cfg->micb_mv = wcd937x->micb2_mv;
2909	cfg->linein_th = 5000;
2910	cfg->hs_thr = 1700;
2911	cfg->hph_thr = 50;
2912
2913	wcd_dt_parse_mbhc_data(dev, &wcd937x->mbhc_cfg);
2914
2915	ret = wcd937x_add_slave_components(wcd937x, dev, &match);
2916	if (ret)
2917		goto err_disable_regulators;
2918
2919	wcd937x_reset(wcd937x);
2920
2921	ret = component_master_add_with_match(dev, &wcd937x_comp_ops, match);
2922	if (ret)
2923		goto err_disable_regulators;
2924
2925	pm_runtime_set_autosuspend_delay(dev, 1000);
2926	pm_runtime_use_autosuspend(dev);
2927	pm_runtime_mark_last_busy(dev);
2928	pm_runtime_set_active(dev);
2929	pm_runtime_enable(dev);
2930	pm_runtime_idle(dev);
2931
2932	return 0;
2933
2934err_disable_regulators:
2935	regulator_bulk_disable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2936	regulator_bulk_free(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2937
2938	return ret;
2939}
2940
2941static void wcd937x_remove(struct platform_device *pdev)
2942{
2943	struct device *dev = &pdev->dev;
2944	struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);
2945
2946	component_master_del(&pdev->dev, &wcd937x_comp_ops);
2947
2948	pm_runtime_disable(dev);
2949	pm_runtime_set_suspended(dev);
2950	pm_runtime_dont_use_autosuspend(dev);
2951
2952	regulator_bulk_disable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2953	regulator_bulk_free(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies);
2954}
2955
2956#if defined(CONFIG_OF)
2957static const struct of_device_id wcd937x_of_match[] = {
2958	{ .compatible = "qcom,wcd9370-codec" },
2959	{ .compatible = "qcom,wcd9375-codec" },
2960	{ }
2961};
2962MODULE_DEVICE_TABLE(of, wcd937x_of_match);
2963#endif
2964
2965static struct platform_driver wcd937x_codec_driver = {
2966	.probe = wcd937x_probe,
2967	.remove = wcd937x_remove,
2968	.driver = {
2969		.name = "wcd937x_codec",
2970		.of_match_table = of_match_ptr(wcd937x_of_match),
2971		.suppress_bind_attrs = true,
2972	},
2973};
2974
2975module_platform_driver(wcd937x_codec_driver);
2976MODULE_DESCRIPTION("WCD937X Codec driver");
2977MODULE_LICENSE("GPL");