File Index
Files and directories
Sign in
FILE

wcd937x.c

File preview with syntax highlighting.

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