18d78602aSSrinivas Kandagatla // SPDX-License-Identifier: GPL-2.0-only
28d78602aSSrinivas Kandagatla // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
38d78602aSSrinivas Kandagatla
48d78602aSSrinivas Kandagatla #include <linux/module.h>
58d78602aSSrinivas Kandagatla #include <linux/slab.h>
68d78602aSSrinivas Kandagatla #include <linux/platform_device.h>
78d78602aSSrinivas Kandagatla #include <linux/device.h>
88d78602aSSrinivas Kandagatla #include <linux/delay.h>
9db0b4aedSSrinivasa Rao Mandadapu #include <linux/gpio/consumer.h>
108d78602aSSrinivas Kandagatla #include <linux/kernel.h>
118d78602aSSrinivas Kandagatla #include <linux/pm_runtime.h>
128d78602aSSrinivas Kandagatla #include <linux/component.h>
138d78602aSSrinivas Kandagatla #include <sound/tlv.h>
148d78602aSSrinivas Kandagatla #include <linux/of_gpio.h>
158d78602aSSrinivas Kandagatla #include <linux/of.h>
168d78602aSSrinivas Kandagatla #include <sound/jack.h>
178d78602aSSrinivas Kandagatla #include <sound/pcm.h>
188d78602aSSrinivas Kandagatla #include <sound/pcm_params.h>
198d78602aSSrinivas Kandagatla #include <linux/regmap.h>
208d78602aSSrinivas Kandagatla #include <sound/soc.h>
218d78602aSSrinivas Kandagatla #include <sound/soc-dapm.h>
228d78602aSSrinivas Kandagatla #include <linux/regulator/consumer.h>
238d78602aSSrinivas Kandagatla
248d78602aSSrinivas Kandagatla #include "wcd-clsh-v2.h"
25bcee7ed0SSrinivas Kandagatla #include "wcd-mbhc-v2.h"
268d78602aSSrinivas Kandagatla #include "wcd938x.h"
278d78602aSSrinivas Kandagatla
288d78602aSSrinivas Kandagatla #define WCD938X_MAX_MICBIAS (4)
298d78602aSSrinivas Kandagatla #define WCD938X_MAX_SUPPLY (4)
308d78602aSSrinivas Kandagatla #define WCD938X_MBHC_MAX_BUTTONS (8)
318d78602aSSrinivas Kandagatla #define TX_ADC_MAX (4)
328d78602aSSrinivas Kandagatla #define WCD938X_TX_MAX_SWR_PORTS (5)
338d78602aSSrinivas Kandagatla
348d78602aSSrinivas Kandagatla #define WCD938X_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
358d78602aSSrinivas Kandagatla SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
368d78602aSSrinivas Kandagatla SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
378d78602aSSrinivas Kandagatla /* Fractional Rates */
388d78602aSSrinivas Kandagatla #define WCD938X_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
398d78602aSSrinivas Kandagatla SNDRV_PCM_RATE_176400)
408d78602aSSrinivas Kandagatla #define WCD938X_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
418d78602aSSrinivas Kandagatla SNDRV_PCM_FMTBIT_S24_LE)
428d78602aSSrinivas Kandagatla /* Convert from vout ctl to micbias voltage in mV */
438d78602aSSrinivas Kandagatla #define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
448d78602aSSrinivas Kandagatla #define SWR_CLK_RATE_0P6MHZ (600000)
458d78602aSSrinivas Kandagatla #define SWR_CLK_RATE_1P2MHZ (1200000)
468d78602aSSrinivas Kandagatla #define SWR_CLK_RATE_2P4MHZ (2400000)
478d78602aSSrinivas Kandagatla #define SWR_CLK_RATE_4P8MHZ (4800000)
488d78602aSSrinivas Kandagatla #define SWR_CLK_RATE_9P6MHZ (9600000)
498d78602aSSrinivas Kandagatla #define SWR_CLK_RATE_11P2896MHZ (1128960)
508d78602aSSrinivas Kandagatla
518d78602aSSrinivas Kandagatla #define WCD938X_DRV_NAME "wcd938x_codec"
528d78602aSSrinivas Kandagatla #define WCD938X_VERSION_1_0 (1)
538d78602aSSrinivas Kandagatla #define EAR_RX_PATH_AUX (1)
548d78602aSSrinivas Kandagatla
558d78602aSSrinivas Kandagatla #define ADC_MODE_VAL_HIFI 0x01
568d78602aSSrinivas Kandagatla #define ADC_MODE_VAL_LO_HIF 0x02
578d78602aSSrinivas Kandagatla #define ADC_MODE_VAL_NORMAL 0x03
588d78602aSSrinivas Kandagatla #define ADC_MODE_VAL_LP 0x05
598d78602aSSrinivas Kandagatla #define ADC_MODE_VAL_ULP1 0x09
608d78602aSSrinivas Kandagatla #define ADC_MODE_VAL_ULP2 0x0B
618d78602aSSrinivas Kandagatla
628d78602aSSrinivas Kandagatla /* Z value defined in milliohm */
638d78602aSSrinivas Kandagatla #define WCD938X_ZDET_VAL_32 (32000)
648d78602aSSrinivas Kandagatla #define WCD938X_ZDET_VAL_400 (400000)
658d78602aSSrinivas Kandagatla #define WCD938X_ZDET_VAL_1200 (1200000)
668d78602aSSrinivas Kandagatla #define WCD938X_ZDET_VAL_100K (100000000)
678d78602aSSrinivas Kandagatla /* Z floating defined in ohms */
688d78602aSSrinivas Kandagatla #define WCD938X_ZDET_FLOATING_IMPEDANCE (0x0FFFFFFE)
698d78602aSSrinivas Kandagatla #define WCD938X_ZDET_NUM_MEASUREMENTS (900)
708d78602aSSrinivas Kandagatla #define WCD938X_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
718d78602aSSrinivas Kandagatla #define WCD938X_MBHC_GET_X1(x) (x & 0x3FFF)
728d78602aSSrinivas Kandagatla /* Z value compared in milliOhm */
738d78602aSSrinivas Kandagatla #define WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
748d78602aSSrinivas Kandagatla #define WCD938X_MBHC_ZDET_CONST (86 * 16384)
758d78602aSSrinivas Kandagatla #define WCD938X_MBHC_MOISTURE_RREF R_24_KOHM
768d78602aSSrinivas Kandagatla #define WCD_MBHC_HS_V_MAX 1600
778d78602aSSrinivas Kandagatla
78e8ba1e05SSrinivas Kandagatla #define WCD938X_EAR_PA_GAIN_TLV(xname, reg, shift, max, invert, tlv_array) \
79e8ba1e05SSrinivas Kandagatla { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
80e8ba1e05SSrinivas Kandagatla .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
81e8ba1e05SSrinivas Kandagatla SNDRV_CTL_ELEM_ACCESS_READWRITE,\
82e8ba1e05SSrinivas Kandagatla .tlv.p = (tlv_array), \
83e8ba1e05SSrinivas Kandagatla .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
84e8ba1e05SSrinivas Kandagatla .put = wcd938x_ear_pa_put_gain, \
85e8ba1e05SSrinivas Kandagatla .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
86e8ba1e05SSrinivas Kandagatla
878d78602aSSrinivas Kandagatla enum {
888d78602aSSrinivas Kandagatla WCD9380 = 0,
898d78602aSSrinivas Kandagatla WCD9385 = 5,
908d78602aSSrinivas Kandagatla };
918d78602aSSrinivas Kandagatla
928d78602aSSrinivas Kandagatla enum {
938d78602aSSrinivas Kandagatla TX_HDR12 = 0,
948d78602aSSrinivas Kandagatla TX_HDR34,
958d78602aSSrinivas Kandagatla TX_HDR_MAX,
968d78602aSSrinivas Kandagatla };
978d78602aSSrinivas Kandagatla
988d78602aSSrinivas Kandagatla enum {
998d78602aSSrinivas Kandagatla WCD_RX1,
1008d78602aSSrinivas Kandagatla WCD_RX2,
1018d78602aSSrinivas Kandagatla WCD_RX3
1028d78602aSSrinivas Kandagatla };
1038d78602aSSrinivas Kandagatla
1048d78602aSSrinivas Kandagatla enum {
1058d78602aSSrinivas Kandagatla /* INTR_CTRL_INT_MASK_0 */
1068d78602aSSrinivas Kandagatla WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0,
1078d78602aSSrinivas Kandagatla WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET,
1088d78602aSSrinivas Kandagatla WCD938X_IRQ_MBHC_ELECT_INS_REM_DET,
1098d78602aSSrinivas Kandagatla WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
1108d78602aSSrinivas Kandagatla WCD938X_IRQ_MBHC_SW_DET,
1118d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHR_OCP_INT,
1128d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHR_CNP_INT,
1138d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHL_OCP_INT,
1148d78602aSSrinivas Kandagatla
1158d78602aSSrinivas Kandagatla /* INTR_CTRL_INT_MASK_1 */
1168d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHL_CNP_INT,
1178d78602aSSrinivas Kandagatla WCD938X_IRQ_EAR_CNP_INT,
1188d78602aSSrinivas Kandagatla WCD938X_IRQ_EAR_SCD_INT,
1198d78602aSSrinivas Kandagatla WCD938X_IRQ_AUX_CNP_INT,
1208d78602aSSrinivas Kandagatla WCD938X_IRQ_AUX_SCD_INT,
1218d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHL_PDM_WD_INT,
1228d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHR_PDM_WD_INT,
1238d78602aSSrinivas Kandagatla WCD938X_IRQ_AUX_PDM_WD_INT,
1248d78602aSSrinivas Kandagatla
1258d78602aSSrinivas Kandagatla /* INTR_CTRL_INT_MASK_2 */
1268d78602aSSrinivas Kandagatla WCD938X_IRQ_LDORT_SCD_INT,
1278d78602aSSrinivas Kandagatla WCD938X_IRQ_MBHC_MOISTURE_INT,
1288d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHL_SURGE_DET_INT,
1298d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHR_SURGE_DET_INT,
1308d78602aSSrinivas Kandagatla WCD938X_NUM_IRQS,
1318d78602aSSrinivas Kandagatla };
1328d78602aSSrinivas Kandagatla
1338d78602aSSrinivas Kandagatla enum {
1348d78602aSSrinivas Kandagatla WCD_ADC1 = 0,
1358d78602aSSrinivas Kandagatla WCD_ADC2,
1368d78602aSSrinivas Kandagatla WCD_ADC3,
1378d78602aSSrinivas Kandagatla WCD_ADC4,
1388d78602aSSrinivas Kandagatla ALLOW_BUCK_DISABLE,
1398d78602aSSrinivas Kandagatla HPH_COMP_DELAY,
1408d78602aSSrinivas Kandagatla HPH_PA_DELAY,
1418d78602aSSrinivas Kandagatla AMIC2_BCS_ENABLE,
1428d78602aSSrinivas Kandagatla WCD_SUPPLIES_LPM_MODE,
1438d78602aSSrinivas Kandagatla };
1448d78602aSSrinivas Kandagatla
1458d78602aSSrinivas Kandagatla enum {
1468d78602aSSrinivas Kandagatla ADC_MODE_INVALID = 0,
1478d78602aSSrinivas Kandagatla ADC_MODE_HIFI,
1488d78602aSSrinivas Kandagatla ADC_MODE_LO_HIF,
1498d78602aSSrinivas Kandagatla ADC_MODE_NORMAL,
1508d78602aSSrinivas Kandagatla ADC_MODE_LP,
1518d78602aSSrinivas Kandagatla ADC_MODE_ULP1,
1528d78602aSSrinivas Kandagatla ADC_MODE_ULP2,
1538d78602aSSrinivas Kandagatla };
1548d78602aSSrinivas Kandagatla
1558d78602aSSrinivas Kandagatla enum {
1568d78602aSSrinivas Kandagatla AIF1_PB = 0,
1578d78602aSSrinivas Kandagatla AIF1_CAP,
1588d78602aSSrinivas Kandagatla NUM_CODEC_DAIS,
1598d78602aSSrinivas Kandagatla };
1608d78602aSSrinivas Kandagatla
161d5add08fSSrinivas Kandagatla static u8 tx_mode_bit[] = {
162d5add08fSSrinivas Kandagatla [ADC_MODE_INVALID] = 0x00,
163d5add08fSSrinivas Kandagatla [ADC_MODE_HIFI] = 0x01,
164d5add08fSSrinivas Kandagatla [ADC_MODE_LO_HIF] = 0x02,
165d5add08fSSrinivas Kandagatla [ADC_MODE_NORMAL] = 0x04,
166d5add08fSSrinivas Kandagatla [ADC_MODE_LP] = 0x08,
167d5add08fSSrinivas Kandagatla [ADC_MODE_ULP1] = 0x10,
168d5add08fSSrinivas Kandagatla [ADC_MODE_ULP2] = 0x20,
169d5add08fSSrinivas Kandagatla };
170d5add08fSSrinivas Kandagatla
1718d78602aSSrinivas Kandagatla struct wcd938x_priv {
1728d78602aSSrinivas Kandagatla struct sdw_slave *tx_sdw_dev;
1738d78602aSSrinivas Kandagatla struct wcd938x_sdw_priv *sdw_priv[NUM_CODEC_DAIS];
1748d78602aSSrinivas Kandagatla struct device *txdev;
1758d78602aSSrinivas Kandagatla struct device *rxdev;
1768d78602aSSrinivas Kandagatla struct device_node *rxnode, *txnode;
1778d78602aSSrinivas Kandagatla struct regmap *regmap;
178bcee7ed0SSrinivas Kandagatla struct mutex micb_lock;
179bcee7ed0SSrinivas Kandagatla /* mbhc module */
180bcee7ed0SSrinivas Kandagatla struct wcd_mbhc *wcd_mbhc;
181bcee7ed0SSrinivas Kandagatla struct wcd_mbhc_config mbhc_cfg;
182bcee7ed0SSrinivas Kandagatla struct wcd_mbhc_intr intr_ids;
1838d78602aSSrinivas Kandagatla struct wcd_clsh_ctrl *clsh_info;
1848d78602aSSrinivas Kandagatla struct irq_domain *virq;
1858d78602aSSrinivas Kandagatla struct regmap_irq_chip *wcd_regmap_irq_chip;
1868d78602aSSrinivas Kandagatla struct regmap_irq_chip_data *irq_chip;
1878d78602aSSrinivas Kandagatla struct regulator_bulk_data supplies[WCD938X_MAX_SUPPLY];
1888d78602aSSrinivas Kandagatla struct snd_soc_jack *jack;
1898d78602aSSrinivas Kandagatla unsigned long status_mask;
1908d78602aSSrinivas Kandagatla s32 micb_ref[WCD938X_MAX_MICBIAS];
1918d78602aSSrinivas Kandagatla s32 pullup_ref[WCD938X_MAX_MICBIAS];
1928d78602aSSrinivas Kandagatla u32 hph_mode;
1938d78602aSSrinivas Kandagatla u32 tx_mode[TX_ADC_MAX];
1948d78602aSSrinivas Kandagatla int flyback_cur_det_disable;
1958d78602aSSrinivas Kandagatla int ear_rx_path;
1968d78602aSSrinivas Kandagatla int variant;
1978d78602aSSrinivas Kandagatla int reset_gpio;
198db0b4aedSSrinivasa Rao Mandadapu struct gpio_desc *us_euro_gpio;
1998d78602aSSrinivas Kandagatla u32 micb1_mv;
2008d78602aSSrinivas Kandagatla u32 micb2_mv;
2018d78602aSSrinivas Kandagatla u32 micb3_mv;
2028d78602aSSrinivas Kandagatla u32 micb4_mv;
2038d78602aSSrinivas Kandagatla int hphr_pdm_wd_int;
2048d78602aSSrinivas Kandagatla int hphl_pdm_wd_int;
2058d78602aSSrinivas Kandagatla int aux_pdm_wd_int;
2068d78602aSSrinivas Kandagatla bool comp1_enable;
2078d78602aSSrinivas Kandagatla bool comp2_enable;
2088d78602aSSrinivas Kandagatla bool ldoh;
2098d78602aSSrinivas Kandagatla bool bcs_dis;
2108d78602aSSrinivas Kandagatla };
2118d78602aSSrinivas Kandagatla
212e8ba1e05SSrinivas Kandagatla static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800);
2139e0454ccSJohan Hovold static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, 0);
214e8ba1e05SSrinivas Kandagatla static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000);
215e8ba1e05SSrinivas Kandagatla
216bcee7ed0SSrinivas Kandagatla struct wcd938x_mbhc_zdet_param {
217bcee7ed0SSrinivas Kandagatla u16 ldo_ctl;
218bcee7ed0SSrinivas Kandagatla u16 noff;
219bcee7ed0SSrinivas Kandagatla u16 nshift;
220bcee7ed0SSrinivas Kandagatla u16 btn5;
221bcee7ed0SSrinivas Kandagatla u16 btn6;
222bcee7ed0SSrinivas Kandagatla u16 btn7;
223bcee7ed0SSrinivas Kandagatla };
224bcee7ed0SSrinivas Kandagatla
225bcee7ed0SSrinivas Kandagatla static struct wcd_mbhc_field wcd_mbhc_fields[WCD_MBHC_REG_FUNC_MAX] = {
226bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_L_DET_EN, WCD938X_ANA_MBHC_MECH, 0x80),
227bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_GND_DET_EN, WCD938X_ANA_MBHC_MECH, 0x40),
228bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MECH_DETECTION_TYPE, WCD938X_ANA_MBHC_MECH, 0x20),
229bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MIC_CLAMP_CTL, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x30),
230bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ELECT_DETECTION_TYPE, WCD938X_ANA_MBHC_ELECT, 0x08),
231bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F),
232bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, WCD938X_ANA_MBHC_MECH, 0x04),
233bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHL_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x10),
234bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_GND_PLUG_TYPE, WCD938X_ANA_MBHC_MECH, 0x08),
235bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_SW_HPH_LP_100K_TO_GND, WCD938X_ANA_MBHC_MECH, 0x01),
236bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ELECT_SCHMT_ISRC, WCD938X_ANA_MBHC_ELECT, 0x06),
237bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_FSM_EN, WCD938X_ANA_MBHC_ELECT, 0x80),
238bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_INSREM_DBNC, WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0x0F),
239bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_BTN_DBNC, WCD938X_MBHC_NEW_CTL_1, 0x03),
240bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HS_VREF, WCD938X_MBHC_NEW_CTL_2, 0x03),
241bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HS_COMP_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x08),
242bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_IN2P_CLAMP_STATE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
243bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MIC_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x20),
244bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHL_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x80),
245bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHR_SCHMT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x40),
246bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_OCP_FSM_EN, WCD938X_HPH_OCP_CTL, 0x10),
247bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_BTN_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0x07),
248bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_BTN_ISRC_CTL, WCD938X_ANA_MBHC_ELECT, 0x70),
249bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ELECT_RESULT, WCD938X_ANA_MBHC_RESULT_3, 0xFF),
250bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MICB_CTRL, WCD938X_ANA_MICB2, 0xC0),
251bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPH_CNP_WG_TIME, WCD938X_HPH_CNP_WG_TIME, 0xFF),
252bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHR_PA_EN, WCD938X_ANA_HPH, 0x40),
253bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHL_PA_EN, WCD938X_ANA_HPH, 0x80),
254bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPH_PA_EN, WCD938X_ANA_HPH, 0xC0),
255bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_SWCH_LEVEL_REMOVE, WCD938X_ANA_MBHC_RESULT_3, 0x10),
256bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ANC_DET_EN, WCD938X_MBHC_CTL_BCS, 0x02),
257bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_FSM_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x01),
258bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MUX_CTL, WCD938X_MBHC_NEW_CTL_2, 0x70),
259bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MOISTURE_STATUS, WCD938X_MBHC_NEW_FSM_STATUS, 0x20),
260bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHR_GND, WCD938X_HPH_PA_CTL2, 0x40),
261bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHL_GND, WCD938X_HPH_PA_CTL2, 0x10),
262bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_DET_EN, WCD938X_HPH_L_TEST, 0x01),
263bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_DET_EN, WCD938X_HPH_R_TEST, 0x01),
264bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHL_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x80),
265bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_HPHR_OCP_STATUS, WCD938X_DIGITAL_INTR_STATUS_0, 0x20),
266bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ADC_EN, WCD938X_MBHC_NEW_CTL_1, 0x08),
267bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ADC_COMPLETE, WCD938X_MBHC_NEW_FSM_STATUS, 0x40),
268bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ADC_TIMEOUT, WCD938X_MBHC_NEW_FSM_STATUS, 0x80),
269bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ADC_RESULT, WCD938X_MBHC_NEW_ADC_RESULT, 0xFF),
270bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_MICB2_VOUT, WCD938X_ANA_MICB2, 0x3F),
271bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ADC_MODE, WCD938X_MBHC_NEW_CTL_1, 0x10),
272bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_DETECTION_DONE, WCD938X_MBHC_NEW_CTL_1, 0x04),
273bcee7ed0SSrinivas Kandagatla WCD_MBHC_FIELD(WCD_MBHC_ELECT_ISRC_EN, WCD938X_ANA_MBHC_ZDET, 0x02),
274bcee7ed0SSrinivas Kandagatla };
275bcee7ed0SSrinivas Kandagatla
2768d78602aSSrinivas Kandagatla static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = {
2778d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
2788d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x02),
2798d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04),
2808d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08),
2818d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_SW_DET, 0, 0x10),
2828d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_OCP_INT, 0, 0x20),
2838d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_CNP_INT, 0, 0x40),
2848d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_OCP_INT, 0, 0x80),
2858d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_CNP_INT, 1, 0x01),
2868d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_EAR_CNP_INT, 1, 0x02),
2878d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_EAR_SCD_INT, 1, 0x04),
2888d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_AUX_CNP_INT, 1, 0x08),
2898d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_AUX_SCD_INT, 1, 0x10),
2908d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_PDM_WD_INT, 1, 0x20),
2918d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_PDM_WD_INT, 1, 0x40),
2928d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_AUX_PDM_WD_INT, 1, 0x80),
2938d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_LDORT_SCD_INT, 2, 0x01),
2948d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_MBHC_MOISTURE_INT, 2, 0x02),
2958d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHL_SURGE_DET_INT, 2, 0x04),
2968d78602aSSrinivas Kandagatla REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08),
2978d78602aSSrinivas Kandagatla };
2988d78602aSSrinivas Kandagatla
2998d78602aSSrinivas Kandagatla static struct regmap_irq_chip wcd938x_regmap_irq_chip = {
3008d78602aSSrinivas Kandagatla .name = "wcd938x",
3018d78602aSSrinivas Kandagatla .irqs = wcd938x_irqs,
3028d78602aSSrinivas Kandagatla .num_irqs = ARRAY_SIZE(wcd938x_irqs),
3038d78602aSSrinivas Kandagatla .num_regs = 3,
3048d78602aSSrinivas Kandagatla .status_base = WCD938X_DIGITAL_INTR_STATUS_0,
3058d78602aSSrinivas Kandagatla .mask_base = WCD938X_DIGITAL_INTR_MASK_0,
3068d78602aSSrinivas Kandagatla .ack_base = WCD938X_DIGITAL_INTR_CLEAR_0,
3078d78602aSSrinivas Kandagatla .use_ack = 1,
3088d78602aSSrinivas Kandagatla .runtime_pm = true,
3098d78602aSSrinivas Kandagatla .irq_drv_data = NULL,
3108d78602aSSrinivas Kandagatla };
3118d78602aSSrinivas Kandagatla
wcd938x_get_clk_rate(int mode)312d5add08fSSrinivas Kandagatla static int wcd938x_get_clk_rate(int mode)
313d5add08fSSrinivas Kandagatla {
314d5add08fSSrinivas Kandagatla int rate;
315d5add08fSSrinivas Kandagatla
316d5add08fSSrinivas Kandagatla switch (mode) {
317d5add08fSSrinivas Kandagatla case ADC_MODE_ULP2:
318d5add08fSSrinivas Kandagatla rate = SWR_CLK_RATE_0P6MHZ;
319d5add08fSSrinivas Kandagatla break;
320d5add08fSSrinivas Kandagatla case ADC_MODE_ULP1:
321d5add08fSSrinivas Kandagatla rate = SWR_CLK_RATE_1P2MHZ;
322d5add08fSSrinivas Kandagatla break;
323d5add08fSSrinivas Kandagatla case ADC_MODE_LP:
324d5add08fSSrinivas Kandagatla rate = SWR_CLK_RATE_4P8MHZ;
325d5add08fSSrinivas Kandagatla break;
326d5add08fSSrinivas Kandagatla case ADC_MODE_NORMAL:
327d5add08fSSrinivas Kandagatla case ADC_MODE_LO_HIF:
328d5add08fSSrinivas Kandagatla case ADC_MODE_HIFI:
329d5add08fSSrinivas Kandagatla case ADC_MODE_INVALID:
330d5add08fSSrinivas Kandagatla default:
331d5add08fSSrinivas Kandagatla rate = SWR_CLK_RATE_9P6MHZ;
332d5add08fSSrinivas Kandagatla break;
333d5add08fSSrinivas Kandagatla }
334d5add08fSSrinivas Kandagatla
335d5add08fSSrinivas Kandagatla return rate;
336d5add08fSSrinivas Kandagatla }
337d5add08fSSrinivas Kandagatla
wcd938x_set_swr_clk_rate(struct snd_soc_component * component,int rate,int bank)338d5add08fSSrinivas Kandagatla static int wcd938x_set_swr_clk_rate(struct snd_soc_component *component, int rate, int bank)
339d5add08fSSrinivas Kandagatla {
340d5add08fSSrinivas Kandagatla u8 mask = (bank ? 0xF0 : 0x0F);
341d5add08fSSrinivas Kandagatla u8 val = 0;
342d5add08fSSrinivas Kandagatla
343d5add08fSSrinivas Kandagatla switch (rate) {
344d5add08fSSrinivas Kandagatla case SWR_CLK_RATE_0P6MHZ:
345d5add08fSSrinivas Kandagatla val = (bank ? 0x60 : 0x06);
346d5add08fSSrinivas Kandagatla break;
347d5add08fSSrinivas Kandagatla case SWR_CLK_RATE_1P2MHZ:
348d5add08fSSrinivas Kandagatla val = (bank ? 0x50 : 0x05);
349d5add08fSSrinivas Kandagatla break;
350d5add08fSSrinivas Kandagatla case SWR_CLK_RATE_2P4MHZ:
351d5add08fSSrinivas Kandagatla val = (bank ? 0x30 : 0x03);
352d5add08fSSrinivas Kandagatla break;
353d5add08fSSrinivas Kandagatla case SWR_CLK_RATE_4P8MHZ:
354d5add08fSSrinivas Kandagatla val = (bank ? 0x10 : 0x01);
355d5add08fSSrinivas Kandagatla break;
356d5add08fSSrinivas Kandagatla case SWR_CLK_RATE_9P6MHZ:
357d5add08fSSrinivas Kandagatla default:
358d5add08fSSrinivas Kandagatla val = 0x00;
359d5add08fSSrinivas Kandagatla break;
360d5add08fSSrinivas Kandagatla }
361d5add08fSSrinivas Kandagatla snd_soc_component_update_bits(component, WCD938X_DIGITAL_SWR_TX_CLK_RATE,
362d5add08fSSrinivas Kandagatla mask, val);
363d5add08fSSrinivas Kandagatla
364d5add08fSSrinivas Kandagatla return 0;
365d5add08fSSrinivas Kandagatla }
366d5add08fSSrinivas Kandagatla
wcd938x_io_init(struct wcd938x_priv * wcd938x)3678d78602aSSrinivas Kandagatla static int wcd938x_io_init(struct wcd938x_priv *wcd938x)
3688d78602aSSrinivas Kandagatla {
3698d78602aSSrinivas Kandagatla struct regmap *rm = wcd938x->regmap;
3708d78602aSSrinivas Kandagatla
3718d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x0E, 0x0E);
3728d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x80, 0x80);
3738d78602aSSrinivas Kandagatla /* 1 msec delay as per HW requirement */
3748d78602aSSrinivas Kandagatla usleep_range(1000, 1010);
3758d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_SLEEP_CTL, 0x40, 0x40);
3768d78602aSSrinivas Kandagatla /* 1 msec delay as per HW requirement */
3778d78602aSSrinivas Kandagatla usleep_range(1000, 1010);
3788d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_LDORXTX_CONFIG, 0x10, 0x00);
3798d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_BIAS_VBG_FINE_ADJ,
3808d78602aSSrinivas Kandagatla 0xF0, 0x80);
3818d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x80, 0x80);
3828d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x40, 0x40);
3838d78602aSSrinivas Kandagatla /* 10 msec delay as per HW requirement */
3848d78602aSSrinivas Kandagatla usleep_range(10000, 10010);
3858d78602aSSrinivas Kandagatla
3868d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_ANA_BIAS, 0x40, 0x00);
3878d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL,
3888d78602aSSrinivas Kandagatla 0xF0, 0x00);
3898d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW,
3908d78602aSSrinivas Kandagatla 0x1F, 0x15);
3918d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW,
3928d78602aSSrinivas Kandagatla 0x1F, 0x15);
3938d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_HPH_REFBUFF_UHQA_CTL,
3948d78602aSSrinivas Kandagatla 0xC0, 0x80);
3958d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_DIGITAL_CDC_DMIC_CTL,
3968d78602aSSrinivas Kandagatla 0x02, 0x02);
3978d78602aSSrinivas Kandagatla
3988d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP,
3998d78602aSSrinivas Kandagatla 0xFF, 0x14);
4008d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP,
4018d78602aSSrinivas Kandagatla 0x1F, 0x08);
4028d78602aSSrinivas Kandagatla
4038d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0xFF, 0x55);
4048d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0xFF, 0x44);
4058d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0xFF, 0x11);
4068d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0xFF, 0x00);
4078d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0xFF, 0x00);
4088d78602aSSrinivas Kandagatla
4098d78602aSSrinivas Kandagatla /* Set Noise Filter Resistor value */
4108d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_MICB1_TEST_CTL_1, 0xE0, 0xE0);
4118d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_MICB2_TEST_CTL_1, 0xE0, 0xE0);
4128d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_MICB3_TEST_CTL_1, 0xE0, 0xE0);
4138d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_MICB4_TEST_CTL_1, 0xE0, 0xE0);
4148d78602aSSrinivas Kandagatla
4158d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_TX_3_4_TEST_BLK_EN2, 0x01, 0x00);
4168d78602aSSrinivas Kandagatla regmap_update_bits(rm, WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
4178d78602aSSrinivas Kandagatla
4188d78602aSSrinivas Kandagatla return 0;
4198d78602aSSrinivas Kandagatla
4208d78602aSSrinivas Kandagatla }
4218d78602aSSrinivas Kandagatla
wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info * ch_info,struct sdw_port_config * port_config,u8 enable)422e8ba1e05SSrinivas Kandagatla static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
423e8ba1e05SSrinivas Kandagatla struct sdw_port_config *port_config,
424e8ba1e05SSrinivas Kandagatla u8 enable)
425e8ba1e05SSrinivas Kandagatla {
426e8ba1e05SSrinivas Kandagatla u8 ch_mask, port_num;
427e8ba1e05SSrinivas Kandagatla
428e8ba1e05SSrinivas Kandagatla port_num = ch_info->port_num;
429e8ba1e05SSrinivas Kandagatla ch_mask = ch_info->ch_mask;
430e8ba1e05SSrinivas Kandagatla
431e8ba1e05SSrinivas Kandagatla port_config->num = port_num;
432e8ba1e05SSrinivas Kandagatla
433e8ba1e05SSrinivas Kandagatla if (enable)
434e8ba1e05SSrinivas Kandagatla port_config->ch_mask |= ch_mask;
435e8ba1e05SSrinivas Kandagatla else
436e8ba1e05SSrinivas Kandagatla port_config->ch_mask &= ~ch_mask;
437e8ba1e05SSrinivas Kandagatla
438e8ba1e05SSrinivas Kandagatla return 0;
439e8ba1e05SSrinivas Kandagatla }
440e8ba1e05SSrinivas Kandagatla
wcd938x_connect_port(struct wcd938x_sdw_priv * wcd,u8 port_num,u8 ch_id,u8 enable)441c5c1546aSSrinivas Kandagatla static int wcd938x_connect_port(struct wcd938x_sdw_priv *wcd, u8 port_num, u8 ch_id, u8 enable)
442e8ba1e05SSrinivas Kandagatla {
443e8ba1e05SSrinivas Kandagatla return wcd938x_sdw_connect_port(&wcd->ch_info[ch_id],
444c5c1546aSSrinivas Kandagatla &wcd->port_config[port_num - 1],
445e8ba1e05SSrinivas Kandagatla enable);
446e8ba1e05SSrinivas Kandagatla }
447e8ba1e05SSrinivas Kandagatla
wcd938x_codec_enable_rxclk(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)4488da9db0cSSrinivas Kandagatla static int wcd938x_codec_enable_rxclk(struct snd_soc_dapm_widget *w,
4498da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
4508da9db0cSSrinivas Kandagatla int event)
4518da9db0cSSrinivas Kandagatla {
4528da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
4538da9db0cSSrinivas Kandagatla
4548da9db0cSSrinivas Kandagatla switch (event) {
4558da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
4568da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
4578da9db0cSSrinivas Kandagatla WCD938X_ANA_RX_CLK_EN_MASK, 1);
4588da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
4598da9db0cSSrinivas Kandagatla WCD938X_RX_BIAS_EN_MASK, 1);
4608da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX0_CTL,
4618da9db0cSSrinivas Kandagatla WCD938X_DEM_DITHER_ENABLE_MASK, 0);
4628da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX1_CTL,
4638da9db0cSSrinivas Kandagatla WCD938X_DEM_DITHER_ENABLE_MASK, 0);
4648da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_RX2_CTL,
4658da9db0cSSrinivas Kandagatla WCD938X_DEM_DITHER_ENABLE_MASK, 0);
4668da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
4678da9db0cSSrinivas Kandagatla WCD938X_ANA_RX_DIV2_CLK_EN_MASK, 1);
4688da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_AUX_AUXPA,
4698da9db0cSSrinivas Kandagatla WCD938X_AUXPA_CLK_EN_MASK, 1);
4708da9db0cSSrinivas Kandagatla break;
4718da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
4728da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
4738da9db0cSSrinivas Kandagatla WCD938X_VNEG_EN_MASK, 0);
4748da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
4758da9db0cSSrinivas Kandagatla WCD938X_VPOS_EN_MASK, 0);
4768da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
4778da9db0cSSrinivas Kandagatla WCD938X_RX_BIAS_EN_MASK, 0);
4788da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
4798da9db0cSSrinivas Kandagatla WCD938X_ANA_RX_DIV2_CLK_EN_MASK, 0);
4808da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
4818da9db0cSSrinivas Kandagatla WCD938X_ANA_RX_CLK_EN_MASK, 0);
4828da9db0cSSrinivas Kandagatla break;
4838da9db0cSSrinivas Kandagatla }
4848da9db0cSSrinivas Kandagatla return 0;
4858da9db0cSSrinivas Kandagatla }
4868da9db0cSSrinivas Kandagatla
wcd938x_codec_hphl_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)4878da9db0cSSrinivas Kandagatla static int wcd938x_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
4888da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
4898da9db0cSSrinivas Kandagatla int event)
4908da9db0cSSrinivas Kandagatla {
4918da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
4928da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
4938da9db0cSSrinivas Kandagatla
4948da9db0cSSrinivas Kandagatla switch (event) {
4958da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
4968da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
4978da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
4988da9db0cSSrinivas Kandagatla WCD938X_RXD0_CLK_EN_MASK, 0x01);
4998da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5008da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
5018da9db0cSSrinivas Kandagatla WCD938X_HPHL_RX_EN_MASK, 1);
5028da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5038da9db0cSSrinivas Kandagatla WCD938X_HPH_RDAC_CLK_CTL1,
5048da9db0cSSrinivas Kandagatla WCD938X_CHOP_CLK_EN_MASK, 0);
5058da9db0cSSrinivas Kandagatla break;
5068da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
5078da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5088da9db0cSSrinivas Kandagatla WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L,
5098da9db0cSSrinivas Kandagatla WCD938X_HPH_RES_DIV_MASK, 0x02);
5108da9db0cSSrinivas Kandagatla if (wcd938x->comp1_enable) {
5118da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5128da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0,
5138da9db0cSSrinivas Kandagatla WCD938X_HPHL_COMP_EN_MASK, 1);
5148da9db0cSSrinivas Kandagatla /* 5msec compander delay as per HW requirement */
5158da9db0cSSrinivas Kandagatla if (!wcd938x->comp2_enable || (snd_soc_component_read(component,
5168da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x01))
5178da9db0cSSrinivas Kandagatla usleep_range(5000, 5010);
5188da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
5198da9db0cSSrinivas Kandagatla WCD938X_AUTOCHOP_TIMER_EN, 0);
5208da9db0cSSrinivas Kandagatla } else {
5218da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5228da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0,
5238da9db0cSSrinivas Kandagatla WCD938X_HPHL_COMP_EN_MASK, 0);
5248da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5258da9db0cSSrinivas Kandagatla WCD938X_HPH_L_EN,
5268da9db0cSSrinivas Kandagatla WCD938X_GAIN_SRC_SEL_MASK,
5278da9db0cSSrinivas Kandagatla WCD938X_GAIN_SRC_SEL_REGISTER);
5288da9db0cSSrinivas Kandagatla
5298da9db0cSSrinivas Kandagatla }
5308da9db0cSSrinivas Kandagatla break;
5318da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
5328da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5338da9db0cSSrinivas Kandagatla WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
5348da9db0cSSrinivas Kandagatla WCD938X_HPH_RES_DIV_MASK, 0x1);
5358da9db0cSSrinivas Kandagatla break;
5368da9db0cSSrinivas Kandagatla }
5378da9db0cSSrinivas Kandagatla
5388da9db0cSSrinivas Kandagatla return 0;
5398da9db0cSSrinivas Kandagatla }
5408da9db0cSSrinivas Kandagatla
wcd938x_codec_hphr_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)5418da9db0cSSrinivas Kandagatla static int wcd938x_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
5428da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
5438da9db0cSSrinivas Kandagatla int event)
5448da9db0cSSrinivas Kandagatla {
5458da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
5468da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
5478da9db0cSSrinivas Kandagatla
5488da9db0cSSrinivas Kandagatla switch (event) {
5498da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
5508da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5518da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
5528da9db0cSSrinivas Kandagatla WCD938X_RXD1_CLK_EN_MASK, 1);
5538da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5548da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
5558da9db0cSSrinivas Kandagatla WCD938X_HPHR_RX_EN_MASK, 1);
5568da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5578da9db0cSSrinivas Kandagatla WCD938X_HPH_RDAC_CLK_CTL1,
5588da9db0cSSrinivas Kandagatla WCD938X_CHOP_CLK_EN_MASK, 0);
5598da9db0cSSrinivas Kandagatla break;
5608da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
5618da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5628da9db0cSSrinivas Kandagatla WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
5638da9db0cSSrinivas Kandagatla WCD938X_HPH_RES_DIV_MASK, 0x02);
5648da9db0cSSrinivas Kandagatla if (wcd938x->comp2_enable) {
5658da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5668da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0,
5678da9db0cSSrinivas Kandagatla WCD938X_HPHR_COMP_EN_MASK, 1);
5688da9db0cSSrinivas Kandagatla /* 5msec compander delay as per HW requirement */
5698da9db0cSSrinivas Kandagatla if (!wcd938x->comp1_enable ||
5708da9db0cSSrinivas Kandagatla (snd_soc_component_read(component,
5718da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0) & 0x02))
5728da9db0cSSrinivas Kandagatla usleep_range(5000, 5010);
5738da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
5748da9db0cSSrinivas Kandagatla WCD938X_AUTOCHOP_TIMER_EN, 0);
5758da9db0cSSrinivas Kandagatla } else {
5768da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5778da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0,
5788da9db0cSSrinivas Kandagatla WCD938X_HPHR_COMP_EN_MASK, 0);
5798da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5808da9db0cSSrinivas Kandagatla WCD938X_HPH_R_EN,
5818da9db0cSSrinivas Kandagatla WCD938X_GAIN_SRC_SEL_MASK,
5828da9db0cSSrinivas Kandagatla WCD938X_GAIN_SRC_SEL_REGISTER);
5838da9db0cSSrinivas Kandagatla }
5848da9db0cSSrinivas Kandagatla break;
5858da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
5868da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
5878da9db0cSSrinivas Kandagatla WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R,
5888da9db0cSSrinivas Kandagatla WCD938X_HPH_RES_DIV_MASK, 0x01);
5898da9db0cSSrinivas Kandagatla break;
5908da9db0cSSrinivas Kandagatla }
5918da9db0cSSrinivas Kandagatla
5928da9db0cSSrinivas Kandagatla return 0;
5938da9db0cSSrinivas Kandagatla }
5948da9db0cSSrinivas Kandagatla
wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)5958da9db0cSSrinivas Kandagatla static int wcd938x_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
5968da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
5978da9db0cSSrinivas Kandagatla int event)
5988da9db0cSSrinivas Kandagatla {
5998da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
6008da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
6018da9db0cSSrinivas Kandagatla
6028da9db0cSSrinivas Kandagatla switch (event) {
6038da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
6048da9db0cSSrinivas Kandagatla wcd938x->ear_rx_path =
6058da9db0cSSrinivas Kandagatla snd_soc_component_read(
6068da9db0cSSrinivas Kandagatla component, WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
6078da9db0cSSrinivas Kandagatla if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
6088da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6098da9db0cSSrinivas Kandagatla WCD938X_EAR_EAR_DAC_CON,
6108da9db0cSSrinivas Kandagatla WCD938X_DAC_SAMPLE_EDGE_SEL_MASK, 0);
6118da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6128da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
6138da9db0cSSrinivas Kandagatla WCD938X_AUX_EN_MASK, 1);
6148da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6158da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
6168da9db0cSSrinivas Kandagatla WCD938X_RXD2_CLK_EN_MASK, 1);
6178da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6188da9db0cSSrinivas Kandagatla WCD938X_ANA_EAR_COMPANDER_CTL,
6198da9db0cSSrinivas Kandagatla WCD938X_GAIN_OVRD_REG_MASK, 1);
6208da9db0cSSrinivas Kandagatla } else {
6218da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6228da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
6238da9db0cSSrinivas Kandagatla WCD938X_HPHL_RX_EN_MASK, 1);
6248da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6258da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
6268da9db0cSSrinivas Kandagatla WCD938X_RXD0_CLK_EN_MASK, 1);
6278da9db0cSSrinivas Kandagatla if (wcd938x->comp1_enable)
6288da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6298da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0,
6308da9db0cSSrinivas Kandagatla WCD938X_HPHL_COMP_EN_MASK, 1);
6318da9db0cSSrinivas Kandagatla }
6328da9db0cSSrinivas Kandagatla /* 5 msec delay as per HW requirement */
6338da9db0cSSrinivas Kandagatla usleep_range(5000, 5010);
6348da9db0cSSrinivas Kandagatla if (wcd938x->flyback_cur_det_disable == 0)
6358da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
6368da9db0cSSrinivas Kandagatla WCD938X_EN_CUR_DET_MASK, 0);
6378da9db0cSSrinivas Kandagatla wcd938x->flyback_cur_det_disable++;
6388da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
6398da9db0cSSrinivas Kandagatla WCD_CLSH_EVENT_PRE_DAC,
6408da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_EAR,
6418da9db0cSSrinivas Kandagatla wcd938x->hph_mode);
6428da9db0cSSrinivas Kandagatla break;
6438da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
6448da9db0cSSrinivas Kandagatla if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX) {
6458da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6468da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
6478da9db0cSSrinivas Kandagatla WCD938X_AUX_EN_MASK, 0);
6488da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6498da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
6508da9db0cSSrinivas Kandagatla WCD938X_RXD2_CLK_EN_MASK, 0);
6518da9db0cSSrinivas Kandagatla } else {
6528da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6538da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_HPH_GAIN_CTL,
6548da9db0cSSrinivas Kandagatla WCD938X_HPHL_RX_EN_MASK, 0);
6558da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6568da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
6578da9db0cSSrinivas Kandagatla WCD938X_RXD0_CLK_EN_MASK, 0);
6588da9db0cSSrinivas Kandagatla if (wcd938x->comp1_enable)
6598da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6608da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_COMP_CTL_0,
6618da9db0cSSrinivas Kandagatla WCD938X_HPHL_COMP_EN_MASK, 0);
6628da9db0cSSrinivas Kandagatla }
6638da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
6648da9db0cSSrinivas Kandagatla WCD938X_GAIN_OVRD_REG_MASK, 0);
6658da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6668da9db0cSSrinivas Kandagatla WCD938X_EAR_EAR_DAC_CON,
6678da9db0cSSrinivas Kandagatla WCD938X_DAC_SAMPLE_EDGE_SEL_MASK, 1);
6688da9db0cSSrinivas Kandagatla break;
6698da9db0cSSrinivas Kandagatla }
6708da9db0cSSrinivas Kandagatla return 0;
6718da9db0cSSrinivas Kandagatla
6728da9db0cSSrinivas Kandagatla }
6738da9db0cSSrinivas Kandagatla
wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)6748da9db0cSSrinivas Kandagatla static int wcd938x_codec_aux_dac_event(struct snd_soc_dapm_widget *w,
6758da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
6768da9db0cSSrinivas Kandagatla int event)
6778da9db0cSSrinivas Kandagatla {
6788da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
6798da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
6808da9db0cSSrinivas Kandagatla
6818da9db0cSSrinivas Kandagatla switch (event) {
6828da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
6838da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6848da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
6858da9db0cSSrinivas Kandagatla WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 1);
6868da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6878da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
6888da9db0cSSrinivas Kandagatla WCD938X_RXD2_CLK_EN_MASK, 1);
6898da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
6908da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_AUX_GAIN_CTL,
6918da9db0cSSrinivas Kandagatla WCD938X_AUX_EN_MASK, 1);
6928da9db0cSSrinivas Kandagatla if (wcd938x->flyback_cur_det_disable == 0)
6938da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
6948da9db0cSSrinivas Kandagatla WCD938X_EN_CUR_DET_MASK, 0);
6958da9db0cSSrinivas Kandagatla wcd938x->flyback_cur_det_disable++;
6968da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
6978da9db0cSSrinivas Kandagatla WCD_CLSH_EVENT_PRE_DAC,
6988da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_AUX,
6998da9db0cSSrinivas Kandagatla wcd938x->hph_mode);
7008da9db0cSSrinivas Kandagatla break;
7018da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
7028da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
7038da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
7048da9db0cSSrinivas Kandagatla WCD938X_ANA_RX_DIV4_CLK_EN_MASK, 0);
7058da9db0cSSrinivas Kandagatla break;
7068da9db0cSSrinivas Kandagatla }
7074d0b79ecSkernel test robot return 0;
7088da9db0cSSrinivas Kandagatla
7098da9db0cSSrinivas Kandagatla }
7108da9db0cSSrinivas Kandagatla
wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)7118da9db0cSSrinivas Kandagatla static int wcd938x_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
7128da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
7138da9db0cSSrinivas Kandagatla {
7148da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
7158da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
7168da9db0cSSrinivas Kandagatla int hph_mode = wcd938x->hph_mode;
7178da9db0cSSrinivas Kandagatla
7188da9db0cSSrinivas Kandagatla switch (event) {
7198da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
7208da9db0cSSrinivas Kandagatla if (wcd938x->ldoh)
7218da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
7228da9db0cSSrinivas Kandagatla WCD938X_LDOH_EN_MASK, 1);
7238da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC,
7248da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_HPHR, hph_mode);
7258da9db0cSSrinivas Kandagatla wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI);
7268da9db0cSSrinivas Kandagatla
7278da9db0cSSrinivas Kandagatla if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
7288da9db0cSSrinivas Kandagatla hph_mode == CLS_H_ULP) {
7298da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
7308da9db0cSSrinivas Kandagatla WCD938X_HPH_REFBUFF_LP_CTL,
7318da9db0cSSrinivas Kandagatla WCD938X_PREREF_FLIT_BYPASS_MASK, 1);
7328da9db0cSSrinivas Kandagatla }
7338da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_HPH,
7348da9db0cSSrinivas Kandagatla WCD938X_HPHR_REF_EN_MASK, 1);
7358da9db0cSSrinivas Kandagatla wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode);
7368da9db0cSSrinivas Kandagatla /* 100 usec delay as per HW requirement */
7378da9db0cSSrinivas Kandagatla usleep_range(100, 110);
7388da9db0cSSrinivas Kandagatla set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
7398da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
7408da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_PDM_WD_CTL1,
7418da9db0cSSrinivas Kandagatla WCD938X_PDM_WD_EN_MASK, 0x3);
7428da9db0cSSrinivas Kandagatla break;
7438da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
7448da9db0cSSrinivas Kandagatla /*
7458da9db0cSSrinivas Kandagatla * 7ms sleep is required if compander is enabled as per
7468da9db0cSSrinivas Kandagatla * HW requirement. If compander is disabled, then
7478da9db0cSSrinivas Kandagatla * 20ms delay is required.
7488da9db0cSSrinivas Kandagatla */
7498da9db0cSSrinivas Kandagatla if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
7508da9db0cSSrinivas Kandagatla if (!wcd938x->comp2_enable)
7518da9db0cSSrinivas Kandagatla usleep_range(20000, 20100);
7528da9db0cSSrinivas Kandagatla else
7538da9db0cSSrinivas Kandagatla usleep_range(7000, 7100);
7548da9db0cSSrinivas Kandagatla
7558da9db0cSSrinivas Kandagatla if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
7568da9db0cSSrinivas Kandagatla hph_mode == CLS_H_ULP)
7578da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
7588da9db0cSSrinivas Kandagatla WCD938X_HPH_REFBUFF_LP_CTL,
7598da9db0cSSrinivas Kandagatla WCD938X_PREREF_FLIT_BYPASS_MASK, 0);
7608da9db0cSSrinivas Kandagatla clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
7618da9db0cSSrinivas Kandagatla }
7628da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
7638da9db0cSSrinivas Kandagatla WCD938X_AUTOCHOP_TIMER_EN, 1);
7648da9db0cSSrinivas Kandagatla if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
7658da9db0cSSrinivas Kandagatla hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
7668da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
7678da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_MASK,
7688da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_CLASS_AB);
7698da9db0cSSrinivas Kandagatla enable_irq(wcd938x->hphr_pdm_wd_int);
7708da9db0cSSrinivas Kandagatla break;
7718da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMD:
7728da9db0cSSrinivas Kandagatla disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
7738da9db0cSSrinivas Kandagatla /*
7748da9db0cSSrinivas Kandagatla * 7ms sleep is required if compander is enabled as per
7758da9db0cSSrinivas Kandagatla * HW requirement. If compander is disabled, then
7768da9db0cSSrinivas Kandagatla * 20ms delay is required.
7778da9db0cSSrinivas Kandagatla */
7788da9db0cSSrinivas Kandagatla if (!wcd938x->comp2_enable)
7798da9db0cSSrinivas Kandagatla usleep_range(20000, 20100);
7808da9db0cSSrinivas Kandagatla else
7818da9db0cSSrinivas Kandagatla usleep_range(7000, 7100);
7828da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_HPH,
7838da9db0cSSrinivas Kandagatla WCD938X_HPHR_EN_MASK, 0);
784bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
785bcee7ed0SSrinivas Kandagatla WCD_EVENT_PRE_HPHR_PA_OFF);
7868da9db0cSSrinivas Kandagatla set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
7878da9db0cSSrinivas Kandagatla break;
7888da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
7898da9db0cSSrinivas Kandagatla /*
7908da9db0cSSrinivas Kandagatla * 7ms sleep is required if compander is enabled as per
7918da9db0cSSrinivas Kandagatla * HW requirement. If compander is disabled, then
7928da9db0cSSrinivas Kandagatla * 20ms delay is required.
7938da9db0cSSrinivas Kandagatla */
7948da9db0cSSrinivas Kandagatla if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
7958da9db0cSSrinivas Kandagatla if (!wcd938x->comp2_enable)
7968da9db0cSSrinivas Kandagatla usleep_range(20000, 20100);
7978da9db0cSSrinivas Kandagatla else
7988da9db0cSSrinivas Kandagatla usleep_range(7000, 7100);
7998da9db0cSSrinivas Kandagatla clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
8008da9db0cSSrinivas Kandagatla }
801bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
802bcee7ed0SSrinivas Kandagatla WCD_EVENT_POST_HPHR_PA_OFF);
8038da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_HPH,
8048da9db0cSSrinivas Kandagatla WCD938X_HPHR_REF_EN_MASK, 0);
8058da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL1,
8068da9db0cSSrinivas Kandagatla WCD938X_PDM_WD_EN_MASK, 0);
8078da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
8088da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_HPHR, hph_mode);
8098da9db0cSSrinivas Kandagatla if (wcd938x->ldoh)
8108da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
8118da9db0cSSrinivas Kandagatla WCD938X_LDOH_EN_MASK, 0);
8128da9db0cSSrinivas Kandagatla break;
8138da9db0cSSrinivas Kandagatla }
8148da9db0cSSrinivas Kandagatla
8158da9db0cSSrinivas Kandagatla return 0;
8168da9db0cSSrinivas Kandagatla }
8178da9db0cSSrinivas Kandagatla
wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)8188da9db0cSSrinivas Kandagatla static int wcd938x_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
8198da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
8208da9db0cSSrinivas Kandagatla {
8218da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
8228da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
8238da9db0cSSrinivas Kandagatla int hph_mode = wcd938x->hph_mode;
8248da9db0cSSrinivas Kandagatla
8258da9db0cSSrinivas Kandagatla switch (event) {
8268da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
8278da9db0cSSrinivas Kandagatla if (wcd938x->ldoh)
8288da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
8298da9db0cSSrinivas Kandagatla WCD938X_LDOH_EN_MASK, 1);
8308da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_PRE_DAC,
8318da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_HPHL, hph_mode);
8328da9db0cSSrinivas Kandagatla wcd_clsh_set_hph_mode(wcd938x->clsh_info, CLS_H_HIFI);
8338da9db0cSSrinivas Kandagatla if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
8348da9db0cSSrinivas Kandagatla hph_mode == CLS_H_ULP) {
8358da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
8368da9db0cSSrinivas Kandagatla WCD938X_HPH_REFBUFF_LP_CTL,
8378da9db0cSSrinivas Kandagatla WCD938X_PREREF_FLIT_BYPASS_MASK, 1);
8388da9db0cSSrinivas Kandagatla }
8398da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_HPH,
8408da9db0cSSrinivas Kandagatla WCD938X_HPHL_REF_EN_MASK, 1);
8418da9db0cSSrinivas Kandagatla wcd_clsh_set_hph_mode(wcd938x->clsh_info, hph_mode);
8428da9db0cSSrinivas Kandagatla /* 100 usec delay as per HW requirement */
8438da9db0cSSrinivas Kandagatla usleep_range(100, 110);
8448da9db0cSSrinivas Kandagatla set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
8458da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
8468da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_PDM_WD_CTL0,
8478da9db0cSSrinivas Kandagatla WCD938X_PDM_WD_EN_MASK, 0x3);
8488da9db0cSSrinivas Kandagatla break;
8498da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
8508da9db0cSSrinivas Kandagatla /*
8518da9db0cSSrinivas Kandagatla * 7ms sleep is required if compander is enabled as per
8528da9db0cSSrinivas Kandagatla * HW requirement. If compander is disabled, then
8538da9db0cSSrinivas Kandagatla * 20ms delay is required.
8548da9db0cSSrinivas Kandagatla */
8558da9db0cSSrinivas Kandagatla if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
8568da9db0cSSrinivas Kandagatla if (!wcd938x->comp1_enable)
8578da9db0cSSrinivas Kandagatla usleep_range(20000, 20100);
8588da9db0cSSrinivas Kandagatla else
8598da9db0cSSrinivas Kandagatla usleep_range(7000, 7100);
8608da9db0cSSrinivas Kandagatla if (hph_mode == CLS_H_LP || hph_mode == CLS_H_LOHIFI ||
8618da9db0cSSrinivas Kandagatla hph_mode == CLS_H_ULP)
8628da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
8638da9db0cSSrinivas Kandagatla WCD938X_HPH_REFBUFF_LP_CTL,
8648da9db0cSSrinivas Kandagatla WCD938X_PREREF_FLIT_BYPASS_MASK, 0);
8658da9db0cSSrinivas Kandagatla clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
8668da9db0cSSrinivas Kandagatla }
8678da9db0cSSrinivas Kandagatla
8688da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_NEW_INT_HPH_TIMER1,
8698da9db0cSSrinivas Kandagatla WCD938X_AUTOCHOP_TIMER_EN, 1);
8708da9db0cSSrinivas Kandagatla if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
8718da9db0cSSrinivas Kandagatla hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
8728da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
8738da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_MASK,
8748da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_CLASS_AB);
8758da9db0cSSrinivas Kandagatla enable_irq(wcd938x->hphl_pdm_wd_int);
8768da9db0cSSrinivas Kandagatla break;
8778da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMD:
8788da9db0cSSrinivas Kandagatla disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
8798da9db0cSSrinivas Kandagatla /*
8808da9db0cSSrinivas Kandagatla * 7ms sleep is required if compander is enabled as per
8818da9db0cSSrinivas Kandagatla * HW requirement. If compander is disabled, then
8828da9db0cSSrinivas Kandagatla * 20ms delay is required.
8838da9db0cSSrinivas Kandagatla */
8848da9db0cSSrinivas Kandagatla if (!wcd938x->comp1_enable)
8858da9db0cSSrinivas Kandagatla usleep_range(20000, 20100);
8868da9db0cSSrinivas Kandagatla else
8878da9db0cSSrinivas Kandagatla usleep_range(7000, 7100);
8888da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_HPH,
8898da9db0cSSrinivas Kandagatla WCD938X_HPHL_EN_MASK, 0);
890bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc, WCD_EVENT_PRE_HPHL_PA_OFF);
8918da9db0cSSrinivas Kandagatla set_bit(HPH_PA_DELAY, &wcd938x->status_mask);
8928da9db0cSSrinivas Kandagatla break;
8938da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
8948da9db0cSSrinivas Kandagatla /*
8958da9db0cSSrinivas Kandagatla * 7ms sleep is required if compander is enabled as per
8968da9db0cSSrinivas Kandagatla * HW requirement. If compander is disabled, then
8978da9db0cSSrinivas Kandagatla * 20ms delay is required.
8988da9db0cSSrinivas Kandagatla */
8998da9db0cSSrinivas Kandagatla if (test_bit(HPH_PA_DELAY, &wcd938x->status_mask)) {
9008da9db0cSSrinivas Kandagatla if (!wcd938x->comp1_enable)
9018da9db0cSSrinivas Kandagatla usleep_range(21000, 21100);
9028da9db0cSSrinivas Kandagatla else
9038da9db0cSSrinivas Kandagatla usleep_range(7000, 7100);
9048da9db0cSSrinivas Kandagatla clear_bit(HPH_PA_DELAY, &wcd938x->status_mask);
9058da9db0cSSrinivas Kandagatla }
906bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
907bcee7ed0SSrinivas Kandagatla WCD_EVENT_POST_HPHL_PA_OFF);
9088da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_HPH,
9098da9db0cSSrinivas Kandagatla WCD938X_HPHL_REF_EN_MASK, 0);
9108da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
9118da9db0cSSrinivas Kandagatla WCD938X_PDM_WD_EN_MASK, 0);
9128da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
9138da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_HPHL, hph_mode);
9148da9db0cSSrinivas Kandagatla if (wcd938x->ldoh)
9158da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_LDOH_MODE,
9168da9db0cSSrinivas Kandagatla WCD938X_LDOH_EN_MASK, 0);
9178da9db0cSSrinivas Kandagatla break;
9188da9db0cSSrinivas Kandagatla }
9198da9db0cSSrinivas Kandagatla
9208da9db0cSSrinivas Kandagatla return 0;
9218da9db0cSSrinivas Kandagatla }
9228da9db0cSSrinivas Kandagatla
wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)9238da9db0cSSrinivas Kandagatla static int wcd938x_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
9248da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
9258da9db0cSSrinivas Kandagatla {
9268da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
9278da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
9288da9db0cSSrinivas Kandagatla int hph_mode = wcd938x->hph_mode;
9298da9db0cSSrinivas Kandagatla
9308da9db0cSSrinivas Kandagatla switch (event) {
9318da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
9328da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
9338da9db0cSSrinivas Kandagatla WCD938X_AUX_PDM_WD_EN_MASK, 1);
9348da9db0cSSrinivas Kandagatla break;
9358da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
9368da9db0cSSrinivas Kandagatla /* 1 msec delay as per HW requirement */
9378da9db0cSSrinivas Kandagatla usleep_range(1000, 1010);
9388da9db0cSSrinivas Kandagatla if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
9398da9db0cSSrinivas Kandagatla hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
9408da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
9418da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_MASK,
9428da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_CLASS_AB);
9438da9db0cSSrinivas Kandagatla enable_irq(wcd938x->aux_pdm_wd_int);
9448da9db0cSSrinivas Kandagatla break;
9458da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMD:
9468da9db0cSSrinivas Kandagatla disable_irq_nosync(wcd938x->aux_pdm_wd_int);
9478da9db0cSSrinivas Kandagatla break;
9488da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
9498da9db0cSSrinivas Kandagatla /* 1 msec delay as per HW requirement */
9508da9db0cSSrinivas Kandagatla usleep_range(1000, 1010);
9518da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
9528da9db0cSSrinivas Kandagatla WCD938X_AUX_PDM_WD_EN_MASK, 0);
9538da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info,
9548da9db0cSSrinivas Kandagatla WCD_CLSH_EVENT_POST_PA,
9558da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_AUX,
9568da9db0cSSrinivas Kandagatla hph_mode);
9578da9db0cSSrinivas Kandagatla
9588da9db0cSSrinivas Kandagatla wcd938x->flyback_cur_det_disable--;
9598da9db0cSSrinivas Kandagatla if (wcd938x->flyback_cur_det_disable == 0)
9608da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
9618da9db0cSSrinivas Kandagatla WCD938X_EN_CUR_DET_MASK, 1);
9628da9db0cSSrinivas Kandagatla break;
9638da9db0cSSrinivas Kandagatla }
9644d0b79ecSkernel test robot return 0;
9658da9db0cSSrinivas Kandagatla }
9668da9db0cSSrinivas Kandagatla
wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)9678da9db0cSSrinivas Kandagatla static int wcd938x_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
9688da9db0cSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
9698da9db0cSSrinivas Kandagatla {
9708da9db0cSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
9718da9db0cSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
9728da9db0cSSrinivas Kandagatla int hph_mode = wcd938x->hph_mode;
9738da9db0cSSrinivas Kandagatla
9748da9db0cSSrinivas Kandagatla switch (event) {
9758da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
9768da9db0cSSrinivas Kandagatla /*
9778da9db0cSSrinivas Kandagatla * Enable watchdog interrupt for HPHL or AUX
9788da9db0cSSrinivas Kandagatla * depending on mux value
9798da9db0cSSrinivas Kandagatla */
9808da9db0cSSrinivas Kandagatla wcd938x->ear_rx_path = snd_soc_component_read(component,
9818da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_CDC_EAR_PATH_CTL);
9828da9db0cSSrinivas Kandagatla if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
9838da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
9848da9db0cSSrinivas Kandagatla WCD938X_AUX_PDM_WD_EN_MASK, 1);
9858da9db0cSSrinivas Kandagatla else
9868da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
9878da9db0cSSrinivas Kandagatla WCD938X_DIGITAL_PDM_WD_CTL0,
9888da9db0cSSrinivas Kandagatla WCD938X_PDM_WD_EN_MASK, 0x3);
9898da9db0cSSrinivas Kandagatla if (!wcd938x->comp1_enable)
9908da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component,
9918da9db0cSSrinivas Kandagatla WCD938X_ANA_EAR_COMPANDER_CTL,
9928da9db0cSSrinivas Kandagatla WCD938X_GAIN_OVRD_REG_MASK, 1);
9938da9db0cSSrinivas Kandagatla
9948da9db0cSSrinivas Kandagatla break;
9958da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
9968da9db0cSSrinivas Kandagatla /* 6 msec delay as per HW requirement */
9978da9db0cSSrinivas Kandagatla usleep_range(6000, 6010);
9988da9db0cSSrinivas Kandagatla if (hph_mode == CLS_AB || hph_mode == CLS_AB_HIFI ||
9998da9db0cSSrinivas Kandagatla hph_mode == CLS_AB_LP || hph_mode == CLS_AB_LOHIFI)
10008da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_RX_SUPPLIES,
10018da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_MASK,
10028da9db0cSSrinivas Kandagatla WCD938X_REGULATOR_MODE_CLASS_AB);
10038da9db0cSSrinivas Kandagatla if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
10048da9db0cSSrinivas Kandagatla enable_irq(wcd938x->aux_pdm_wd_int);
10058da9db0cSSrinivas Kandagatla else
10068da9db0cSSrinivas Kandagatla enable_irq(wcd938x->hphl_pdm_wd_int);
10078da9db0cSSrinivas Kandagatla break;
10088da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMD:
10098da9db0cSSrinivas Kandagatla if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
10108da9db0cSSrinivas Kandagatla disable_irq_nosync(wcd938x->aux_pdm_wd_int);
10118da9db0cSSrinivas Kandagatla else
10128da9db0cSSrinivas Kandagatla disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
10138da9db0cSSrinivas Kandagatla break;
10148da9db0cSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
10158da9db0cSSrinivas Kandagatla if (!wcd938x->comp1_enable)
10168da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
10178da9db0cSSrinivas Kandagatla WCD938X_GAIN_OVRD_REG_MASK, 0);
10188da9db0cSSrinivas Kandagatla /* 7 msec delay as per HW requirement */
10198da9db0cSSrinivas Kandagatla usleep_range(7000, 7010);
10208da9db0cSSrinivas Kandagatla if (wcd938x->ear_rx_path & EAR_RX_PATH_AUX)
10218da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL2,
10228da9db0cSSrinivas Kandagatla WCD938X_AUX_PDM_WD_EN_MASK, 0);
10238da9db0cSSrinivas Kandagatla else
10248da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_PDM_WD_CTL0,
10258da9db0cSSrinivas Kandagatla WCD938X_PDM_WD_EN_MASK, 0);
10268da9db0cSSrinivas Kandagatla
10278da9db0cSSrinivas Kandagatla wcd_clsh_ctrl_set_state(wcd938x->clsh_info, WCD_CLSH_EVENT_POST_PA,
10288da9db0cSSrinivas Kandagatla WCD_CLSH_STATE_EAR, hph_mode);
10298da9db0cSSrinivas Kandagatla
10308da9db0cSSrinivas Kandagatla wcd938x->flyback_cur_det_disable--;
10318da9db0cSSrinivas Kandagatla if (wcd938x->flyback_cur_det_disable == 0)
10328da9db0cSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_FLYBACK_EN,
10338da9db0cSSrinivas Kandagatla WCD938X_EN_CUR_DET_MASK, 1);
10348da9db0cSSrinivas Kandagatla break;
10358da9db0cSSrinivas Kandagatla }
10368da9db0cSSrinivas Kandagatla
10378da9db0cSSrinivas Kandagatla return 0;
10388da9db0cSSrinivas Kandagatla }
10398da9db0cSSrinivas Kandagatla
wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1040d5add08fSSrinivas Kandagatla static int wcd938x_codec_enable_dmic(struct snd_soc_dapm_widget *w,
1041d5add08fSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
1042d5add08fSSrinivas Kandagatla int event)
1043d5add08fSSrinivas Kandagatla {
1044d5add08fSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1045d5add08fSSrinivas Kandagatla u16 dmic_clk_reg, dmic_clk_en_reg;
1046d5add08fSSrinivas Kandagatla u8 dmic_sel_mask, dmic_clk_mask;
1047d5add08fSSrinivas Kandagatla
1048d5add08fSSrinivas Kandagatla switch (w->shift) {
1049d5add08fSSrinivas Kandagatla case 0:
1050d5add08fSSrinivas Kandagatla case 1:
1051d5add08fSSrinivas Kandagatla dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
1052d5add08fSSrinivas Kandagatla dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC1_CTL;
1053d5add08fSSrinivas Kandagatla dmic_clk_mask = WCD938X_DMIC1_RATE_MASK;
1054d5add08fSSrinivas Kandagatla dmic_sel_mask = WCD938X_AMIC1_IN_SEL_MASK;
1055d5add08fSSrinivas Kandagatla break;
1056d5add08fSSrinivas Kandagatla case 2:
1057d5add08fSSrinivas Kandagatla case 3:
1058d5add08fSSrinivas Kandagatla dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_1_2;
1059d5add08fSSrinivas Kandagatla dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC2_CTL;
1060d5add08fSSrinivas Kandagatla dmic_clk_mask = WCD938X_DMIC2_RATE_MASK;
1061d5add08fSSrinivas Kandagatla dmic_sel_mask = WCD938X_AMIC3_IN_SEL_MASK;
1062d5add08fSSrinivas Kandagatla break;
1063d5add08fSSrinivas Kandagatla case 4:
1064d5add08fSSrinivas Kandagatla case 5:
1065d5add08fSSrinivas Kandagatla dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
1066d5add08fSSrinivas Kandagatla dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC3_CTL;
1067d5add08fSSrinivas Kandagatla dmic_clk_mask = WCD938X_DMIC3_RATE_MASK;
1068d5add08fSSrinivas Kandagatla dmic_sel_mask = WCD938X_AMIC4_IN_SEL_MASK;
1069d5add08fSSrinivas Kandagatla break;
1070d5add08fSSrinivas Kandagatla case 6:
1071d5add08fSSrinivas Kandagatla case 7:
1072d5add08fSSrinivas Kandagatla dmic_clk_reg = WCD938X_DIGITAL_CDC_DMIC_RATE_3_4;
1073d5add08fSSrinivas Kandagatla dmic_clk_en_reg = WCD938X_DIGITAL_CDC_DMIC4_CTL;
1074d5add08fSSrinivas Kandagatla dmic_clk_mask = WCD938X_DMIC4_RATE_MASK;
1075d5add08fSSrinivas Kandagatla dmic_sel_mask = WCD938X_AMIC5_IN_SEL_MASK;
1076d5add08fSSrinivas Kandagatla break;
1077d5add08fSSrinivas Kandagatla default:
1078d5add08fSSrinivas Kandagatla dev_err(component->dev, "%s: Invalid DMIC Selection\n",
1079d5add08fSSrinivas Kandagatla __func__);
1080d5add08fSSrinivas Kandagatla return -EINVAL;
1081d5add08fSSrinivas Kandagatla }
1082d5add08fSSrinivas Kandagatla
1083d5add08fSSrinivas Kandagatla switch (event) {
1084d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
1085d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1086d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_AMIC_CTL,
1087d5add08fSSrinivas Kandagatla dmic_sel_mask,
1088d5add08fSSrinivas Kandagatla WCD938X_AMIC1_IN_SEL_DMIC);
1089d5add08fSSrinivas Kandagatla /* 250us sleep as per HW requirement */
1090d5add08fSSrinivas Kandagatla usleep_range(250, 260);
1091d5add08fSSrinivas Kandagatla /* Setting DMIC clock rate to 2.4MHz */
1092d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, dmic_clk_reg,
1093d5add08fSSrinivas Kandagatla dmic_clk_mask,
1094d5add08fSSrinivas Kandagatla WCD938X_DMIC4_RATE_2P4MHZ);
1095d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, dmic_clk_en_reg,
1096d5add08fSSrinivas Kandagatla WCD938X_DMIC_CLK_EN_MASK, 1);
1097d5add08fSSrinivas Kandagatla /* enable clock scaling */
1098d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_DMIC_CTL,
1099d5add08fSSrinivas Kandagatla WCD938X_DMIC_CLK_SCALING_EN_MASK, 0x3);
1100d5add08fSSrinivas Kandagatla break;
1101d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
1102d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1103d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_AMIC_CTL,
1104d5add08fSSrinivas Kandagatla dmic_sel_mask, WCD938X_AMIC1_IN_SEL_AMIC);
1105d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, dmic_clk_en_reg,
1106d5add08fSSrinivas Kandagatla WCD938X_DMIC_CLK_EN_MASK, 0);
1107d5add08fSSrinivas Kandagatla break;
1108d5add08fSSrinivas Kandagatla }
1109d5add08fSSrinivas Kandagatla return 0;
1110d5add08fSSrinivas Kandagatla }
1111d5add08fSSrinivas Kandagatla
wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1112d5add08fSSrinivas Kandagatla static int wcd938x_tx_swr_ctrl(struct snd_soc_dapm_widget *w,
1113d5add08fSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
1114d5add08fSSrinivas Kandagatla {
1115d5add08fSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1116d5add08fSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1117d5add08fSSrinivas Kandagatla int bank;
1118d5add08fSSrinivas Kandagatla int rate;
1119d5add08fSSrinivas Kandagatla
1120d5add08fSSrinivas Kandagatla bank = (wcd938x_swr_get_current_bank(wcd938x->sdw_priv[AIF1_CAP]->sdev)) ? 0 : 1;
1121d5add08fSSrinivas Kandagatla bank = bank ? 0 : 1;
1122d5add08fSSrinivas Kandagatla
1123d5add08fSSrinivas Kandagatla switch (event) {
1124d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
1125d5add08fSSrinivas Kandagatla if (strnstr(w->name, "ADC", sizeof("ADC"))) {
1126d5add08fSSrinivas Kandagatla int i = 0, mode = 0;
1127d5add08fSSrinivas Kandagatla
1128d5add08fSSrinivas Kandagatla if (test_bit(WCD_ADC1, &wcd938x->status_mask))
1129d5add08fSSrinivas Kandagatla mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC1]];
1130d5add08fSSrinivas Kandagatla if (test_bit(WCD_ADC2, &wcd938x->status_mask))
1131d5add08fSSrinivas Kandagatla mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC2]];
1132d5add08fSSrinivas Kandagatla if (test_bit(WCD_ADC3, &wcd938x->status_mask))
1133d5add08fSSrinivas Kandagatla mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC3]];
1134d5add08fSSrinivas Kandagatla if (test_bit(WCD_ADC4, &wcd938x->status_mask))
1135d5add08fSSrinivas Kandagatla mode |= tx_mode_bit[wcd938x->tx_mode[WCD_ADC4]];
1136d5add08fSSrinivas Kandagatla
1137d5add08fSSrinivas Kandagatla if (mode != 0) {
1138d5add08fSSrinivas Kandagatla for (i = 0; i < ADC_MODE_ULP2; i++) {
1139d5add08fSSrinivas Kandagatla if (mode & (1 << i)) {
1140d5add08fSSrinivas Kandagatla i++;
1141d5add08fSSrinivas Kandagatla break;
1142d5add08fSSrinivas Kandagatla }
1143d5add08fSSrinivas Kandagatla }
1144d5add08fSSrinivas Kandagatla }
1145d5add08fSSrinivas Kandagatla rate = wcd938x_get_clk_rate(i);
1146d5add08fSSrinivas Kandagatla wcd938x_set_swr_clk_rate(component, rate, bank);
1147d5add08fSSrinivas Kandagatla /* Copy clk settings to active bank */
1148d5add08fSSrinivas Kandagatla wcd938x_set_swr_clk_rate(component, rate, !bank);
1149d245fff1SSrinivas Kandagatla }
1150d5add08fSSrinivas Kandagatla break;
1151d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
1152d5add08fSSrinivas Kandagatla if (strnstr(w->name, "ADC", sizeof("ADC"))) {
1153d5add08fSSrinivas Kandagatla rate = wcd938x_get_clk_rate(ADC_MODE_INVALID);
1154d5add08fSSrinivas Kandagatla wcd938x_set_swr_clk_rate(component, rate, !bank);
1155d5add08fSSrinivas Kandagatla wcd938x_set_swr_clk_rate(component, rate, bank);
1156d5add08fSSrinivas Kandagatla }
1157d5add08fSSrinivas Kandagatla break;
1158d5add08fSSrinivas Kandagatla }
1159d5add08fSSrinivas Kandagatla
1160d5add08fSSrinivas Kandagatla return 0;
1161d5add08fSSrinivas Kandagatla }
1162d5add08fSSrinivas Kandagatla
wcd938x_get_adc_mode(int val)1163d5add08fSSrinivas Kandagatla static int wcd938x_get_adc_mode(int val)
1164d5add08fSSrinivas Kandagatla {
1165d5add08fSSrinivas Kandagatla int ret = 0;
1166d5add08fSSrinivas Kandagatla
1167d5add08fSSrinivas Kandagatla switch (val) {
1168d5add08fSSrinivas Kandagatla case ADC_MODE_INVALID:
1169d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_NORMAL;
1170d5add08fSSrinivas Kandagatla break;
1171d5add08fSSrinivas Kandagatla case ADC_MODE_HIFI:
1172d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_HIFI;
1173d5add08fSSrinivas Kandagatla break;
1174d5add08fSSrinivas Kandagatla case ADC_MODE_LO_HIF:
1175d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_LO_HIF;
1176d5add08fSSrinivas Kandagatla break;
1177d5add08fSSrinivas Kandagatla case ADC_MODE_NORMAL:
1178d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_NORMAL;
1179d5add08fSSrinivas Kandagatla break;
1180d5add08fSSrinivas Kandagatla case ADC_MODE_LP:
1181d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_LP;
1182d5add08fSSrinivas Kandagatla break;
1183d5add08fSSrinivas Kandagatla case ADC_MODE_ULP1:
1184d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_ULP1;
1185d5add08fSSrinivas Kandagatla break;
1186d5add08fSSrinivas Kandagatla case ADC_MODE_ULP2:
1187d5add08fSSrinivas Kandagatla ret = ADC_MODE_VAL_ULP2;
1188d5add08fSSrinivas Kandagatla break;
1189d5add08fSSrinivas Kandagatla default:
1190d5add08fSSrinivas Kandagatla ret = -EINVAL;
1191d5add08fSSrinivas Kandagatla break;
1192d5add08fSSrinivas Kandagatla }
1193d5add08fSSrinivas Kandagatla return ret;
1194d5add08fSSrinivas Kandagatla }
1195d5add08fSSrinivas Kandagatla
wcd938x_codec_enable_adc(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1196d5add08fSSrinivas Kandagatla static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
1197d5add08fSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
1198d5add08fSSrinivas Kandagatla {
1199d5add08fSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1200d5add08fSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1201d5add08fSSrinivas Kandagatla
1202d5add08fSSrinivas Kandagatla switch (event) {
1203d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
1204d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1205d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
1206d5add08fSSrinivas Kandagatla WCD938X_ANA_TX_CLK_EN_MASK, 1);
1207d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1208d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
1209d5add08fSSrinivas Kandagatla WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 1);
1210d5add08fSSrinivas Kandagatla set_bit(w->shift, &wcd938x->status_mask);
1211d5add08fSSrinivas Kandagatla break;
1212d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
1213d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
1214d5add08fSSrinivas Kandagatla WCD938X_ANA_TX_CLK_EN_MASK, 0);
1215d5add08fSSrinivas Kandagatla clear_bit(w->shift, &wcd938x->status_mask);
1216d5add08fSSrinivas Kandagatla break;
1217d5add08fSSrinivas Kandagatla }
1218d5add08fSSrinivas Kandagatla
1219d5add08fSSrinivas Kandagatla return 0;
1220d5add08fSSrinivas Kandagatla }
1221d5add08fSSrinivas Kandagatla
wcd938x_tx_channel_config(struct snd_soc_component * component,int channel,int mode)1222d5add08fSSrinivas Kandagatla static void wcd938x_tx_channel_config(struct snd_soc_component *component,
1223d5add08fSSrinivas Kandagatla int channel, int mode)
1224d5add08fSSrinivas Kandagatla {
1225d5add08fSSrinivas Kandagatla int reg, mask;
1226d5add08fSSrinivas Kandagatla
1227d5add08fSSrinivas Kandagatla switch (channel) {
1228d5add08fSSrinivas Kandagatla case 0:
1229d5add08fSSrinivas Kandagatla reg = WCD938X_ANA_TX_CH2;
1230d5add08fSSrinivas Kandagatla mask = WCD938X_HPF1_INIT_MASK;
1231d5add08fSSrinivas Kandagatla break;
1232d5add08fSSrinivas Kandagatla case 1:
1233d5add08fSSrinivas Kandagatla reg = WCD938X_ANA_TX_CH2;
1234d5add08fSSrinivas Kandagatla mask = WCD938X_HPF2_INIT_MASK;
1235d5add08fSSrinivas Kandagatla break;
1236d5add08fSSrinivas Kandagatla case 2:
1237d5add08fSSrinivas Kandagatla reg = WCD938X_ANA_TX_CH4;
1238d5add08fSSrinivas Kandagatla mask = WCD938X_HPF3_INIT_MASK;
1239d5add08fSSrinivas Kandagatla break;
1240d5add08fSSrinivas Kandagatla case 3:
1241d5add08fSSrinivas Kandagatla reg = WCD938X_ANA_TX_CH4;
1242d5add08fSSrinivas Kandagatla mask = WCD938X_HPF4_INIT_MASK;
1243d5add08fSSrinivas Kandagatla break;
1244d245fff1SSrinivas Kandagatla default:
1245d245fff1SSrinivas Kandagatla return;
1246d5add08fSSrinivas Kandagatla }
1247d5add08fSSrinivas Kandagatla
1248d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, reg, mask, mode);
1249d5add08fSSrinivas Kandagatla }
1250d5add08fSSrinivas Kandagatla
wcd938x_adc_enable_req(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1251d5add08fSSrinivas Kandagatla static int wcd938x_adc_enable_req(struct snd_soc_dapm_widget *w,
1252d5add08fSSrinivas Kandagatla struct snd_kcontrol *kcontrol, int event)
1253d5add08fSSrinivas Kandagatla {
1254d5add08fSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1255d5add08fSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1256d5add08fSSrinivas Kandagatla int mode;
1257d5add08fSSrinivas Kandagatla
1258d5add08fSSrinivas Kandagatla switch (event) {
1259d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
1260d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1261d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_REQ_CTL,
1262d5add08fSSrinivas Kandagatla WCD938X_FS_RATE_4P8_MASK, 1);
1263d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1264d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_REQ_CTL,
1265d5add08fSSrinivas Kandagatla WCD938X_NO_NOTCH_MASK, 0);
1266d5add08fSSrinivas Kandagatla wcd938x_tx_channel_config(component, w->shift, 1);
1267d5add08fSSrinivas Kandagatla mode = wcd938x_get_adc_mode(wcd938x->tx_mode[w->shift]);
1268d5add08fSSrinivas Kandagatla if (mode < 0) {
1269d5add08fSSrinivas Kandagatla dev_info(component->dev, "Invalid ADC mode\n");
1270d5add08fSSrinivas Kandagatla return -EINVAL;
1271d5add08fSSrinivas Kandagatla }
1272d5add08fSSrinivas Kandagatla switch (w->shift) {
1273d5add08fSSrinivas Kandagatla case 0:
1274d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1275d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
1276d5add08fSSrinivas Kandagatla WCD938X_TXD0_MODE_MASK, mode);
1277d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1278d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1279d5add08fSSrinivas Kandagatla WCD938X_TXD0_CLK_EN_MASK, 1);
1280d5add08fSSrinivas Kandagatla break;
1281d5add08fSSrinivas Kandagatla case 1:
1282d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1283d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
1284d5add08fSSrinivas Kandagatla WCD938X_TXD1_MODE_MASK, mode);
1285d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1286d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1287d5add08fSSrinivas Kandagatla WCD938X_TXD1_CLK_EN_MASK, 1);
1288d5add08fSSrinivas Kandagatla break;
1289d5add08fSSrinivas Kandagatla case 2:
1290d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1291d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
1292d5add08fSSrinivas Kandagatla WCD938X_TXD2_MODE_MASK, mode);
1293d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1294d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1295d5add08fSSrinivas Kandagatla WCD938X_TXD2_CLK_EN_MASK, 1);
1296d5add08fSSrinivas Kandagatla break;
1297d5add08fSSrinivas Kandagatla case 3:
1298d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1299d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
1300d5add08fSSrinivas Kandagatla WCD938X_TXD3_MODE_MASK, mode);
1301d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1302d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1303d5add08fSSrinivas Kandagatla WCD938X_TXD3_CLK_EN_MASK, 1);
1304d5add08fSSrinivas Kandagatla break;
1305d5add08fSSrinivas Kandagatla default:
1306d5add08fSSrinivas Kandagatla break;
1307d5add08fSSrinivas Kandagatla }
1308d5add08fSSrinivas Kandagatla
1309d5add08fSSrinivas Kandagatla wcd938x_tx_channel_config(component, w->shift, 0);
1310d5add08fSSrinivas Kandagatla break;
1311d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
1312d5add08fSSrinivas Kandagatla switch (w->shift) {
1313d5add08fSSrinivas Kandagatla case 0:
1314d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1315d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
1316d5add08fSSrinivas Kandagatla WCD938X_TXD0_MODE_MASK, 0);
1317d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1318d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1319d5add08fSSrinivas Kandagatla WCD938X_TXD0_CLK_EN_MASK, 0);
1320d5add08fSSrinivas Kandagatla break;
1321d5add08fSSrinivas Kandagatla case 1:
1322d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1323d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1,
1324d5add08fSSrinivas Kandagatla WCD938X_TXD1_MODE_MASK, 0);
1325d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1326d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1327d5add08fSSrinivas Kandagatla WCD938X_TXD1_CLK_EN_MASK, 0);
1328d5add08fSSrinivas Kandagatla break;
1329d5add08fSSrinivas Kandagatla case 2:
1330d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1331d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
1332d5add08fSSrinivas Kandagatla WCD938X_TXD2_MODE_MASK, 0);
1333d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1334d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1335d5add08fSSrinivas Kandagatla WCD938X_TXD2_CLK_EN_MASK, 0);
1336d5add08fSSrinivas Kandagatla break;
1337d5add08fSSrinivas Kandagatla case 3:
1338d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1339d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3,
1340d5add08fSSrinivas Kandagatla WCD938X_TXD3_MODE_MASK, 0);
1341d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1342d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1343d5add08fSSrinivas Kandagatla WCD938X_TXD3_CLK_EN_MASK, 0);
1344d5add08fSSrinivas Kandagatla break;
1345d5add08fSSrinivas Kandagatla default:
1346d5add08fSSrinivas Kandagatla break;
1347d5add08fSSrinivas Kandagatla }
1348d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1349d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
1350d5add08fSSrinivas Kandagatla WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 0);
1351d5add08fSSrinivas Kandagatla break;
1352d5add08fSSrinivas Kandagatla }
1353d5add08fSSrinivas Kandagatla
1354d5add08fSSrinivas Kandagatla return 0;
1355d5add08fSSrinivas Kandagatla }
1356d5add08fSSrinivas Kandagatla
wcd938x_micbias_control(struct snd_soc_component * component,int micb_num,int req,bool is_dapm)1357d5add08fSSrinivas Kandagatla static int wcd938x_micbias_control(struct snd_soc_component *component,
1358d5add08fSSrinivas Kandagatla int micb_num, int req, bool is_dapm)
1359d5add08fSSrinivas Kandagatla {
1360d5add08fSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1361d5add08fSSrinivas Kandagatla int micb_index = micb_num - 1;
1362d5add08fSSrinivas Kandagatla u16 micb_reg;
1363d5add08fSSrinivas Kandagatla
1364d5add08fSSrinivas Kandagatla switch (micb_num) {
1365d5add08fSSrinivas Kandagatla case MIC_BIAS_1:
1366d5add08fSSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB1;
1367d5add08fSSrinivas Kandagatla break;
1368d5add08fSSrinivas Kandagatla case MIC_BIAS_2:
1369d5add08fSSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB2;
1370d5add08fSSrinivas Kandagatla break;
1371d5add08fSSrinivas Kandagatla case MIC_BIAS_3:
1372d5add08fSSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB3;
1373d5add08fSSrinivas Kandagatla break;
1374d5add08fSSrinivas Kandagatla case MIC_BIAS_4:
1375d5add08fSSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB4;
1376d5add08fSSrinivas Kandagatla break;
1377d5add08fSSrinivas Kandagatla default:
1378d5add08fSSrinivas Kandagatla dev_err(component->dev, "%s: Invalid micbias number: %d\n",
1379d5add08fSSrinivas Kandagatla __func__, micb_num);
1380d5add08fSSrinivas Kandagatla return -EINVAL;
1381d5add08fSSrinivas Kandagatla }
1382d5add08fSSrinivas Kandagatla
1383d5add08fSSrinivas Kandagatla switch (req) {
1384d5add08fSSrinivas Kandagatla case MICB_PULLUP_ENABLE:
1385d5add08fSSrinivas Kandagatla wcd938x->pullup_ref[micb_index]++;
1386d5add08fSSrinivas Kandagatla if ((wcd938x->pullup_ref[micb_index] == 1) &&
1387d5add08fSSrinivas Kandagatla (wcd938x->micb_ref[micb_index] == 0))
1388d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
1389d5add08fSSrinivas Kandagatla WCD938X_MICB_EN_MASK,
1390d5add08fSSrinivas Kandagatla WCD938X_MICB_PULL_UP);
1391d5add08fSSrinivas Kandagatla break;
1392d5add08fSSrinivas Kandagatla case MICB_PULLUP_DISABLE:
1393d5add08fSSrinivas Kandagatla if (wcd938x->pullup_ref[micb_index] > 0)
1394d5add08fSSrinivas Kandagatla wcd938x->pullup_ref[micb_index]--;
1395d5add08fSSrinivas Kandagatla
1396d5add08fSSrinivas Kandagatla if ((wcd938x->pullup_ref[micb_index] == 0) &&
1397d5add08fSSrinivas Kandagatla (wcd938x->micb_ref[micb_index] == 0))
1398d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
1399d5add08fSSrinivas Kandagatla WCD938X_MICB_EN_MASK, 0);
1400d5add08fSSrinivas Kandagatla break;
1401d5add08fSSrinivas Kandagatla case MICB_ENABLE:
1402d5add08fSSrinivas Kandagatla wcd938x->micb_ref[micb_index]++;
1403d5add08fSSrinivas Kandagatla if (wcd938x->micb_ref[micb_index] == 1) {
1404d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1405d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_DIG_CLK_CTL,
1406d5add08fSSrinivas Kandagatla WCD938X_TX_CLK_EN_MASK, 0xF);
1407d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1408d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_CLK_CTL,
1409d5add08fSSrinivas Kandagatla WCD938X_ANA_TX_DIV2_CLK_EN_MASK, 1);
1410d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component,
1411d5add08fSSrinivas Kandagatla WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL,
1412d5add08fSSrinivas Kandagatla WCD938X_TX_SC_CLK_EN_MASK, 1);
1413d5add08fSSrinivas Kandagatla
1414d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
1415d5add08fSSrinivas Kandagatla WCD938X_MICB_EN_MASK,
1416d5add08fSSrinivas Kandagatla WCD938X_MICB_ENABLE);
1417bcee7ed0SSrinivas Kandagatla if (micb_num == MIC_BIAS_2)
1418bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
1419bcee7ed0SSrinivas Kandagatla WCD_EVENT_POST_MICBIAS_2_ON);
1420d5add08fSSrinivas Kandagatla }
1421bcee7ed0SSrinivas Kandagatla if (micb_num == MIC_BIAS_2 && is_dapm)
1422bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
1423bcee7ed0SSrinivas Kandagatla WCD_EVENT_POST_DAPM_MICBIAS_2_ON);
1424bcee7ed0SSrinivas Kandagatla
1425d5add08fSSrinivas Kandagatla
1426d5add08fSSrinivas Kandagatla break;
1427d5add08fSSrinivas Kandagatla case MICB_DISABLE:
1428d5add08fSSrinivas Kandagatla if (wcd938x->micb_ref[micb_index] > 0)
1429d5add08fSSrinivas Kandagatla wcd938x->micb_ref[micb_index]--;
1430d5add08fSSrinivas Kandagatla
1431d5add08fSSrinivas Kandagatla if ((wcd938x->micb_ref[micb_index] == 0) &&
1432d5add08fSSrinivas Kandagatla (wcd938x->pullup_ref[micb_index] > 0))
1433d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
1434d5add08fSSrinivas Kandagatla WCD938X_MICB_EN_MASK,
1435d5add08fSSrinivas Kandagatla WCD938X_MICB_PULL_UP);
1436d5add08fSSrinivas Kandagatla else if ((wcd938x->micb_ref[micb_index] == 0) &&
1437d5add08fSSrinivas Kandagatla (wcd938x->pullup_ref[micb_index] == 0)) {
1438bcee7ed0SSrinivas Kandagatla if (micb_num == MIC_BIAS_2)
1439bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
1440bcee7ed0SSrinivas Kandagatla WCD_EVENT_PRE_MICBIAS_2_OFF);
1441d5add08fSSrinivas Kandagatla
1442d5add08fSSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
1443d5add08fSSrinivas Kandagatla WCD938X_MICB_EN_MASK, 0);
1444bcee7ed0SSrinivas Kandagatla if (micb_num == MIC_BIAS_2)
1445bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
1446bcee7ed0SSrinivas Kandagatla WCD_EVENT_POST_MICBIAS_2_OFF);
1447d5add08fSSrinivas Kandagatla }
1448bcee7ed0SSrinivas Kandagatla if (is_dapm && micb_num == MIC_BIAS_2)
1449bcee7ed0SSrinivas Kandagatla wcd_mbhc_event_notify(wcd938x->wcd_mbhc,
1450bcee7ed0SSrinivas Kandagatla WCD_EVENT_POST_DAPM_MICBIAS_2_OFF);
1451d5add08fSSrinivas Kandagatla break;
1452d5add08fSSrinivas Kandagatla }
1453d5add08fSSrinivas Kandagatla
1454d5add08fSSrinivas Kandagatla return 0;
1455d5add08fSSrinivas Kandagatla }
1456d5add08fSSrinivas Kandagatla
wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1457d5add08fSSrinivas Kandagatla static int wcd938x_codec_enable_micbias(struct snd_soc_dapm_widget *w,
1458d5add08fSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
1459d5add08fSSrinivas Kandagatla int event)
1460d5add08fSSrinivas Kandagatla {
1461d5add08fSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1462d5add08fSSrinivas Kandagatla int micb_num = w->shift;
1463d5add08fSSrinivas Kandagatla
1464d5add08fSSrinivas Kandagatla switch (event) {
1465d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
1466d5add08fSSrinivas Kandagatla wcd938x_micbias_control(component, micb_num, MICB_ENABLE, true);
1467d5add08fSSrinivas Kandagatla break;
1468d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
1469d5add08fSSrinivas Kandagatla /* 1 msec delay as per HW requirement */
1470d5add08fSSrinivas Kandagatla usleep_range(1000, 1100);
1471d5add08fSSrinivas Kandagatla break;
1472d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
1473d5add08fSSrinivas Kandagatla wcd938x_micbias_control(component, micb_num, MICB_DISABLE, true);
1474d5add08fSSrinivas Kandagatla break;
1475d5add08fSSrinivas Kandagatla }
1476d5add08fSSrinivas Kandagatla
1477d5add08fSSrinivas Kandagatla return 0;
1478d5add08fSSrinivas Kandagatla }
1479d5add08fSSrinivas Kandagatla
wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)1480d5add08fSSrinivas Kandagatla static int wcd938x_codec_enable_micbias_pullup(struct snd_soc_dapm_widget *w,
1481d5add08fSSrinivas Kandagatla struct snd_kcontrol *kcontrol,
1482d5add08fSSrinivas Kandagatla int event)
1483d5add08fSSrinivas Kandagatla {
1484d5add08fSSrinivas Kandagatla struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1485d5add08fSSrinivas Kandagatla int micb_num = w->shift;
1486d5add08fSSrinivas Kandagatla
1487d5add08fSSrinivas Kandagatla switch (event) {
1488d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_PRE_PMU:
1489d5add08fSSrinivas Kandagatla wcd938x_micbias_control(component, micb_num,
1490d5add08fSSrinivas Kandagatla MICB_PULLUP_ENABLE, true);
1491d5add08fSSrinivas Kandagatla break;
1492d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMU:
1493d5add08fSSrinivas Kandagatla /* 1 msec delay as per HW requirement */
1494d5add08fSSrinivas Kandagatla usleep_range(1000, 1100);
1495d5add08fSSrinivas Kandagatla break;
1496d5add08fSSrinivas Kandagatla case SND_SOC_DAPM_POST_PMD:
1497d5add08fSSrinivas Kandagatla wcd938x_micbias_control(component, micb_num,
1498d5add08fSSrinivas Kandagatla MICB_PULLUP_DISABLE, true);
1499d5add08fSSrinivas Kandagatla break;
1500d5add08fSSrinivas Kandagatla }
1501d5add08fSSrinivas Kandagatla
1502d5add08fSSrinivas Kandagatla return 0;
1503d5add08fSSrinivas Kandagatla }
1504d5add08fSSrinivas Kandagatla
wcd938x_tx_mode_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1505e8ba1e05SSrinivas Kandagatla static int wcd938x_tx_mode_get(struct snd_kcontrol *kcontrol,
1506e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1507e8ba1e05SSrinivas Kandagatla {
1508e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1509e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1510e8ba1e05SSrinivas Kandagatla struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1511e8ba1e05SSrinivas Kandagatla int path = e->shift_l;
1512e8ba1e05SSrinivas Kandagatla
1513cc587b7cSSrinivas Kandagatla ucontrol->value.enumerated.item[0] = wcd938x->tx_mode[path];
1514e8ba1e05SSrinivas Kandagatla
1515e8ba1e05SSrinivas Kandagatla return 0;
1516e8ba1e05SSrinivas Kandagatla }
1517e8ba1e05SSrinivas Kandagatla
wcd938x_tx_mode_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1518e8ba1e05SSrinivas Kandagatla static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol,
1519e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1520e8ba1e05SSrinivas Kandagatla {
1521e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1522e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1523e8ba1e05SSrinivas Kandagatla struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1524e8ba1e05SSrinivas Kandagatla int path = e->shift_l;
1525e8ba1e05SSrinivas Kandagatla
152610e7ff00SMark Brown if (wcd938x->tx_mode[path] == ucontrol->value.enumerated.item[0])
152710e7ff00SMark Brown return 0;
152810e7ff00SMark Brown
1529e8ba1e05SSrinivas Kandagatla wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0];
1530e8ba1e05SSrinivas Kandagatla
1531e8ba1e05SSrinivas Kandagatla return 1;
1532e8ba1e05SSrinivas Kandagatla }
1533e8ba1e05SSrinivas Kandagatla
wcd938x_rx_hph_mode_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1534e8ba1e05SSrinivas Kandagatla static int wcd938x_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
1535e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1536e8ba1e05SSrinivas Kandagatla {
1537e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1538e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1539e8ba1e05SSrinivas Kandagatla
1540cc587b7cSSrinivas Kandagatla ucontrol->value.enumerated.item[0] = wcd938x->hph_mode;
1541e8ba1e05SSrinivas Kandagatla
1542e8ba1e05SSrinivas Kandagatla return 0;
1543e8ba1e05SSrinivas Kandagatla }
1544e8ba1e05SSrinivas Kandagatla
wcd938x_rx_hph_mode_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1545e8ba1e05SSrinivas Kandagatla static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
1546e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1547e8ba1e05SSrinivas Kandagatla {
1548e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1549e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1550e8ba1e05SSrinivas Kandagatla
155110e7ff00SMark Brown if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0])
155210e7ff00SMark Brown return 0;
155310e7ff00SMark Brown
1554e8ba1e05SSrinivas Kandagatla wcd938x->hph_mode = ucontrol->value.enumerated.item[0];
1555e8ba1e05SSrinivas Kandagatla
1556e8ba1e05SSrinivas Kandagatla return 1;
1557e8ba1e05SSrinivas Kandagatla }
1558e8ba1e05SSrinivas Kandagatla
wcd938x_ear_pa_put_gain(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1559e8ba1e05SSrinivas Kandagatla static int wcd938x_ear_pa_put_gain(struct snd_kcontrol *kcontrol,
1560e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1561e8ba1e05SSrinivas Kandagatla {
1562e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1563e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1564e8ba1e05SSrinivas Kandagatla
1565e8ba1e05SSrinivas Kandagatla if (wcd938x->comp1_enable) {
1566e8ba1e05SSrinivas Kandagatla dev_err(component->dev, "Can not set EAR PA Gain, compander1 is enabled\n");
1567e8ba1e05SSrinivas Kandagatla return -EINVAL;
1568e8ba1e05SSrinivas Kandagatla }
1569e8ba1e05SSrinivas Kandagatla
1570e8ba1e05SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_EAR_COMPANDER_CTL,
1571e8ba1e05SSrinivas Kandagatla WCD938X_EAR_GAIN_MASK,
1572e8ba1e05SSrinivas Kandagatla ucontrol->value.integer.value[0]);
1573e8ba1e05SSrinivas Kandagatla
1574bd2347fdSSrinivas Kandagatla return 1;
1575e8ba1e05SSrinivas Kandagatla }
1576e8ba1e05SSrinivas Kandagatla
wcd938x_get_compander(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1577e8ba1e05SSrinivas Kandagatla static int wcd938x_get_compander(struct snd_kcontrol *kcontrol,
1578e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1579e8ba1e05SSrinivas Kandagatla {
1580e8ba1e05SSrinivas Kandagatla
1581e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1582e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1583e8ba1e05SSrinivas Kandagatla struct soc_mixer_control *mc;
1584e8ba1e05SSrinivas Kandagatla bool hphr;
1585e8ba1e05SSrinivas Kandagatla
1586e8ba1e05SSrinivas Kandagatla mc = (struct soc_mixer_control *)(kcontrol->private_value);
1587e8ba1e05SSrinivas Kandagatla hphr = mc->shift;
1588e8ba1e05SSrinivas Kandagatla
1589e8ba1e05SSrinivas Kandagatla if (hphr)
1590e8ba1e05SSrinivas Kandagatla ucontrol->value.integer.value[0] = wcd938x->comp2_enable;
1591e8ba1e05SSrinivas Kandagatla else
1592e8ba1e05SSrinivas Kandagatla ucontrol->value.integer.value[0] = wcd938x->comp1_enable;
1593e8ba1e05SSrinivas Kandagatla
1594e8ba1e05SSrinivas Kandagatla return 0;
1595e8ba1e05SSrinivas Kandagatla }
1596e8ba1e05SSrinivas Kandagatla
wcd938x_set_compander(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1597e8ba1e05SSrinivas Kandagatla static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
1598e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1599e8ba1e05SSrinivas Kandagatla {
1600e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1601e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1602e8ba1e05SSrinivas Kandagatla struct wcd938x_sdw_priv *wcd;
1603e8ba1e05SSrinivas Kandagatla int value = ucontrol->value.integer.value[0];
1604c5c1546aSSrinivas Kandagatla int portidx;
1605e8ba1e05SSrinivas Kandagatla struct soc_mixer_control *mc;
1606e8ba1e05SSrinivas Kandagatla bool hphr;
1607e8ba1e05SSrinivas Kandagatla
1608e8ba1e05SSrinivas Kandagatla mc = (struct soc_mixer_control *)(kcontrol->private_value);
1609e8ba1e05SSrinivas Kandagatla hphr = mc->shift;
1610e8ba1e05SSrinivas Kandagatla
1611e8ba1e05SSrinivas Kandagatla wcd = wcd938x->sdw_priv[AIF1_PB];
1612e8ba1e05SSrinivas Kandagatla
1613e8ba1e05SSrinivas Kandagatla if (hphr)
1614e8ba1e05SSrinivas Kandagatla wcd938x->comp2_enable = value;
1615e8ba1e05SSrinivas Kandagatla else
1616e8ba1e05SSrinivas Kandagatla wcd938x->comp1_enable = value;
1617e8ba1e05SSrinivas Kandagatla
1618c5c1546aSSrinivas Kandagatla portidx = wcd->ch_info[mc->reg].port_num;
1619c5c1546aSSrinivas Kandagatla
1620e8ba1e05SSrinivas Kandagatla if (value)
1621c5c1546aSSrinivas Kandagatla wcd938x_connect_port(wcd, portidx, mc->reg, true);
1622e8ba1e05SSrinivas Kandagatla else
1623c5c1546aSSrinivas Kandagatla wcd938x_connect_port(wcd, portidx, mc->reg, false);
1624e8ba1e05SSrinivas Kandagatla
1625bd2347fdSSrinivas Kandagatla return 1;
1626e8ba1e05SSrinivas Kandagatla }
1627e8ba1e05SSrinivas Kandagatla
wcd938x_ldoh_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1628e8ba1e05SSrinivas Kandagatla static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol,
1629e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1630e8ba1e05SSrinivas Kandagatla {
1631e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1632e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1633e8ba1e05SSrinivas Kandagatla
1634e8ba1e05SSrinivas Kandagatla ucontrol->value.integer.value[0] = wcd938x->ldoh;
1635e8ba1e05SSrinivas Kandagatla
1636e8ba1e05SSrinivas Kandagatla return 0;
1637e8ba1e05SSrinivas Kandagatla }
1638e8ba1e05SSrinivas Kandagatla
wcd938x_ldoh_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1639e8ba1e05SSrinivas Kandagatla static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol,
1640e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1641e8ba1e05SSrinivas Kandagatla {
1642e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1643e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1644e8ba1e05SSrinivas Kandagatla
164510e7ff00SMark Brown if (wcd938x->ldoh == ucontrol->value.integer.value[0])
164610e7ff00SMark Brown return 0;
164710e7ff00SMark Brown
1648e8ba1e05SSrinivas Kandagatla wcd938x->ldoh = ucontrol->value.integer.value[0];
1649e8ba1e05SSrinivas Kandagatla
1650e8ba1e05SSrinivas Kandagatla return 1;
1651e8ba1e05SSrinivas Kandagatla }
1652e8ba1e05SSrinivas Kandagatla
wcd938x_bcs_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1653e8ba1e05SSrinivas Kandagatla static int wcd938x_bcs_get(struct snd_kcontrol *kcontrol,
1654e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1655e8ba1e05SSrinivas Kandagatla {
1656e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1657e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1658e8ba1e05SSrinivas Kandagatla
1659e8ba1e05SSrinivas Kandagatla ucontrol->value.integer.value[0] = wcd938x->bcs_dis;
1660e8ba1e05SSrinivas Kandagatla
1661e8ba1e05SSrinivas Kandagatla return 0;
1662e8ba1e05SSrinivas Kandagatla }
1663e8ba1e05SSrinivas Kandagatla
wcd938x_bcs_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1664e8ba1e05SSrinivas Kandagatla static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol,
1665e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1666e8ba1e05SSrinivas Kandagatla {
1667e8ba1e05SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1668e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
1669e8ba1e05SSrinivas Kandagatla
167010e7ff00SMark Brown if (wcd938x->bcs_dis == ucontrol->value.integer.value[0])
167110e7ff00SMark Brown return 0;
167210e7ff00SMark Brown
1673e8ba1e05SSrinivas Kandagatla wcd938x->bcs_dis = ucontrol->value.integer.value[0];
1674e8ba1e05SSrinivas Kandagatla
1675e8ba1e05SSrinivas Kandagatla return 1;
1676e8ba1e05SSrinivas Kandagatla }
1677e8ba1e05SSrinivas Kandagatla
1678e8ba1e05SSrinivas Kandagatla static const char * const tx_mode_mux_text_wcd9380[] = {
1679e8ba1e05SSrinivas Kandagatla "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
1680e8ba1e05SSrinivas Kandagatla };
1681e8ba1e05SSrinivas Kandagatla
1682e8ba1e05SSrinivas Kandagatla static const char * const tx_mode_mux_text[] = {
1683e8ba1e05SSrinivas Kandagatla "ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
1684e8ba1e05SSrinivas Kandagatla "ADC_ULP1", "ADC_ULP2",
1685e8ba1e05SSrinivas Kandagatla };
1686e8ba1e05SSrinivas Kandagatla
1687e8ba1e05SSrinivas Kandagatla static const char * const rx_hph_mode_mux_text_wcd9380[] = {
1688e8ba1e05SSrinivas Kandagatla "CLS_H_INVALID", "CLS_H_INVALID_1", "CLS_H_LP", "CLS_AB",
1689e8ba1e05SSrinivas Kandagatla "CLS_H_LOHIFI", "CLS_H_ULP", "CLS_H_INVALID_2", "CLS_AB_LP",
1690e8ba1e05SSrinivas Kandagatla "CLS_AB_LOHIFI",
1691e8ba1e05SSrinivas Kandagatla };
1692e8ba1e05SSrinivas Kandagatla
1693e8ba1e05SSrinivas Kandagatla static const char * const rx_hph_mode_mux_text[] = {
1694e8ba1e05SSrinivas Kandagatla "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
1695e8ba1e05SSrinivas Kandagatla "CLS_H_ULP", "CLS_AB_HIFI", "CLS_AB_LP", "CLS_AB_LOHIFI",
1696e8ba1e05SSrinivas Kandagatla };
1697e8ba1e05SSrinivas Kandagatla
16988da9db0cSSrinivas Kandagatla static const char * const adc2_mux_text[] = {
16998da9db0cSSrinivas Kandagatla "INP2", "INP3"
17008da9db0cSSrinivas Kandagatla };
17018da9db0cSSrinivas Kandagatla
17028da9db0cSSrinivas Kandagatla static const char * const adc3_mux_text[] = {
17038da9db0cSSrinivas Kandagatla "INP4", "INP6"
17048da9db0cSSrinivas Kandagatla };
17058da9db0cSSrinivas Kandagatla
17068da9db0cSSrinivas Kandagatla static const char * const adc4_mux_text[] = {
17078da9db0cSSrinivas Kandagatla "INP5", "INP7"
17088da9db0cSSrinivas Kandagatla };
17098da9db0cSSrinivas Kandagatla
17108da9db0cSSrinivas Kandagatla static const char * const rdac3_mux_text[] = {
17118da9db0cSSrinivas Kandagatla "RX1", "RX3"
17128da9db0cSSrinivas Kandagatla };
17138da9db0cSSrinivas Kandagatla
17148da9db0cSSrinivas Kandagatla static const char * const hdr12_mux_text[] = {
17158da9db0cSSrinivas Kandagatla "NO_HDR12", "HDR12"
17168da9db0cSSrinivas Kandagatla };
17178da9db0cSSrinivas Kandagatla
17188da9db0cSSrinivas Kandagatla static const char * const hdr34_mux_text[] = {
17198da9db0cSSrinivas Kandagatla "NO_HDR34", "HDR34"
17208da9db0cSSrinivas Kandagatla };
17218da9db0cSSrinivas Kandagatla
1722e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx0_mode_enum_wcd9380 =
1723e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
1724e8ba1e05SSrinivas Kandagatla tx_mode_mux_text_wcd9380);
1725e8ba1e05SSrinivas Kandagatla
1726e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx1_mode_enum_wcd9380 =
1727e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
1728e8ba1e05SSrinivas Kandagatla tx_mode_mux_text_wcd9380);
1729e8ba1e05SSrinivas Kandagatla
1730e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx2_mode_enum_wcd9380 =
1731e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
1732e8ba1e05SSrinivas Kandagatla tx_mode_mux_text_wcd9380);
1733e8ba1e05SSrinivas Kandagatla
1734e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx3_mode_enum_wcd9380 =
1735e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text_wcd9380),
1736e8ba1e05SSrinivas Kandagatla tx_mode_mux_text_wcd9380);
1737e8ba1e05SSrinivas Kandagatla
1738e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx0_mode_enum_wcd9385 =
1739e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(tx_mode_mux_text),
1740e8ba1e05SSrinivas Kandagatla tx_mode_mux_text);
1741e8ba1e05SSrinivas Kandagatla
1742e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx1_mode_enum_wcd9385 =
1743e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 1, ARRAY_SIZE(tx_mode_mux_text),
1744e8ba1e05SSrinivas Kandagatla tx_mode_mux_text);
1745e8ba1e05SSrinivas Kandagatla
1746e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx2_mode_enum_wcd9385 =
1747e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 2, ARRAY_SIZE(tx_mode_mux_text),
1748e8ba1e05SSrinivas Kandagatla tx_mode_mux_text);
1749e8ba1e05SSrinivas Kandagatla
1750e8ba1e05SSrinivas Kandagatla static const struct soc_enum tx3_mode_enum_wcd9385 =
1751e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE(SND_SOC_NOPM, 3, ARRAY_SIZE(tx_mode_mux_text),
1752e8ba1e05SSrinivas Kandagatla tx_mode_mux_text);
1753e8ba1e05SSrinivas Kandagatla
1754e8ba1e05SSrinivas Kandagatla static const struct soc_enum rx_hph_mode_mux_enum_wcd9380 =
1755e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text_wcd9380),
1756e8ba1e05SSrinivas Kandagatla rx_hph_mode_mux_text_wcd9380);
1757e8ba1e05SSrinivas Kandagatla
1758e8ba1e05SSrinivas Kandagatla static const struct soc_enum rx_hph_mode_mux_enum =
1759e8ba1e05SSrinivas Kandagatla SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
1760e8ba1e05SSrinivas Kandagatla rx_hph_mode_mux_text);
1761e8ba1e05SSrinivas Kandagatla
1762d5add08fSSrinivas Kandagatla static const struct soc_enum adc2_enum =
1763d5add08fSSrinivas Kandagatla SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 7,
1764d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
1765d5add08fSSrinivas Kandagatla
1766d5add08fSSrinivas Kandagatla static const struct soc_enum adc3_enum =
1767d5add08fSSrinivas Kandagatla SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 6,
1768d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc3_mux_text), adc3_mux_text);
1769d5add08fSSrinivas Kandagatla
1770d5add08fSSrinivas Kandagatla static const struct soc_enum adc4_enum =
1771d5add08fSSrinivas Kandagatla SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 5,
1772d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc4_mux_text), adc4_mux_text);
1773d5add08fSSrinivas Kandagatla
1774d5add08fSSrinivas Kandagatla static const struct soc_enum hdr12_enum =
1775d5add08fSSrinivas Kandagatla SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 4,
1776d5add08fSSrinivas Kandagatla ARRAY_SIZE(hdr12_mux_text), hdr12_mux_text);
1777d5add08fSSrinivas Kandagatla
1778d5add08fSSrinivas Kandagatla static const struct soc_enum hdr34_enum =
1779d5add08fSSrinivas Kandagatla SOC_ENUM_SINGLE(WCD938X_TX_NEW_AMIC_MUX_CFG, 3,
1780d5add08fSSrinivas Kandagatla ARRAY_SIZE(hdr34_mux_text), hdr34_mux_text);
1781d5add08fSSrinivas Kandagatla
17828da9db0cSSrinivas Kandagatla static const struct soc_enum rdac3_enum =
17838da9db0cSSrinivas Kandagatla SOC_ENUM_SINGLE(WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0,
17848da9db0cSSrinivas Kandagatla ARRAY_SIZE(rdac3_mux_text), rdac3_mux_text);
17858da9db0cSSrinivas Kandagatla
1786d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new adc1_switch[] = {
1787d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1788d5add08fSSrinivas Kandagatla };
1789d5add08fSSrinivas Kandagatla
1790d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new adc2_switch[] = {
1791d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1792d5add08fSSrinivas Kandagatla };
1793d5add08fSSrinivas Kandagatla
1794d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new adc3_switch[] = {
1795d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1796d5add08fSSrinivas Kandagatla };
1797d5add08fSSrinivas Kandagatla
1798d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new adc4_switch[] = {
1799d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1800d5add08fSSrinivas Kandagatla };
1801d5add08fSSrinivas Kandagatla
1802d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic1_switch[] = {
1803d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1804d5add08fSSrinivas Kandagatla };
1805d5add08fSSrinivas Kandagatla
1806d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic2_switch[] = {
1807d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1808d5add08fSSrinivas Kandagatla };
1809d5add08fSSrinivas Kandagatla
1810d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic3_switch[] = {
1811d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1812d5add08fSSrinivas Kandagatla };
1813d5add08fSSrinivas Kandagatla
1814d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic4_switch[] = {
1815d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1816d5add08fSSrinivas Kandagatla };
1817d5add08fSSrinivas Kandagatla
1818d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic5_switch[] = {
1819d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1820d5add08fSSrinivas Kandagatla };
1821d5add08fSSrinivas Kandagatla
1822d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic6_switch[] = {
1823d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1824d5add08fSSrinivas Kandagatla };
1825d5add08fSSrinivas Kandagatla
1826d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic7_switch[] = {
1827d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1828d5add08fSSrinivas Kandagatla };
1829d5add08fSSrinivas Kandagatla
1830d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new dmic8_switch[] = {
1831d5add08fSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
1832d5add08fSSrinivas Kandagatla };
1833d5add08fSSrinivas Kandagatla
18348da9db0cSSrinivas Kandagatla static const struct snd_kcontrol_new ear_rdac_switch[] = {
18358da9db0cSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
18368da9db0cSSrinivas Kandagatla };
18378da9db0cSSrinivas Kandagatla
18388da9db0cSSrinivas Kandagatla static const struct snd_kcontrol_new aux_rdac_switch[] = {
18398da9db0cSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
18408da9db0cSSrinivas Kandagatla };
18418da9db0cSSrinivas Kandagatla
18428da9db0cSSrinivas Kandagatla static const struct snd_kcontrol_new hphl_rdac_switch[] = {
18438da9db0cSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
18448da9db0cSSrinivas Kandagatla };
18458da9db0cSSrinivas Kandagatla
18468da9db0cSSrinivas Kandagatla static const struct snd_kcontrol_new hphr_rdac_switch[] = {
18478da9db0cSSrinivas Kandagatla SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
18488da9db0cSSrinivas Kandagatla };
18498da9db0cSSrinivas Kandagatla
1850d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new tx_adc2_mux =
1851d5add08fSSrinivas Kandagatla SOC_DAPM_ENUM("ADC2 MUX Mux", adc2_enum);
1852d5add08fSSrinivas Kandagatla
1853d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new tx_adc3_mux =
1854d5add08fSSrinivas Kandagatla SOC_DAPM_ENUM("ADC3 MUX Mux", adc3_enum);
1855d5add08fSSrinivas Kandagatla
1856d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new tx_adc4_mux =
1857d5add08fSSrinivas Kandagatla SOC_DAPM_ENUM("ADC4 MUX Mux", adc4_enum);
1858d5add08fSSrinivas Kandagatla
1859d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new tx_hdr12_mux =
1860d5add08fSSrinivas Kandagatla SOC_DAPM_ENUM("HDR12 MUX Mux", hdr12_enum);
1861d5add08fSSrinivas Kandagatla
1862d5add08fSSrinivas Kandagatla static const struct snd_kcontrol_new tx_hdr34_mux =
1863d5add08fSSrinivas Kandagatla SOC_DAPM_ENUM("HDR34 MUX Mux", hdr34_enum);
1864d5add08fSSrinivas Kandagatla
18658da9db0cSSrinivas Kandagatla static const struct snd_kcontrol_new rx_rdac3_mux =
18668da9db0cSSrinivas Kandagatla SOC_DAPM_ENUM("RDAC3_MUX Mux", rdac3_enum);
18678da9db0cSSrinivas Kandagatla
1868e8ba1e05SSrinivas Kandagatla static const struct snd_kcontrol_new wcd9380_snd_controls[] = {
1869e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum_wcd9380,
1870e8ba1e05SSrinivas Kandagatla wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
1871e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX0 MODE", tx0_mode_enum_wcd9380,
1872e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1873e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX1 MODE", tx1_mode_enum_wcd9380,
1874e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1875e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX2 MODE", tx2_mode_enum_wcd9380,
1876e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1877e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX3 MODE", tx3_mode_enum_wcd9380,
1878e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1879e8ba1e05SSrinivas Kandagatla };
1880e8ba1e05SSrinivas Kandagatla
1881e8ba1e05SSrinivas Kandagatla static const struct snd_kcontrol_new wcd9385_snd_controls[] = {
1882e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("RX HPH Mode", rx_hph_mode_mux_enum,
1883e8ba1e05SSrinivas Kandagatla wcd938x_rx_hph_mode_get, wcd938x_rx_hph_mode_put),
1884e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX0 MODE", tx0_mode_enum_wcd9385,
1885e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1886e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX1 MODE", tx1_mode_enum_wcd9385,
1887e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1888e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX2 MODE", tx2_mode_enum_wcd9385,
1889e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1890e8ba1e05SSrinivas Kandagatla SOC_ENUM_EXT("TX3 MODE", tx3_mode_enum_wcd9385,
1891e8ba1e05SSrinivas Kandagatla wcd938x_tx_mode_get, wcd938x_tx_mode_put),
1892e8ba1e05SSrinivas Kandagatla };
1893e8ba1e05SSrinivas Kandagatla
wcd938x_get_swr_port(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1894e8ba1e05SSrinivas Kandagatla static int wcd938x_get_swr_port(struct snd_kcontrol *kcontrol,
1895e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1896e8ba1e05SSrinivas Kandagatla {
1897e8ba1e05SSrinivas Kandagatla struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
1898e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp);
1899e8ba1e05SSrinivas Kandagatla struct wcd938x_sdw_priv *wcd;
1900e8ba1e05SSrinivas Kandagatla struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
1901e8ba1e05SSrinivas Kandagatla int dai_id = mixer->shift;
1902c5c1546aSSrinivas Kandagatla int portidx, ch_idx = mixer->reg;
1903c5c1546aSSrinivas Kandagatla
1904e8ba1e05SSrinivas Kandagatla
1905e8ba1e05SSrinivas Kandagatla wcd = wcd938x->sdw_priv[dai_id];
1906c5c1546aSSrinivas Kandagatla portidx = wcd->ch_info[ch_idx].port_num;
1907e8ba1e05SSrinivas Kandagatla
1908e8ba1e05SSrinivas Kandagatla ucontrol->value.integer.value[0] = wcd->port_enable[portidx];
1909e8ba1e05SSrinivas Kandagatla
1910e8ba1e05SSrinivas Kandagatla return 0;
1911e8ba1e05SSrinivas Kandagatla }
1912e8ba1e05SSrinivas Kandagatla
wcd938x_set_swr_port(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1913e8ba1e05SSrinivas Kandagatla static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol,
1914e8ba1e05SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
1915e8ba1e05SSrinivas Kandagatla {
1916e8ba1e05SSrinivas Kandagatla struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
1917e8ba1e05SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(comp);
1918e8ba1e05SSrinivas Kandagatla struct wcd938x_sdw_priv *wcd;
1919e8ba1e05SSrinivas Kandagatla struct soc_mixer_control *mixer =
1920e8ba1e05SSrinivas Kandagatla (struct soc_mixer_control *)kcontrol->private_value;
1921c5c1546aSSrinivas Kandagatla int ch_idx = mixer->reg;
1922c5c1546aSSrinivas Kandagatla int portidx;
1923e8ba1e05SSrinivas Kandagatla int dai_id = mixer->shift;
1924e8ba1e05SSrinivas Kandagatla bool enable;
1925e8ba1e05SSrinivas Kandagatla
1926e8ba1e05SSrinivas Kandagatla wcd = wcd938x->sdw_priv[dai_id];
1927e8ba1e05SSrinivas Kandagatla
1928c5c1546aSSrinivas Kandagatla portidx = wcd->ch_info[ch_idx].port_num;
1929e8ba1e05SSrinivas Kandagatla if (ucontrol->value.integer.value[0])
1930e8ba1e05SSrinivas Kandagatla enable = true;
1931e8ba1e05SSrinivas Kandagatla else
1932e8ba1e05SSrinivas Kandagatla enable = false;
1933e8ba1e05SSrinivas Kandagatla
1934e8ba1e05SSrinivas Kandagatla wcd->port_enable[portidx] = enable;
1935e8ba1e05SSrinivas Kandagatla
1936c5c1546aSSrinivas Kandagatla wcd938x_connect_port(wcd, portidx, ch_idx, enable);
1937e8ba1e05SSrinivas Kandagatla
1938bd2347fdSSrinivas Kandagatla return 1;
1939e8ba1e05SSrinivas Kandagatla
1940e8ba1e05SSrinivas Kandagatla }
1941e8ba1e05SSrinivas Kandagatla
1942bcee7ed0SSrinivas Kandagatla /* MBHC related */
wcd938x_mbhc_clk_setup(struct snd_soc_component * component,bool enable)1943bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_clk_setup(struct snd_soc_component *component,
1944bcee7ed0SSrinivas Kandagatla bool enable)
1945bcee7ed0SSrinivas Kandagatla {
1946bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_1,
1947bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_CTL_RCO_EN_MASK, enable);
1948bcee7ed0SSrinivas Kandagatla }
1949bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_mbhc_bias_control(struct snd_soc_component * component,bool enable)1950bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_mbhc_bias_control(struct snd_soc_component *component,
1951bcee7ed0SSrinivas Kandagatla bool enable)
1952bcee7ed0SSrinivas Kandagatla {
1953bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MBHC_ELECT,
1954bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_BIAS_EN, enable);
1955bcee7ed0SSrinivas Kandagatla }
1956bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_program_btn_thr(struct snd_soc_component * component,int * btn_low,int * btn_high,int num_btn,bool is_micbias)1957bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_program_btn_thr(struct snd_soc_component *component,
1958bcee7ed0SSrinivas Kandagatla int *btn_low, int *btn_high,
1959bcee7ed0SSrinivas Kandagatla int num_btn, bool is_micbias)
1960bcee7ed0SSrinivas Kandagatla {
1961bcee7ed0SSrinivas Kandagatla int i, vth;
1962bcee7ed0SSrinivas Kandagatla
1963bcee7ed0SSrinivas Kandagatla if (num_btn > WCD_MBHC_DEF_BUTTONS) {
1964bcee7ed0SSrinivas Kandagatla dev_err(component->dev, "%s: invalid number of buttons: %d\n",
1965bcee7ed0SSrinivas Kandagatla __func__, num_btn);
1966bcee7ed0SSrinivas Kandagatla return;
1967bcee7ed0SSrinivas Kandagatla }
1968bcee7ed0SSrinivas Kandagatla
1969bcee7ed0SSrinivas Kandagatla for (i = 0; i < num_btn; i++) {
1970bcee7ed0SSrinivas Kandagatla vth = ((btn_high[i] * 2) / 25) & 0x3F;
1971bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MBHC_BTN0 + i,
1972bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_BTN_VTH_MASK, vth);
1973bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: btn_high[%d]: %d, vth: %d\n",
1974bcee7ed0SSrinivas Kandagatla __func__, i, btn_high[i], vth);
1975bcee7ed0SSrinivas Kandagatla }
1976bcee7ed0SSrinivas Kandagatla }
1977bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_micb_en_status(struct snd_soc_component * component,int micb_num)1978bcee7ed0SSrinivas Kandagatla static bool wcd938x_mbhc_micb_en_status(struct snd_soc_component *component, int micb_num)
1979bcee7ed0SSrinivas Kandagatla {
1980bcee7ed0SSrinivas Kandagatla u8 val;
1981bcee7ed0SSrinivas Kandagatla
1982bcee7ed0SSrinivas Kandagatla if (micb_num == MIC_BIAS_2) {
1983bcee7ed0SSrinivas Kandagatla val = snd_soc_component_read_field(component,
1984bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MICB2,
1985bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MICB2_ENABLE_MASK);
1986bcee7ed0SSrinivas Kandagatla if (val == WCD938X_MICB_ENABLE)
1987bcee7ed0SSrinivas Kandagatla return true;
1988bcee7ed0SSrinivas Kandagatla }
1989bcee7ed0SSrinivas Kandagatla return false;
1990bcee7ed0SSrinivas Kandagatla }
1991bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_hph_l_pull_up_control(struct snd_soc_component * component,int pull_up_cur)1992bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_hph_l_pull_up_control(struct snd_soc_component *component,
1993bcee7ed0SSrinivas Kandagatla int pull_up_cur)
1994bcee7ed0SSrinivas Kandagatla {
1995bcee7ed0SSrinivas Kandagatla /* Default pull up current to 2uA */
1996bcee7ed0SSrinivas Kandagatla if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA)
1997bcee7ed0SSrinivas Kandagatla pull_up_cur = HS_PULLUP_I_2P0_UA;
1998bcee7ed0SSrinivas Kandagatla
1999bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component,
2000bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT,
2001bcee7ed0SSrinivas Kandagatla WCD938X_HSDET_PULLUP_C_MASK, pull_up_cur);
2002bcee7ed0SSrinivas Kandagatla }
2003bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_request_micbias(struct snd_soc_component * component,int micb_num,int req)2004bcee7ed0SSrinivas Kandagatla static int wcd938x_mbhc_request_micbias(struct snd_soc_component *component,
2005bcee7ed0SSrinivas Kandagatla int micb_num, int req)
2006bcee7ed0SSrinivas Kandagatla {
2007bcee7ed0SSrinivas Kandagatla return wcd938x_micbias_control(component, micb_num, req, false);
2008bcee7ed0SSrinivas Kandagatla }
2009bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_micb_ramp_control(struct snd_soc_component * component,bool enable)2010bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_micb_ramp_control(struct snd_soc_component *component,
2011bcee7ed0SSrinivas Kandagatla bool enable)
2012bcee7ed0SSrinivas Kandagatla {
2013bcee7ed0SSrinivas Kandagatla if (enable) {
2014bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
2015bcee7ed0SSrinivas Kandagatla WCD938X_RAMP_SHIFT_CTRL_MASK, 0x0C);
2016bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
2017bcee7ed0SSrinivas Kandagatla WCD938X_RAMP_EN_MASK, 1);
2018bcee7ed0SSrinivas Kandagatla } else {
2019bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
2020bcee7ed0SSrinivas Kandagatla WCD938X_RAMP_EN_MASK, 0);
2021bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MICB2_RAMP,
2022bcee7ed0SSrinivas Kandagatla WCD938X_RAMP_SHIFT_CTRL_MASK, 0);
2023bcee7ed0SSrinivas Kandagatla }
2024bcee7ed0SSrinivas Kandagatla }
2025bcee7ed0SSrinivas Kandagatla
wcd938x_get_micb_vout_ctl_val(u32 micb_mv)2026bcee7ed0SSrinivas Kandagatla static int wcd938x_get_micb_vout_ctl_val(u32 micb_mv)
2027bcee7ed0SSrinivas Kandagatla {
2028bcee7ed0SSrinivas Kandagatla /* min micbias voltage is 1V and maximum is 2.85V */
2029bcee7ed0SSrinivas Kandagatla if (micb_mv < 1000 || micb_mv > 2850)
2030bcee7ed0SSrinivas Kandagatla return -EINVAL;
2031bcee7ed0SSrinivas Kandagatla
2032bcee7ed0SSrinivas Kandagatla return (micb_mv - 1000) / 50;
2033bcee7ed0SSrinivas Kandagatla }
2034bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component * component,int req_volt,int micb_num)2035bcee7ed0SSrinivas Kandagatla static int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
2036bcee7ed0SSrinivas Kandagatla int req_volt, int micb_num)
2037bcee7ed0SSrinivas Kandagatla {
2038bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2039bcee7ed0SSrinivas Kandagatla int cur_vout_ctl, req_vout_ctl, micb_reg, micb_en, ret = 0;
2040bcee7ed0SSrinivas Kandagatla
2041bcee7ed0SSrinivas Kandagatla switch (micb_num) {
2042bcee7ed0SSrinivas Kandagatla case MIC_BIAS_1:
2043bcee7ed0SSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB1;
2044bcee7ed0SSrinivas Kandagatla break;
2045bcee7ed0SSrinivas Kandagatla case MIC_BIAS_2:
2046bcee7ed0SSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB2;
2047bcee7ed0SSrinivas Kandagatla break;
2048bcee7ed0SSrinivas Kandagatla case MIC_BIAS_3:
2049bcee7ed0SSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB3;
2050bcee7ed0SSrinivas Kandagatla break;
2051bcee7ed0SSrinivas Kandagatla case MIC_BIAS_4:
2052bcee7ed0SSrinivas Kandagatla micb_reg = WCD938X_ANA_MICB4;
2053bcee7ed0SSrinivas Kandagatla break;
2054bcee7ed0SSrinivas Kandagatla default:
2055bcee7ed0SSrinivas Kandagatla return -EINVAL;
2056bcee7ed0SSrinivas Kandagatla }
2057bcee7ed0SSrinivas Kandagatla mutex_lock(&wcd938x->micb_lock);
2058bcee7ed0SSrinivas Kandagatla /*
2059bcee7ed0SSrinivas Kandagatla * If requested micbias voltage is same as current micbias
2060bcee7ed0SSrinivas Kandagatla * voltage, then just return. Otherwise, adjust voltage as
2061bcee7ed0SSrinivas Kandagatla * per requested value. If micbias is already enabled, then
2062bcee7ed0SSrinivas Kandagatla * to avoid slow micbias ramp-up or down enable pull-up
2063bcee7ed0SSrinivas Kandagatla * momentarily, change the micbias value and then re-enable
2064bcee7ed0SSrinivas Kandagatla * micbias.
2065bcee7ed0SSrinivas Kandagatla */
2066bcee7ed0SSrinivas Kandagatla micb_en = snd_soc_component_read_field(component, micb_reg,
2067bcee7ed0SSrinivas Kandagatla WCD938X_MICB_EN_MASK);
2068bcee7ed0SSrinivas Kandagatla cur_vout_ctl = snd_soc_component_read_field(component, micb_reg,
2069bcee7ed0SSrinivas Kandagatla WCD938X_MICB_VOUT_MASK);
2070bcee7ed0SSrinivas Kandagatla
2071bcee7ed0SSrinivas Kandagatla req_vout_ctl = wcd938x_get_micb_vout_ctl_val(req_volt);
2072bcee7ed0SSrinivas Kandagatla if (req_vout_ctl < 0) {
2073bcee7ed0SSrinivas Kandagatla ret = -EINVAL;
2074bcee7ed0SSrinivas Kandagatla goto exit;
2075bcee7ed0SSrinivas Kandagatla }
2076bcee7ed0SSrinivas Kandagatla
2077bcee7ed0SSrinivas Kandagatla if (cur_vout_ctl == req_vout_ctl) {
2078bcee7ed0SSrinivas Kandagatla ret = 0;
2079bcee7ed0SSrinivas Kandagatla goto exit;
2080bcee7ed0SSrinivas Kandagatla }
2081bcee7ed0SSrinivas Kandagatla
2082bcee7ed0SSrinivas Kandagatla if (micb_en == WCD938X_MICB_ENABLE)
2083bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
2084bcee7ed0SSrinivas Kandagatla WCD938X_MICB_EN_MASK,
2085bcee7ed0SSrinivas Kandagatla WCD938X_MICB_PULL_UP);
2086bcee7ed0SSrinivas Kandagatla
2087bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
2088bcee7ed0SSrinivas Kandagatla WCD938X_MICB_VOUT_MASK,
2089bcee7ed0SSrinivas Kandagatla req_vout_ctl);
2090bcee7ed0SSrinivas Kandagatla
2091bcee7ed0SSrinivas Kandagatla if (micb_en == WCD938X_MICB_ENABLE) {
2092bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, micb_reg,
2093bcee7ed0SSrinivas Kandagatla WCD938X_MICB_EN_MASK,
2094bcee7ed0SSrinivas Kandagatla WCD938X_MICB_ENABLE);
2095bcee7ed0SSrinivas Kandagatla /*
2096bcee7ed0SSrinivas Kandagatla * Add 2ms delay as per HW requirement after enabling
2097bcee7ed0SSrinivas Kandagatla * micbias
2098bcee7ed0SSrinivas Kandagatla */
2099bcee7ed0SSrinivas Kandagatla usleep_range(2000, 2100);
2100bcee7ed0SSrinivas Kandagatla }
2101bcee7ed0SSrinivas Kandagatla exit:
2102bcee7ed0SSrinivas Kandagatla mutex_unlock(&wcd938x->micb_lock);
2103bcee7ed0SSrinivas Kandagatla return ret;
2104bcee7ed0SSrinivas Kandagatla }
2105bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component * component,int micb_num,bool req_en)2106bcee7ed0SSrinivas Kandagatla static int wcd938x_mbhc_micb_ctrl_threshold_mic(struct snd_soc_component *component,
2107bcee7ed0SSrinivas Kandagatla int micb_num, bool req_en)
2108bcee7ed0SSrinivas Kandagatla {
2109bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2110b2fde4deSchiminghao int micb_mv;
2111bcee7ed0SSrinivas Kandagatla
2112bcee7ed0SSrinivas Kandagatla if (micb_num != MIC_BIAS_2)
2113bcee7ed0SSrinivas Kandagatla return -EINVAL;
2114bcee7ed0SSrinivas Kandagatla /*
2115bcee7ed0SSrinivas Kandagatla * If device tree micbias level is already above the minimum
2116bcee7ed0SSrinivas Kandagatla * voltage needed to detect threshold microphone, then do
2117bcee7ed0SSrinivas Kandagatla * not change the micbias, just return.
2118bcee7ed0SSrinivas Kandagatla */
2119bcee7ed0SSrinivas Kandagatla if (wcd938x->micb2_mv >= WCD_MBHC_THR_HS_MICB_MV)
2120bcee7ed0SSrinivas Kandagatla return 0;
2121bcee7ed0SSrinivas Kandagatla
2122bcee7ed0SSrinivas Kandagatla micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : wcd938x->micb2_mv;
2123bcee7ed0SSrinivas Kandagatla
2124b2fde4deSchiminghao return wcd938x_mbhc_micb_adjust_voltage(component, micb_mv, MIC_BIAS_2);
2125bcee7ed0SSrinivas Kandagatla }
2126bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_get_result_params(struct snd_soc_component * component,s16 * d1_a,u16 noff,int32_t * zdet)212717d59d9eSJohan Hovold static void wcd938x_mbhc_get_result_params(struct snd_soc_component *component,
2128bcee7ed0SSrinivas Kandagatla s16 *d1_a, u16 noff,
2129bcee7ed0SSrinivas Kandagatla int32_t *zdet)
2130bcee7ed0SSrinivas Kandagatla {
213117d59d9eSJohan Hovold struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2132bcee7ed0SSrinivas Kandagatla int i;
2133bcee7ed0SSrinivas Kandagatla int val, val1;
2134bcee7ed0SSrinivas Kandagatla s16 c1;
2135bcee7ed0SSrinivas Kandagatla s32 x1, d1;
2136bcee7ed0SSrinivas Kandagatla int32_t denom;
2137e110ede8SColin Ian King static const int minCode_param[] = {
2138bcee7ed0SSrinivas Kandagatla 3277, 1639, 820, 410, 205, 103, 52, 26
2139bcee7ed0SSrinivas Kandagatla };
2140bcee7ed0SSrinivas Kandagatla
2141bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x20);
2142bcee7ed0SSrinivas Kandagatla for (i = 0; i < WCD938X_ZDET_NUM_MEASUREMENTS; i++) {
2143bcee7ed0SSrinivas Kandagatla regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_2, &val);
2144bcee7ed0SSrinivas Kandagatla if (val & 0x80)
2145bcee7ed0SSrinivas Kandagatla break;
2146bcee7ed0SSrinivas Kandagatla }
2147bcee7ed0SSrinivas Kandagatla val = val << 0x8;
2148bcee7ed0SSrinivas Kandagatla regmap_read(wcd938x->regmap, WCD938X_ANA_MBHC_RESULT_1, &val1);
2149bcee7ed0SSrinivas Kandagatla val |= val1;
2150bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MBHC_ZDET, 0x20, 0x00);
2151bcee7ed0SSrinivas Kandagatla x1 = WCD938X_MBHC_GET_X1(val);
2152bcee7ed0SSrinivas Kandagatla c1 = WCD938X_MBHC_GET_C1(val);
2153bcee7ed0SSrinivas Kandagatla /* If ramp is not complete, give additional 5ms */
2154bcee7ed0SSrinivas Kandagatla if ((c1 < 2) && x1)
2155bcee7ed0SSrinivas Kandagatla usleep_range(5000, 5050);
2156bcee7ed0SSrinivas Kandagatla
2157bcee7ed0SSrinivas Kandagatla if (!c1 || !x1) {
215817d59d9eSJohan Hovold dev_err(component->dev, "Impedance detect ramp error, c1=%d, x1=0x%x\n",
215917d59d9eSJohan Hovold c1, x1);
2160bcee7ed0SSrinivas Kandagatla goto ramp_down;
2161bcee7ed0SSrinivas Kandagatla }
2162bcee7ed0SSrinivas Kandagatla d1 = d1_a[c1];
2163bcee7ed0SSrinivas Kandagatla denom = (x1 * d1) - (1 << (14 - noff));
2164bcee7ed0SSrinivas Kandagatla if (denom > 0)
2165bcee7ed0SSrinivas Kandagatla *zdet = (WCD938X_MBHC_ZDET_CONST * 1000) / denom;
2166bcee7ed0SSrinivas Kandagatla else if (x1 < minCode_param[noff])
2167bcee7ed0SSrinivas Kandagatla *zdet = WCD938X_ZDET_FLOATING_IMPEDANCE;
2168bcee7ed0SSrinivas Kandagatla
216917d59d9eSJohan Hovold dev_dbg(component->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d (milliohm)\n",
2170bcee7ed0SSrinivas Kandagatla __func__, d1, c1, x1, *zdet);
2171bcee7ed0SSrinivas Kandagatla ramp_down:
2172bcee7ed0SSrinivas Kandagatla i = 0;
2173bcee7ed0SSrinivas Kandagatla while (x1) {
2174bcee7ed0SSrinivas Kandagatla regmap_read(wcd938x->regmap,
2175bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_RESULT_1, &val);
2176bcee7ed0SSrinivas Kandagatla regmap_read(wcd938x->regmap,
2177bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_RESULT_2, &val1);
2178bcee7ed0SSrinivas Kandagatla val = val << 0x08;
2179bcee7ed0SSrinivas Kandagatla val |= val1;
2180bcee7ed0SSrinivas Kandagatla x1 = WCD938X_MBHC_GET_X1(val);
2181bcee7ed0SSrinivas Kandagatla i++;
2182bcee7ed0SSrinivas Kandagatla if (i == WCD938X_ZDET_NUM_MEASUREMENTS)
2183bcee7ed0SSrinivas Kandagatla break;
2184bcee7ed0SSrinivas Kandagatla }
2185bcee7ed0SSrinivas Kandagatla }
2186bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_zdet_ramp(struct snd_soc_component * component,struct wcd938x_mbhc_zdet_param * zdet_param,int32_t * zl,int32_t * zr,s16 * d1_a)2187bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_zdet_ramp(struct snd_soc_component *component,
2188bcee7ed0SSrinivas Kandagatla struct wcd938x_mbhc_zdet_param *zdet_param,
2189bcee7ed0SSrinivas Kandagatla int32_t *zl, int32_t *zr, s16 *d1_a)
2190bcee7ed0SSrinivas Kandagatla {
2191bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2192bcee7ed0SSrinivas Kandagatla int32_t zdet = 0;
2193bcee7ed0SSrinivas Kandagatla
2194bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
2195bcee7ed0SSrinivas Kandagatla WCD938X_ZDET_MAXV_CTL_MASK, zdet_param->ldo_ctl);
2196bcee7ed0SSrinivas Kandagatla snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN5,
2197bcee7ed0SSrinivas Kandagatla WCD938X_VTH_MASK, zdet_param->btn5);
2198bcee7ed0SSrinivas Kandagatla snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN6,
2199bcee7ed0SSrinivas Kandagatla WCD938X_VTH_MASK, zdet_param->btn6);
2200bcee7ed0SSrinivas Kandagatla snd_soc_component_update_bits(component, WCD938X_ANA_MBHC_BTN7,
2201bcee7ed0SSrinivas Kandagatla WCD938X_VTH_MASK, zdet_param->btn7);
2202bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL,
2203bcee7ed0SSrinivas Kandagatla WCD938X_ZDET_RANGE_CTL_MASK, zdet_param->noff);
2204bcee7ed0SSrinivas Kandagatla snd_soc_component_update_bits(component, WCD938X_MBHC_NEW_ZDET_RAMP_CTL,
2205bcee7ed0SSrinivas Kandagatla 0x0F, zdet_param->nshift);
2206bcee7ed0SSrinivas Kandagatla
2207bcee7ed0SSrinivas Kandagatla if (!zl)
2208bcee7ed0SSrinivas Kandagatla goto z_right;
2209bcee7ed0SSrinivas Kandagatla /* Start impedance measurement for HPH_L */
2210bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2211bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_ZDET, 0x80, 0x80);
2212bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: ramp for HPH_L, noff = %d\n",
2213bcee7ed0SSrinivas Kandagatla __func__, zdet_param->noff);
221417d59d9eSJohan Hovold wcd938x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet);
2215bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2216bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_ZDET, 0x80, 0x00);
2217bcee7ed0SSrinivas Kandagatla
2218bcee7ed0SSrinivas Kandagatla *zl = zdet;
2219bcee7ed0SSrinivas Kandagatla
2220bcee7ed0SSrinivas Kandagatla z_right:
2221bcee7ed0SSrinivas Kandagatla if (!zr)
2222bcee7ed0SSrinivas Kandagatla return;
2223bcee7ed0SSrinivas Kandagatla /* Start impedance measurement for HPH_R */
2224bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2225bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_ZDET, 0x40, 0x40);
2226bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: ramp for HPH_R, noff = %d\n",
2227bcee7ed0SSrinivas Kandagatla __func__, zdet_param->noff);
222817d59d9eSJohan Hovold wcd938x_mbhc_get_result_params(component, d1_a, zdet_param->noff, &zdet);
2229bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2230bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_ZDET, 0x40, 0x00);
2231bcee7ed0SSrinivas Kandagatla
2232bcee7ed0SSrinivas Kandagatla *zr = zdet;
2233bcee7ed0SSrinivas Kandagatla }
2234bcee7ed0SSrinivas Kandagatla
wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component * component,int32_t * z_val,int flag_l_r)22355db9fe95SJohan Hovold static void wcd938x_wcd_mbhc_qfuse_cal(struct snd_soc_component *component,
2236bcee7ed0SSrinivas Kandagatla int32_t *z_val, int flag_l_r)
2237bcee7ed0SSrinivas Kandagatla {
2238bcee7ed0SSrinivas Kandagatla s16 q1;
2239bcee7ed0SSrinivas Kandagatla int q1_cal;
2240bcee7ed0SSrinivas Kandagatla
2241bcee7ed0SSrinivas Kandagatla if (*z_val < (WCD938X_ZDET_VAL_400/1000))
2242bcee7ed0SSrinivas Kandagatla q1 = snd_soc_component_read(component,
2243bcee7ed0SSrinivas Kandagatla WCD938X_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
2244bcee7ed0SSrinivas Kandagatla else
2245bcee7ed0SSrinivas Kandagatla q1 = snd_soc_component_read(component,
2246bcee7ed0SSrinivas Kandagatla WCD938X_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
2247bcee7ed0SSrinivas Kandagatla if (q1 & 0x80)
2248bcee7ed0SSrinivas Kandagatla q1_cal = (10000 - ((q1 & 0x7F) * 25));
2249bcee7ed0SSrinivas Kandagatla else
2250bcee7ed0SSrinivas Kandagatla q1_cal = (10000 + (q1 * 25));
2251bcee7ed0SSrinivas Kandagatla if (q1_cal > 0)
2252bcee7ed0SSrinivas Kandagatla *z_val = ((*z_val) * 10000) / q1_cal;
2253bcee7ed0SSrinivas Kandagatla }
2254bcee7ed0SSrinivas Kandagatla
wcd938x_wcd_mbhc_calc_impedance(struct snd_soc_component * component,uint32_t * zl,uint32_t * zr)2255bcee7ed0SSrinivas Kandagatla static void wcd938x_wcd_mbhc_calc_impedance(struct snd_soc_component *component,
2256bcee7ed0SSrinivas Kandagatla uint32_t *zl, uint32_t *zr)
2257bcee7ed0SSrinivas Kandagatla {
2258bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2259bcee7ed0SSrinivas Kandagatla s16 reg0, reg1, reg2, reg3, reg4;
2260bcee7ed0SSrinivas Kandagatla int32_t z1L, z1R, z1Ls;
2261bcee7ed0SSrinivas Kandagatla int zMono, z_diff1, z_diff2;
2262bcee7ed0SSrinivas Kandagatla bool is_fsm_disable = false;
2263bcee7ed0SSrinivas Kandagatla struct wcd938x_mbhc_zdet_param zdet_param[] = {
2264bcee7ed0SSrinivas Kandagatla {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
2265bcee7ed0SSrinivas Kandagatla {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
2266bcee7ed0SSrinivas Kandagatla {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
2267bcee7ed0SSrinivas Kandagatla {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
2268bcee7ed0SSrinivas Kandagatla };
2269bcee7ed0SSrinivas Kandagatla struct wcd938x_mbhc_zdet_param *zdet_param_ptr = NULL;
2270bcee7ed0SSrinivas Kandagatla s16 d1_a[][4] = {
2271bcee7ed0SSrinivas Kandagatla {0, 30, 90, 30},
2272bcee7ed0SSrinivas Kandagatla {0, 30, 30, 5},
2273bcee7ed0SSrinivas Kandagatla {0, 30, 30, 5},
2274bcee7ed0SSrinivas Kandagatla {0, 30, 30, 5},
2275bcee7ed0SSrinivas Kandagatla };
2276bcee7ed0SSrinivas Kandagatla s16 *d1 = NULL;
2277bcee7ed0SSrinivas Kandagatla
2278bcee7ed0SSrinivas Kandagatla reg0 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN5);
2279bcee7ed0SSrinivas Kandagatla reg1 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN6);
2280bcee7ed0SSrinivas Kandagatla reg2 = snd_soc_component_read(component, WCD938X_ANA_MBHC_BTN7);
2281bcee7ed0SSrinivas Kandagatla reg3 = snd_soc_component_read(component, WCD938X_MBHC_CTL_CLK);
2282bcee7ed0SSrinivas Kandagatla reg4 = snd_soc_component_read(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL);
2283bcee7ed0SSrinivas Kandagatla
2284bcee7ed0SSrinivas Kandagatla if (snd_soc_component_read(component, WCD938X_ANA_MBHC_ELECT) & 0x80) {
2285bcee7ed0SSrinivas Kandagatla is_fsm_disable = true;
2286bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2287bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_ELECT, 0x80, 0x00);
2288bcee7ed0SSrinivas Kandagatla }
2289bcee7ed0SSrinivas Kandagatla
2290bcee7ed0SSrinivas Kandagatla /* For NO-jack, disable L_DET_EN before Z-det measurements */
2291bcee7ed0SSrinivas Kandagatla if (wcd938x->mbhc_cfg.hphl_swh)
2292bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2293bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_MECH, 0x80, 0x00);
2294bcee7ed0SSrinivas Kandagatla
2295bcee7ed0SSrinivas Kandagatla /* Turn off 100k pull down on HPHL */
2296bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2297bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_MECH, 0x01, 0x00);
2298bcee7ed0SSrinivas Kandagatla
2299bcee7ed0SSrinivas Kandagatla /* Disable surge protection before impedance detection.
2300bcee7ed0SSrinivas Kandagatla * This is done to give correct value for high impedance.
2301bcee7ed0SSrinivas Kandagatla */
2302bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2303bcee7ed0SSrinivas Kandagatla WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
2304bcee7ed0SSrinivas Kandagatla /* 1ms delay needed after disable surge protection */
2305bcee7ed0SSrinivas Kandagatla usleep_range(1000, 1010);
2306bcee7ed0SSrinivas Kandagatla
2307bcee7ed0SSrinivas Kandagatla /* First get impedance on Left */
2308bcee7ed0SSrinivas Kandagatla d1 = d1_a[1];
2309bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[1];
2310bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
2311bcee7ed0SSrinivas Kandagatla
2312bcee7ed0SSrinivas Kandagatla if (!WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
2313bcee7ed0SSrinivas Kandagatla goto left_ch_impedance;
2314bcee7ed0SSrinivas Kandagatla
2315bcee7ed0SSrinivas Kandagatla /* Second ramp for left ch */
2316bcee7ed0SSrinivas Kandagatla if (z1L < WCD938X_ZDET_VAL_32) {
2317bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[0];
2318bcee7ed0SSrinivas Kandagatla d1 = d1_a[0];
2319bcee7ed0SSrinivas Kandagatla } else if ((z1L > WCD938X_ZDET_VAL_400) &&
2320bcee7ed0SSrinivas Kandagatla (z1L <= WCD938X_ZDET_VAL_1200)) {
2321bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[2];
2322bcee7ed0SSrinivas Kandagatla d1 = d1_a[2];
2323bcee7ed0SSrinivas Kandagatla } else if (z1L > WCD938X_ZDET_VAL_1200) {
2324bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[3];
2325bcee7ed0SSrinivas Kandagatla d1 = d1_a[3];
2326bcee7ed0SSrinivas Kandagatla }
2327bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
2328bcee7ed0SSrinivas Kandagatla
2329bcee7ed0SSrinivas Kandagatla left_ch_impedance:
2330bcee7ed0SSrinivas Kandagatla if ((z1L == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
2331bcee7ed0SSrinivas Kandagatla (z1L > WCD938X_ZDET_VAL_100K)) {
2332bcee7ed0SSrinivas Kandagatla *zl = WCD938X_ZDET_FLOATING_IMPEDANCE;
2333bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[1];
2334bcee7ed0SSrinivas Kandagatla d1 = d1_a[1];
2335bcee7ed0SSrinivas Kandagatla } else {
2336bcee7ed0SSrinivas Kandagatla *zl = z1L/1000;
2337bcee7ed0SSrinivas Kandagatla wcd938x_wcd_mbhc_qfuse_cal(component, zl, 0);
2338bcee7ed0SSrinivas Kandagatla }
2339bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
2340bcee7ed0SSrinivas Kandagatla __func__, *zl);
2341bcee7ed0SSrinivas Kandagatla
2342bcee7ed0SSrinivas Kandagatla /* Start of right impedance ramp and calculation */
2343bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
2344bcee7ed0SSrinivas Kandagatla if (WCD938X_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
2345bcee7ed0SSrinivas Kandagatla if (((z1R > WCD938X_ZDET_VAL_1200) &&
2346bcee7ed0SSrinivas Kandagatla (zdet_param_ptr->noff == 0x6)) ||
2347bcee7ed0SSrinivas Kandagatla ((*zl) != WCD938X_ZDET_FLOATING_IMPEDANCE))
2348bcee7ed0SSrinivas Kandagatla goto right_ch_impedance;
2349bcee7ed0SSrinivas Kandagatla /* Second ramp for right ch */
2350bcee7ed0SSrinivas Kandagatla if (z1R < WCD938X_ZDET_VAL_32) {
2351bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[0];
2352bcee7ed0SSrinivas Kandagatla d1 = d1_a[0];
2353bcee7ed0SSrinivas Kandagatla } else if ((z1R > WCD938X_ZDET_VAL_400) &&
2354bcee7ed0SSrinivas Kandagatla (z1R <= WCD938X_ZDET_VAL_1200)) {
2355bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[2];
2356bcee7ed0SSrinivas Kandagatla d1 = d1_a[2];
2357bcee7ed0SSrinivas Kandagatla } else if (z1R > WCD938X_ZDET_VAL_1200) {
2358bcee7ed0SSrinivas Kandagatla zdet_param_ptr = &zdet_param[3];
2359bcee7ed0SSrinivas Kandagatla d1 = d1_a[3];
2360bcee7ed0SSrinivas Kandagatla }
2361bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
2362bcee7ed0SSrinivas Kandagatla }
2363bcee7ed0SSrinivas Kandagatla right_ch_impedance:
2364bcee7ed0SSrinivas Kandagatla if ((z1R == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
2365bcee7ed0SSrinivas Kandagatla (z1R > WCD938X_ZDET_VAL_100K)) {
2366bcee7ed0SSrinivas Kandagatla *zr = WCD938X_ZDET_FLOATING_IMPEDANCE;
2367bcee7ed0SSrinivas Kandagatla } else {
2368bcee7ed0SSrinivas Kandagatla *zr = z1R/1000;
2369bcee7ed0SSrinivas Kandagatla wcd938x_wcd_mbhc_qfuse_cal(component, zr, 1);
2370bcee7ed0SSrinivas Kandagatla }
2371bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
2372bcee7ed0SSrinivas Kandagatla __func__, *zr);
2373bcee7ed0SSrinivas Kandagatla
2374bcee7ed0SSrinivas Kandagatla /* Mono/stereo detection */
2375bcee7ed0SSrinivas Kandagatla if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) &&
2376bcee7ed0SSrinivas Kandagatla (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE)) {
2377bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev,
2378bcee7ed0SSrinivas Kandagatla "%s: plug type is invalid or extension cable\n",
2379bcee7ed0SSrinivas Kandagatla __func__);
2380bcee7ed0SSrinivas Kandagatla goto zdet_complete;
2381bcee7ed0SSrinivas Kandagatla }
2382bcee7ed0SSrinivas Kandagatla if ((*zl == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
2383bcee7ed0SSrinivas Kandagatla (*zr == WCD938X_ZDET_FLOATING_IMPEDANCE) ||
2384bcee7ed0SSrinivas Kandagatla ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
2385bcee7ed0SSrinivas Kandagatla ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
2386bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev,
2387bcee7ed0SSrinivas Kandagatla "%s: Mono plug type with one ch floating or shorted to GND\n",
2388bcee7ed0SSrinivas Kandagatla __func__);
2389bcee7ed0SSrinivas Kandagatla wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
2390bcee7ed0SSrinivas Kandagatla goto zdet_complete;
2391bcee7ed0SSrinivas Kandagatla }
2392bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
2393bcee7ed0SSrinivas Kandagatla WCD938X_HPHPA_GND_OVR_MASK, 1);
2394bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
2395bcee7ed0SSrinivas Kandagatla WCD938X_HPHPA_GND_R_MASK, 1);
2396bcee7ed0SSrinivas Kandagatla if (*zl < (WCD938X_ZDET_VAL_32/1000))
2397bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls, NULL, d1);
2398bcee7ed0SSrinivas Kandagatla else
2399bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls, NULL, d1);
2400bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
2401bcee7ed0SSrinivas Kandagatla WCD938X_HPHPA_GND_R_MASK, 0);
2402bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_R_ATEST,
2403bcee7ed0SSrinivas Kandagatla WCD938X_HPHPA_GND_OVR_MASK, 0);
2404bcee7ed0SSrinivas Kandagatla z1Ls /= 1000;
2405bcee7ed0SSrinivas Kandagatla wcd938x_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
2406bcee7ed0SSrinivas Kandagatla /* Parallel of left Z and 9 ohm pull down resistor */
2407bcee7ed0SSrinivas Kandagatla zMono = ((*zl) * 9) / ((*zl) + 9);
2408bcee7ed0SSrinivas Kandagatla z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
2409bcee7ed0SSrinivas Kandagatla z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
2410bcee7ed0SSrinivas Kandagatla if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
2411bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: stereo plug type detected\n",
2412bcee7ed0SSrinivas Kandagatla __func__);
2413bcee7ed0SSrinivas Kandagatla wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_STEREO);
2414bcee7ed0SSrinivas Kandagatla } else {
2415bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: MONO plug type detected\n",
2416bcee7ed0SSrinivas Kandagatla __func__);
2417bcee7ed0SSrinivas Kandagatla wcd_mbhc_set_hph_type(wcd938x->wcd_mbhc, WCD_MBHC_HPH_MONO);
2418bcee7ed0SSrinivas Kandagatla }
2419bcee7ed0SSrinivas Kandagatla
2420bcee7ed0SSrinivas Kandagatla /* Enable surge protection again after impedance detection */
2421bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2422bcee7ed0SSrinivas Kandagatla WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
2423bcee7ed0SSrinivas Kandagatla zdet_complete:
2424bcee7ed0SSrinivas Kandagatla snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN5, reg0);
2425bcee7ed0SSrinivas Kandagatla snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN6, reg1);
2426bcee7ed0SSrinivas Kandagatla snd_soc_component_write(component, WCD938X_ANA_MBHC_BTN7, reg2);
2427bcee7ed0SSrinivas Kandagatla /* Turn on 100k pull down on HPHL */
2428bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2429bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_MECH, 0x01, 0x01);
2430bcee7ed0SSrinivas Kandagatla
2431bcee7ed0SSrinivas Kandagatla /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
2432bcee7ed0SSrinivas Kandagatla if (wcd938x->mbhc_cfg.hphl_swh)
2433bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2434bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_MECH, 0x80, 0x80);
2435bcee7ed0SSrinivas Kandagatla
2436bcee7ed0SSrinivas Kandagatla snd_soc_component_write(component, WCD938X_MBHC_NEW_ZDET_ANA_CTL, reg4);
2437bcee7ed0SSrinivas Kandagatla snd_soc_component_write(component, WCD938X_MBHC_CTL_CLK, reg3);
2438bcee7ed0SSrinivas Kandagatla if (is_fsm_disable)
2439bcee7ed0SSrinivas Kandagatla regmap_update_bits(wcd938x->regmap,
2440bcee7ed0SSrinivas Kandagatla WCD938X_ANA_MBHC_ELECT, 0x80, 0x80);
2441bcee7ed0SSrinivas Kandagatla }
2442bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_gnd_det_ctrl(struct snd_soc_component * component,bool enable)2443bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
2444bcee7ed0SSrinivas Kandagatla bool enable)
2445bcee7ed0SSrinivas Kandagatla {
2446bcee7ed0SSrinivas Kandagatla if (enable) {
2447bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
2448bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_HSG_PULLUP_COMP_EN, 1);
2449bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
2450bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_GND_DET_EN_MASK, 1);
2451bcee7ed0SSrinivas Kandagatla } else {
2452bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
2453bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_GND_DET_EN_MASK, 0);
2454bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_ANA_MBHC_MECH,
2455bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_HSG_PULLUP_COMP_EN, 0);
2456bcee7ed0SSrinivas Kandagatla }
2457bcee7ed0SSrinivas Kandagatla }
2458bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_hph_pull_down_ctrl(struct snd_soc_component * component,bool enable)2459bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_hph_pull_down_ctrl(struct snd_soc_component *component,
2460bcee7ed0SSrinivas Kandagatla bool enable)
2461bcee7ed0SSrinivas Kandagatla {
2462bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
2463bcee7ed0SSrinivas Kandagatla WCD938X_HPHPA_GND_R_MASK, enable);
2464bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_HPH_PA_CTL2,
2465bcee7ed0SSrinivas Kandagatla WCD938X_HPHPA_GND_L_MASK, enable);
2466bcee7ed0SSrinivas Kandagatla }
2467bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_moisture_config(struct snd_soc_component * component)2468bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_moisture_config(struct snd_soc_component *component)
2469bcee7ed0SSrinivas Kandagatla {
2470bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2471bcee7ed0SSrinivas Kandagatla
2472bcee7ed0SSrinivas Kandagatla if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
2473bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2474bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, R_OFF);
2475bcee7ed0SSrinivas Kandagatla return;
2476bcee7ed0SSrinivas Kandagatla }
2477bcee7ed0SSrinivas Kandagatla
2478bcee7ed0SSrinivas Kandagatla /* Do not enable moisture detection if jack type is NC */
2479bcee7ed0SSrinivas Kandagatla if (!wcd938x->mbhc_cfg.hphl_swh) {
2480bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
2481bcee7ed0SSrinivas Kandagatla __func__);
2482bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2483bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, R_OFF);
2484bcee7ed0SSrinivas Kandagatla return;
2485bcee7ed0SSrinivas Kandagatla }
2486bcee7ed0SSrinivas Kandagatla
2487bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2488bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
2489bcee7ed0SSrinivas Kandagatla }
2490bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_moisture_detect_en(struct snd_soc_component * component,bool enable)2491bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_moisture_detect_en(struct snd_soc_component *component, bool enable)
2492bcee7ed0SSrinivas Kandagatla {
2493bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2494bcee7ed0SSrinivas Kandagatla
2495bcee7ed0SSrinivas Kandagatla if (enable)
2496bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2497bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, wcd938x->mbhc_cfg.moist_rref);
2498bcee7ed0SSrinivas Kandagatla else
2499bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2500bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, R_OFF);
2501bcee7ed0SSrinivas Kandagatla }
2502bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_get_moisture_status(struct snd_soc_component * component)2503bcee7ed0SSrinivas Kandagatla static bool wcd938x_mbhc_get_moisture_status(struct snd_soc_component *component)
2504bcee7ed0SSrinivas Kandagatla {
2505bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2506bcee7ed0SSrinivas Kandagatla bool ret = false;
2507bcee7ed0SSrinivas Kandagatla
2508bcee7ed0SSrinivas Kandagatla if (wcd938x->mbhc_cfg.moist_rref == R_OFF) {
2509bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2510bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, R_OFF);
2511bcee7ed0SSrinivas Kandagatla goto done;
2512bcee7ed0SSrinivas Kandagatla }
2513bcee7ed0SSrinivas Kandagatla
2514bcee7ed0SSrinivas Kandagatla /* Do not enable moisture detection if jack type is NC */
2515bcee7ed0SSrinivas Kandagatla if (!wcd938x->mbhc_cfg.hphl_swh) {
2516bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: disable moisture detection for NC\n",
2517bcee7ed0SSrinivas Kandagatla __func__);
2518bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component, WCD938X_MBHC_NEW_CTL_2,
2519bcee7ed0SSrinivas Kandagatla WCD938X_M_RTH_CTL_MASK, R_OFF);
2520bcee7ed0SSrinivas Kandagatla goto done;
2521bcee7ed0SSrinivas Kandagatla }
2522bcee7ed0SSrinivas Kandagatla
2523bcee7ed0SSrinivas Kandagatla /*
2524bcee7ed0SSrinivas Kandagatla * If moisture_en is already enabled, then skip to plug type
2525bcee7ed0SSrinivas Kandagatla * detection.
2526bcee7ed0SSrinivas Kandagatla */
2527bcee7ed0SSrinivas Kandagatla if (snd_soc_component_read_field(component, WCD938X_MBHC_NEW_CTL_2, WCD938X_M_RTH_CTL_MASK))
2528bcee7ed0SSrinivas Kandagatla goto done;
2529bcee7ed0SSrinivas Kandagatla
2530bcee7ed0SSrinivas Kandagatla wcd938x_mbhc_moisture_detect_en(component, true);
2531bcee7ed0SSrinivas Kandagatla /* Read moisture comparator status */
2532bcee7ed0SSrinivas Kandagatla ret = ((snd_soc_component_read(component, WCD938X_MBHC_NEW_FSM_STATUS)
2533bcee7ed0SSrinivas Kandagatla & 0x20) ? 0 : 1);
2534bcee7ed0SSrinivas Kandagatla
2535bcee7ed0SSrinivas Kandagatla done:
2536bcee7ed0SSrinivas Kandagatla return ret;
2537bcee7ed0SSrinivas Kandagatla
2538bcee7ed0SSrinivas Kandagatla }
2539bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_moisture_polling_ctrl(struct snd_soc_component * component,bool enable)2540bcee7ed0SSrinivas Kandagatla static void wcd938x_mbhc_moisture_polling_ctrl(struct snd_soc_component *component,
2541bcee7ed0SSrinivas Kandagatla bool enable)
2542bcee7ed0SSrinivas Kandagatla {
2543bcee7ed0SSrinivas Kandagatla snd_soc_component_write_field(component,
2544bcee7ed0SSrinivas Kandagatla WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL,
2545bcee7ed0SSrinivas Kandagatla WCD938X_MOISTURE_EN_POLLING_MASK, enable);
2546bcee7ed0SSrinivas Kandagatla }
2547bcee7ed0SSrinivas Kandagatla
2548bcee7ed0SSrinivas Kandagatla static const struct wcd_mbhc_cb mbhc_cb = {
2549bcee7ed0SSrinivas Kandagatla .clk_setup = wcd938x_mbhc_clk_setup,
2550bcee7ed0SSrinivas Kandagatla .mbhc_bias = wcd938x_mbhc_mbhc_bias_control,
2551bcee7ed0SSrinivas Kandagatla .set_btn_thr = wcd938x_mbhc_program_btn_thr,
2552bcee7ed0SSrinivas Kandagatla .micbias_enable_status = wcd938x_mbhc_micb_en_status,
2553bcee7ed0SSrinivas Kandagatla .hph_pull_up_control_v2 = wcd938x_mbhc_hph_l_pull_up_control,
2554bcee7ed0SSrinivas Kandagatla .mbhc_micbias_control = wcd938x_mbhc_request_micbias,
2555bcee7ed0SSrinivas Kandagatla .mbhc_micb_ramp_control = wcd938x_mbhc_micb_ramp_control,
2556bcee7ed0SSrinivas Kandagatla .mbhc_micb_ctrl_thr_mic = wcd938x_mbhc_micb_ctrl_threshold_mic,
2557bcee7ed0SSrinivas Kandagatla .compute_impedance = wcd938x_wcd_mbhc_calc_impedance,
2558bcee7ed0SSrinivas Kandagatla .mbhc_gnd_det_ctrl = wcd938x_mbhc_gnd_det_ctrl,
2559bcee7ed0SSrinivas Kandagatla .hph_pull_down_ctrl = wcd938x_mbhc_hph_pull_down_ctrl,
2560bcee7ed0SSrinivas Kandagatla .mbhc_moisture_config = wcd938x_mbhc_moisture_config,
2561bcee7ed0SSrinivas Kandagatla .mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
2562bcee7ed0SSrinivas Kandagatla .mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
2563bcee7ed0SSrinivas Kandagatla .mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
2564bcee7ed0SSrinivas Kandagatla };
2565bcee7ed0SSrinivas Kandagatla
wcd938x_get_hph_type(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2566bcee7ed0SSrinivas Kandagatla static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
2567bcee7ed0SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
2568bcee7ed0SSrinivas Kandagatla {
2569bcee7ed0SSrinivas Kandagatla struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2570bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2571bcee7ed0SSrinivas Kandagatla
2572bcee7ed0SSrinivas Kandagatla ucontrol->value.integer.value[0] = wcd_mbhc_get_hph_type(wcd938x->wcd_mbhc);
2573bcee7ed0SSrinivas Kandagatla
2574bcee7ed0SSrinivas Kandagatla return 0;
2575bcee7ed0SSrinivas Kandagatla }
2576bcee7ed0SSrinivas Kandagatla
wcd938x_hph_impedance_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2577bcee7ed0SSrinivas Kandagatla static int wcd938x_hph_impedance_get(struct snd_kcontrol *kcontrol,
2578bcee7ed0SSrinivas Kandagatla struct snd_ctl_elem_value *ucontrol)
2579bcee7ed0SSrinivas Kandagatla {
2580bcee7ed0SSrinivas Kandagatla uint32_t zl, zr;
2581bcee7ed0SSrinivas Kandagatla bool hphr;
2582bcee7ed0SSrinivas Kandagatla struct soc_mixer_control *mc;
2583bcee7ed0SSrinivas Kandagatla struct snd_soc_component *component =
2584bcee7ed0SSrinivas Kandagatla snd_soc_kcontrol_component(kcontrol);
2585bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2586bcee7ed0SSrinivas Kandagatla
2587bcee7ed0SSrinivas Kandagatla mc = (struct soc_mixer_control *)(kcontrol->private_value);
2588bcee7ed0SSrinivas Kandagatla hphr = mc->shift;
2589bcee7ed0SSrinivas Kandagatla wcd_mbhc_get_impedance(wcd938x->wcd_mbhc, &zl, &zr);
2590bcee7ed0SSrinivas Kandagatla dev_dbg(component->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
2591bcee7ed0SSrinivas Kandagatla ucontrol->value.integer.value[0] = hphr ? zr : zl;
2592bcee7ed0SSrinivas Kandagatla
2593bcee7ed0SSrinivas Kandagatla return 0;
2594bcee7ed0SSrinivas Kandagatla }
2595bcee7ed0SSrinivas Kandagatla
2596bcee7ed0SSrinivas Kandagatla static const struct snd_kcontrol_new hph_type_detect_controls[] = {
2597b0217519SSrinivas Kandagatla SOC_SINGLE_EXT("HPH Type", 0, 0, WCD_MBHC_HPH_STEREO, 0,
2598bcee7ed0SSrinivas Kandagatla wcd938x_get_hph_type, NULL),
2599bcee7ed0SSrinivas Kandagatla };
2600bcee7ed0SSrinivas Kandagatla
2601bcee7ed0SSrinivas Kandagatla static const struct snd_kcontrol_new impedance_detect_controls[] = {
2602b0217519SSrinivas Kandagatla SOC_SINGLE_EXT("HPHL Impedance", 0, 0, INT_MAX, 0,
2603bcee7ed0SSrinivas Kandagatla wcd938x_hph_impedance_get, NULL),
2604b0217519SSrinivas Kandagatla SOC_SINGLE_EXT("HPHR Impedance", 0, 1, INT_MAX, 0,
2605bcee7ed0SSrinivas Kandagatla wcd938x_hph_impedance_get, NULL),
2606bcee7ed0SSrinivas Kandagatla };
2607bcee7ed0SSrinivas Kandagatla
wcd938x_mbhc_init(struct snd_soc_component * component)2608bcee7ed0SSrinivas Kandagatla static int wcd938x_mbhc_init(struct snd_soc_component *component)
2609bcee7ed0SSrinivas Kandagatla {
2610bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2611bcee7ed0SSrinivas Kandagatla struct wcd_mbhc_intr *intr_ids = &wcd938x->intr_ids;
2612bcee7ed0SSrinivas Kandagatla
2613bcee7ed0SSrinivas Kandagatla intr_ids->mbhc_sw_intr = regmap_irq_get_virq(wcd938x->irq_chip,
2614bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_MBHC_SW_DET);
2615bcee7ed0SSrinivas Kandagatla intr_ids->mbhc_btn_press_intr = regmap_irq_get_virq(wcd938x->irq_chip,
2616bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_MBHC_BUTTON_PRESS_DET);
2617bcee7ed0SSrinivas Kandagatla intr_ids->mbhc_btn_release_intr = regmap_irq_get_virq(wcd938x->irq_chip,
2618bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET);
2619bcee7ed0SSrinivas Kandagatla intr_ids->mbhc_hs_ins_intr = regmap_irq_get_virq(wcd938x->irq_chip,
2620bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET);
2621bcee7ed0SSrinivas Kandagatla intr_ids->mbhc_hs_rem_intr = regmap_irq_get_virq(wcd938x->irq_chip,
2622bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_MBHC_ELECT_INS_REM_DET);
2623bcee7ed0SSrinivas Kandagatla intr_ids->hph_left_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
2624bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_HPHL_OCP_INT);
2625bcee7ed0SSrinivas Kandagatla intr_ids->hph_right_ocp = regmap_irq_get_virq(wcd938x->irq_chip,
2626bcee7ed0SSrinivas Kandagatla WCD938X_IRQ_HPHR_OCP_INT);
2627bcee7ed0SSrinivas Kandagatla
2628bcee7ed0SSrinivas Kandagatla wcd938x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
26297dfae263SJohan Hovold if (IS_ERR(wcd938x->wcd_mbhc))
26307dfae263SJohan Hovold return PTR_ERR(wcd938x->wcd_mbhc);
2631bcee7ed0SSrinivas Kandagatla
2632bcee7ed0SSrinivas Kandagatla snd_soc_add_component_controls(component, impedance_detect_controls,
2633bcee7ed0SSrinivas Kandagatla ARRAY_SIZE(impedance_detect_controls));
2634bcee7ed0SSrinivas Kandagatla snd_soc_add_component_controls(component, hph_type_detect_controls,
2635bcee7ed0SSrinivas Kandagatla ARRAY_SIZE(hph_type_detect_controls));
2636bcee7ed0SSrinivas Kandagatla
2637bcee7ed0SSrinivas Kandagatla return 0;
2638bcee7ed0SSrinivas Kandagatla }
2639a3406f87SJohan Hovold
wcd938x_mbhc_deinit(struct snd_soc_component * component)2640a3406f87SJohan Hovold static void wcd938x_mbhc_deinit(struct snd_soc_component *component)
2641a3406f87SJohan Hovold {
2642a3406f87SJohan Hovold struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
2643a3406f87SJohan Hovold
2644a3406f87SJohan Hovold wcd_mbhc_deinit(wcd938x->wcd_mbhc);
2645a3406f87SJohan Hovold }
2646a3406f87SJohan Hovold
2647bcee7ed0SSrinivas Kandagatla /* END MBHC */
2648bcee7ed0SSrinivas Kandagatla
2649e8ba1e05SSrinivas Kandagatla static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
2650e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("HPHL_COMP Switch", WCD938X_COMP_L, 0, 1, 0,
2651e8ba1e05SSrinivas Kandagatla wcd938x_get_compander, wcd938x_set_compander),
2652e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("HPHR_COMP Switch", WCD938X_COMP_R, 1, 1, 0,
2653e8ba1e05SSrinivas Kandagatla wcd938x_get_compander, wcd938x_set_compander),
2654e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("HPHL Switch", WCD938X_HPH_L, 0, 1, 0,
2655e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2656e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("HPHR Switch", WCD938X_HPH_R, 0, 1, 0,
2657e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2658e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("CLSH Switch", WCD938X_CLSH, 0, 1, 0,
2659e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2660e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("LO Switch", WCD938X_LO, 0, 1, 0,
2661e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2662e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DSD_L Switch", WCD938X_DSD_L, 0, 1, 0,
2663e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2664e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DSD_R Switch", WCD938X_DSD_R, 0, 1, 0,
2665e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2666c03226baSSrinivas Kandagatla SOC_SINGLE_TLV("HPHL Volume", WCD938X_HPH_L_EN, 0, 0x18, 1, line_gain),
2667c03226baSSrinivas Kandagatla SOC_SINGLE_TLV("HPHR Volume", WCD938X_HPH_R_EN, 0, 0x18, 1, line_gain),
2668e8ba1e05SSrinivas Kandagatla WCD938X_EAR_PA_GAIN_TLV("EAR_PA Volume", WCD938X_ANA_EAR_COMPANDER_CTL,
2669e8ba1e05SSrinivas Kandagatla 2, 0x10, 0, ear_pa_gain),
2670e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("ADC1 Switch", WCD938X_ADC1, 1, 1, 0,
2671e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2672e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("ADC2 Switch", WCD938X_ADC2, 1, 1, 0,
2673e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2674e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("ADC3 Switch", WCD938X_ADC3, 1, 1, 0,
2675e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2676e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("ADC4 Switch", WCD938X_ADC4, 1, 1, 0,
2677e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2678e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC0 Switch", WCD938X_DMIC0, 1, 1, 0,
2679e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2680e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC1 Switch", WCD938X_DMIC1, 1, 1, 0,
2681e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2682e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("MBHC Switch", WCD938X_MBHC, 1, 1, 0,
2683e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2684e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC2 Switch", WCD938X_DMIC2, 1, 1, 0,
2685e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2686e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC3 Switch", WCD938X_DMIC3, 1, 1, 0,
2687e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2688e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC4 Switch", WCD938X_DMIC4, 1, 1, 0,
2689e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2690e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC5 Switch", WCD938X_DMIC5, 1, 1, 0,
2691e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2692e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC6 Switch", WCD938X_DMIC6, 1, 1, 0,
2693e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2694e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("DMIC7 Switch", WCD938X_DMIC7, 1, 1, 0,
2695e8ba1e05SSrinivas Kandagatla wcd938x_get_swr_port, wcd938x_set_swr_port),
2696e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("LDOH Enable Switch", SND_SOC_NOPM, 0, 1, 0,
2697e8ba1e05SSrinivas Kandagatla wcd938x_ldoh_get, wcd938x_ldoh_put),
2698e8ba1e05SSrinivas Kandagatla SOC_SINGLE_EXT("ADC2_BCS Disable Switch", SND_SOC_NOPM, 0, 1, 0,
2699e8ba1e05SSrinivas Kandagatla wcd938x_bcs_get, wcd938x_bcs_put),
2700e8ba1e05SSrinivas Kandagatla
2701e8ba1e05SSrinivas Kandagatla SOC_SINGLE_TLV("ADC1 Volume", WCD938X_ANA_TX_CH1, 0, 20, 0, analog_gain),
2702e8ba1e05SSrinivas Kandagatla SOC_SINGLE_TLV("ADC2 Volume", WCD938X_ANA_TX_CH2, 0, 20, 0, analog_gain),
2703e8ba1e05SSrinivas Kandagatla SOC_SINGLE_TLV("ADC3 Volume", WCD938X_ANA_TX_CH3, 0, 20, 0, analog_gain),
2704e8ba1e05SSrinivas Kandagatla SOC_SINGLE_TLV("ADC4 Volume", WCD938X_ANA_TX_CH4, 0, 20, 0, analog_gain),
2705e8ba1e05SSrinivas Kandagatla };
2706e8ba1e05SSrinivas Kandagatla
27078da9db0cSSrinivas Kandagatla static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
2708d5add08fSSrinivas Kandagatla
2709d5add08fSSrinivas Kandagatla /*input widgets*/
2710d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC1"),
2711d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC2"),
2712d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC3"),
2713d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC4"),
2714d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC5"),
2715d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC6"),
2716d5add08fSSrinivas Kandagatla SND_SOC_DAPM_INPUT("AMIC7"),
2717d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIC("Analog Mic1", NULL),
2718d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIC("Analog Mic2", NULL),
2719d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIC("Analog Mic3", NULL),
2720d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIC("Analog Mic4", NULL),
2721d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIC("Analog Mic5", NULL),
2722d5add08fSSrinivas Kandagatla
2723d5add08fSSrinivas Kandagatla /*tx widgets*/
2724d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC1", NULL, SND_SOC_NOPM, 0, 0,
2725d5add08fSSrinivas Kandagatla wcd938x_codec_enable_adc,
2726d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2727d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC2", NULL, SND_SOC_NOPM, 1, 0,
2728d5add08fSSrinivas Kandagatla wcd938x_codec_enable_adc,
2729d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2730d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC3", NULL, SND_SOC_NOPM, 2, 0,
2731d5add08fSSrinivas Kandagatla wcd938x_codec_enable_adc,
2732d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2733d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("ADC4", NULL, SND_SOC_NOPM, 3, 0,
2734d5add08fSSrinivas Kandagatla wcd938x_codec_enable_adc,
2735d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2736d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
2737d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2738d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2739d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 1, 0,
2740d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2741d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2742d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 2, 0,
2743d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2744d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2745d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 3, 0,
2746d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2747d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2748d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 4, 0,
2749d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2750d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2751d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 5, 0,
2752d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2753d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2754d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 6, 0,
2755d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2756d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2757d5add08fSSrinivas Kandagatla SND_SOC_DAPM_ADC_E("DMIC8", NULL, SND_SOC_NOPM, 7, 0,
2758d5add08fSSrinivas Kandagatla wcd938x_codec_enable_dmic,
2759d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2760d5add08fSSrinivas Kandagatla
2761d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC1 REQ", SND_SOC_NOPM, 0, 0,
2762d5add08fSSrinivas Kandagatla NULL, 0, wcd938x_adc_enable_req,
2763d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2764d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC2 REQ", SND_SOC_NOPM, 1, 0,
2765d5add08fSSrinivas Kandagatla NULL, 0, wcd938x_adc_enable_req,
2766d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2767d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC3 REQ", SND_SOC_NOPM, 2, 0,
2768d5add08fSSrinivas Kandagatla NULL, 0, wcd938x_adc_enable_req,
2769d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2770d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC4 REQ", SND_SOC_NOPM, 3, 0, NULL, 0,
2771d5add08fSSrinivas Kandagatla wcd938x_adc_enable_req,
2772d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2773d5add08fSSrinivas Kandagatla
2774d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
2775d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MUX("ADC3 MUX", SND_SOC_NOPM, 0, 0, &tx_adc3_mux),
2776d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MUX("ADC4 MUX", SND_SOC_NOPM, 0, 0, &tx_adc4_mux),
2777d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MUX("HDR12 MUX", SND_SOC_NOPM, 0, 0, &tx_hdr12_mux),
2778d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MUX("HDR34 MUX", SND_SOC_NOPM, 0, 0, &tx_hdr34_mux),
2779d5add08fSSrinivas Kandagatla
2780d5add08fSSrinivas Kandagatla /*tx mixers*/
2781d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC1_MIXER", SND_SOC_NOPM, 0, 0, adc1_switch,
2782d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc1_switch), wcd938x_tx_swr_ctrl,
2783d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2784d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC2_MIXER", SND_SOC_NOPM, 0, 0, adc2_switch,
2785d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc2_switch), wcd938x_tx_swr_ctrl,
2786d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2787d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC3_MIXER", SND_SOC_NOPM, 0, 0, adc3_switch,
2788d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc3_switch), wcd938x_tx_swr_ctrl,
2789d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2790d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("ADC4_MIXER", SND_SOC_NOPM, 0, 0, adc4_switch,
2791d5add08fSSrinivas Kandagatla ARRAY_SIZE(adc4_switch), wcd938x_tx_swr_ctrl,
2792d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2793d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC1_MIXER", SND_SOC_NOPM, 0, 0, dmic1_switch,
2794d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic1_switch), wcd938x_tx_swr_ctrl,
2795d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2796d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC2_MIXER", SND_SOC_NOPM, 0, 0, dmic2_switch,
2797d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic2_switch), wcd938x_tx_swr_ctrl,
2798d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2799d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC3_MIXER", SND_SOC_NOPM, 0, 0, dmic3_switch,
2800d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic3_switch), wcd938x_tx_swr_ctrl,
2801d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2802d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC4_MIXER", SND_SOC_NOPM, 0, 0, dmic4_switch,
2803d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic4_switch), wcd938x_tx_swr_ctrl,
2804d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2805d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC5_MIXER", SND_SOC_NOPM, 0, 0, dmic5_switch,
2806d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic5_switch), wcd938x_tx_swr_ctrl,
2807d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2808d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC6_MIXER", SND_SOC_NOPM, 0, 0, dmic6_switch,
2809d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic6_switch), wcd938x_tx_swr_ctrl,
2810d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2811d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC7_MIXER", SND_SOC_NOPM, 0, 0, dmic7_switch,
2812d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic7_switch), wcd938x_tx_swr_ctrl,
2813d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2814d5add08fSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("DMIC8_MIXER", SND_SOC_NOPM, 0, 0, dmic8_switch,
2815d5add08fSSrinivas Kandagatla ARRAY_SIZE(dmic8_switch), wcd938x_tx_swr_ctrl,
2816d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2817d5add08fSSrinivas Kandagatla /* micbias widgets*/
2818d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
2819d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias,
2820d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2821d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2822d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
2823d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias,
2824d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2825d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2826d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
2827d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias,
2828d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2829d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2830d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0,
2831d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias,
2832d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2833d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2834d5add08fSSrinivas Kandagatla
2835d5add08fSSrinivas Kandagatla /* micbias pull up widgets*/
2836d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("VA MIC BIAS1", SND_SOC_NOPM, MIC_BIAS_1, 0,
2837d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias_pullup,
2838d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2839d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2840d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("VA MIC BIAS2", SND_SOC_NOPM, MIC_BIAS_2, 0,
2841d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias_pullup,
2842d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2843d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2844d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("VA MIC BIAS3", SND_SOC_NOPM, MIC_BIAS_3, 0,
2845d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias_pullup,
2846d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2847d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2848d5add08fSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("VA MIC BIAS4", SND_SOC_NOPM, MIC_BIAS_4, 0,
2849d5add08fSSrinivas Kandagatla wcd938x_codec_enable_micbias_pullup,
2850d5add08fSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
2851d5add08fSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
2852d5add08fSSrinivas Kandagatla
2853d5add08fSSrinivas Kandagatla /*output widgets tx*/
2854d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"),
2855d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"),
2856d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"),
2857d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("ADC4_OUTPUT"),
2858d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"),
2859d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"),
2860d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"),
2861d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"),
2862d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"),
2863d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"),
2864d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC7_OUTPUT"),
2865d5add08fSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("DMIC8_OUTPUT"),
2866d5add08fSSrinivas Kandagatla
28678da9db0cSSrinivas Kandagatla SND_SOC_DAPM_INPUT("IN1_HPHL"),
28688da9db0cSSrinivas Kandagatla SND_SOC_DAPM_INPUT("IN2_HPHR"),
28698da9db0cSSrinivas Kandagatla SND_SOC_DAPM_INPUT("IN3_AUX"),
28708da9db0cSSrinivas Kandagatla
28718da9db0cSSrinivas Kandagatla /*rx widgets*/
28728da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PGA_E("EAR PGA", WCD938X_ANA_EAR, 7, 0, NULL, 0,
28738da9db0cSSrinivas Kandagatla wcd938x_codec_enable_ear_pa,
28748da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
28758da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
28768da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PGA_E("AUX PGA", WCD938X_AUX_AUXPA, 7, 0, NULL, 0,
28778da9db0cSSrinivas Kandagatla wcd938x_codec_enable_aux_pa,
28788da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
28798da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
28808da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PGA_E("HPHL PGA", WCD938X_ANA_HPH, 7, 0, NULL, 0,
28818da9db0cSSrinivas Kandagatla wcd938x_codec_enable_hphl_pa,
28828da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
28838da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
28848da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PGA_E("HPHR PGA", WCD938X_ANA_HPH, 6, 0, NULL, 0,
28858da9db0cSSrinivas Kandagatla wcd938x_codec_enable_hphr_pa,
28868da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
28878da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
28888da9db0cSSrinivas Kandagatla
28898da9db0cSSrinivas Kandagatla SND_SOC_DAPM_DAC_E("RDAC1", NULL, SND_SOC_NOPM, 0, 0,
28908da9db0cSSrinivas Kandagatla wcd938x_codec_hphl_dac_event,
28918da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
28928da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
28938da9db0cSSrinivas Kandagatla SND_SOC_DAPM_DAC_E("RDAC2", NULL, SND_SOC_NOPM, 0, 0,
28948da9db0cSSrinivas Kandagatla wcd938x_codec_hphr_dac_event,
28958da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
28968da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
28978da9db0cSSrinivas Kandagatla SND_SOC_DAPM_DAC_E("RDAC3", NULL, SND_SOC_NOPM, 0, 0,
28988da9db0cSSrinivas Kandagatla wcd938x_codec_ear_dac_event,
28998da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
29008da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
29018da9db0cSSrinivas Kandagatla SND_SOC_DAPM_DAC_E("RDAC4", NULL, SND_SOC_NOPM, 0, 0,
29028da9db0cSSrinivas Kandagatla wcd938x_codec_aux_dac_event,
29038da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
29048da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
29058da9db0cSSrinivas Kandagatla
29068da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MUX("RDAC3_MUX", SND_SOC_NOPM, 0, 0, &rx_rdac3_mux),
29078da9db0cSSrinivas Kandagatla
29088da9db0cSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("VDD_BUCK", SND_SOC_NOPM, 0, 0, NULL, 0),
29098da9db0cSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY("RXCLK", SND_SOC_NOPM, 0, 0,
29108da9db0cSSrinivas Kandagatla wcd938x_codec_enable_rxclk,
29118da9db0cSSrinivas Kandagatla SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
29128da9db0cSSrinivas Kandagatla SND_SOC_DAPM_POST_PMD),
29138da9db0cSSrinivas Kandagatla
29148da9db0cSSrinivas Kandagatla SND_SOC_DAPM_SUPPLY_S("CLS_H_PORT", 1, SND_SOC_NOPM, 0, 0, NULL, 0),
29158da9db0cSSrinivas Kandagatla
29168da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("RX1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
29178da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("RX2", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
29188da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER_E("RX3", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
29198da9db0cSSrinivas Kandagatla
29208da9db0cSSrinivas Kandagatla /* rx mixer widgets*/
29218da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER("EAR_RDAC", SND_SOC_NOPM, 0, 0,
29228da9db0cSSrinivas Kandagatla ear_rdac_switch, ARRAY_SIZE(ear_rdac_switch)),
29238da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER("AUX_RDAC", SND_SOC_NOPM, 0, 0,
29248da9db0cSSrinivas Kandagatla aux_rdac_switch, ARRAY_SIZE(aux_rdac_switch)),
29258da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER("HPHL_RDAC", SND_SOC_NOPM, 0, 0,
29268da9db0cSSrinivas Kandagatla hphl_rdac_switch, ARRAY_SIZE(hphl_rdac_switch)),
29278da9db0cSSrinivas Kandagatla SND_SOC_DAPM_MIXER("HPHR_RDAC", SND_SOC_NOPM, 0, 0,
29288da9db0cSSrinivas Kandagatla hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)),
29298da9db0cSSrinivas Kandagatla
29308da9db0cSSrinivas Kandagatla /*output widgets rx*/
29318da9db0cSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("EAR"),
29328da9db0cSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("AUX"),
29338da9db0cSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("HPHL"),
29348da9db0cSSrinivas Kandagatla SND_SOC_DAPM_OUTPUT("HPHR"),
293504544222SSrinivas Kandagatla
293604544222SSrinivas Kandagatla };
293704544222SSrinivas Kandagatla
293804544222SSrinivas Kandagatla static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
293904544222SSrinivas Kandagatla {"ADC1_OUTPUT", NULL, "ADC1_MIXER"},
294004544222SSrinivas Kandagatla {"ADC1_MIXER", "Switch", "ADC1 REQ"},
294104544222SSrinivas Kandagatla {"ADC1 REQ", NULL, "ADC1"},
294204544222SSrinivas Kandagatla {"ADC1", NULL, "AMIC1"},
294304544222SSrinivas Kandagatla
294404544222SSrinivas Kandagatla {"ADC2_OUTPUT", NULL, "ADC2_MIXER"},
294504544222SSrinivas Kandagatla {"ADC2_MIXER", "Switch", "ADC2 REQ"},
294604544222SSrinivas Kandagatla {"ADC2 REQ", NULL, "ADC2"},
294704544222SSrinivas Kandagatla {"ADC2", NULL, "HDR12 MUX"},
294804544222SSrinivas Kandagatla {"HDR12 MUX", "NO_HDR12", "ADC2 MUX"},
294904544222SSrinivas Kandagatla {"HDR12 MUX", "HDR12", "AMIC1"},
295004544222SSrinivas Kandagatla {"ADC2 MUX", "INP3", "AMIC3"},
295104544222SSrinivas Kandagatla {"ADC2 MUX", "INP2", "AMIC2"},
295204544222SSrinivas Kandagatla
295304544222SSrinivas Kandagatla {"ADC3_OUTPUT", NULL, "ADC3_MIXER"},
295404544222SSrinivas Kandagatla {"ADC3_MIXER", "Switch", "ADC3 REQ"},
295504544222SSrinivas Kandagatla {"ADC3 REQ", NULL, "ADC3"},
295604544222SSrinivas Kandagatla {"ADC3", NULL, "HDR34 MUX"},
295704544222SSrinivas Kandagatla {"HDR34 MUX", "NO_HDR34", "ADC3 MUX"},
295804544222SSrinivas Kandagatla {"HDR34 MUX", "HDR34", "AMIC5"},
295904544222SSrinivas Kandagatla {"ADC3 MUX", "INP4", "AMIC4"},
296004544222SSrinivas Kandagatla {"ADC3 MUX", "INP6", "AMIC6"},
296104544222SSrinivas Kandagatla
296204544222SSrinivas Kandagatla {"ADC4_OUTPUT", NULL, "ADC4_MIXER"},
296304544222SSrinivas Kandagatla {"ADC4_MIXER", "Switch", "ADC4 REQ"},
296404544222SSrinivas Kandagatla {"ADC4 REQ", NULL, "ADC4"},
296504544222SSrinivas Kandagatla {"ADC4", NULL, "ADC4 MUX"},
296604544222SSrinivas Kandagatla {"ADC4 MUX", "INP5", "AMIC5"},
296704544222SSrinivas Kandagatla {"ADC4 MUX", "INP7", "AMIC7"},
296804544222SSrinivas Kandagatla
296904544222SSrinivas Kandagatla {"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"},
297004544222SSrinivas Kandagatla {"DMIC1_MIXER", "Switch", "DMIC1"},
297104544222SSrinivas Kandagatla
297204544222SSrinivas Kandagatla {"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"},
297304544222SSrinivas Kandagatla {"DMIC2_MIXER", "Switch", "DMIC2"},
297404544222SSrinivas Kandagatla
297504544222SSrinivas Kandagatla {"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"},
297604544222SSrinivas Kandagatla {"DMIC3_MIXER", "Switch", "DMIC3"},
297704544222SSrinivas Kandagatla
297804544222SSrinivas Kandagatla {"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"},
297904544222SSrinivas Kandagatla {"DMIC4_MIXER", "Switch", "DMIC4"},
298004544222SSrinivas Kandagatla
298104544222SSrinivas Kandagatla {"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"},
298204544222SSrinivas Kandagatla {"DMIC5_MIXER", "Switch", "DMIC5"},
298304544222SSrinivas Kandagatla
298404544222SSrinivas Kandagatla {"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"},
298504544222SSrinivas Kandagatla {"DMIC6_MIXER", "Switch", "DMIC6"},
298604544222SSrinivas Kandagatla
298704544222SSrinivas Kandagatla {"DMIC7_OUTPUT", NULL, "DMIC7_MIXER"},
298804544222SSrinivas Kandagatla {"DMIC7_MIXER", "Switch", "DMIC7"},
298904544222SSrinivas Kandagatla
299004544222SSrinivas Kandagatla {"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"},
299104544222SSrinivas Kandagatla {"DMIC8_MIXER", "Switch", "DMIC8"},
299204544222SSrinivas Kandagatla
299304544222SSrinivas Kandagatla {"IN1_HPHL", NULL, "VDD_BUCK"},
299404544222SSrinivas Kandagatla {"IN1_HPHL", NULL, "CLS_H_PORT"},
299504544222SSrinivas Kandagatla
299604544222SSrinivas Kandagatla {"RX1", NULL, "IN1_HPHL"},
299704544222SSrinivas Kandagatla {"RX1", NULL, "RXCLK"},
299804544222SSrinivas Kandagatla {"RDAC1", NULL, "RX1"},
299904544222SSrinivas Kandagatla {"HPHL_RDAC", "Switch", "RDAC1"},
300004544222SSrinivas Kandagatla {"HPHL PGA", NULL, "HPHL_RDAC"},
300104544222SSrinivas Kandagatla {"HPHL", NULL, "HPHL PGA"},
300204544222SSrinivas Kandagatla
300304544222SSrinivas Kandagatla {"IN2_HPHR", NULL, "VDD_BUCK"},
300404544222SSrinivas Kandagatla {"IN2_HPHR", NULL, "CLS_H_PORT"},
300504544222SSrinivas Kandagatla {"RX2", NULL, "IN2_HPHR"},
300604544222SSrinivas Kandagatla {"RDAC2", NULL, "RX2"},
300704544222SSrinivas Kandagatla {"RX2", NULL, "RXCLK"},
300804544222SSrinivas Kandagatla {"HPHR_RDAC", "Switch", "RDAC2"},
300904544222SSrinivas Kandagatla {"HPHR PGA", NULL, "HPHR_RDAC"},
301004544222SSrinivas Kandagatla {"HPHR", NULL, "HPHR PGA"},
301104544222SSrinivas Kandagatla
301204544222SSrinivas Kandagatla {"IN3_AUX", NULL, "VDD_BUCK"},
301304544222SSrinivas Kandagatla {"IN3_AUX", NULL, "CLS_H_PORT"},
301404544222SSrinivas Kandagatla {"RX3", NULL, "IN3_AUX"},
301504544222SSrinivas Kandagatla {"RDAC4", NULL, "RX3"},
301604544222SSrinivas Kandagatla {"RX3", NULL, "RXCLK"},
301704544222SSrinivas Kandagatla {"AUX_RDAC", "Switch", "RDAC4"},
301804544222SSrinivas Kandagatla {"AUX PGA", NULL, "AUX_RDAC"},
301904544222SSrinivas Kandagatla {"AUX", NULL, "AUX PGA"},
302004544222SSrinivas Kandagatla
302104544222SSrinivas Kandagatla {"RDAC3_MUX", "RX3", "RX3"},
302204544222SSrinivas Kandagatla {"RDAC3_MUX", "RX1", "RX1"},
302304544222SSrinivas Kandagatla {"RDAC3", NULL, "RDAC3_MUX"},
302404544222SSrinivas Kandagatla {"EAR_RDAC", "Switch", "RDAC3"},
302504544222SSrinivas Kandagatla {"EAR PGA", NULL, "EAR_RDAC"},
302604544222SSrinivas Kandagatla {"EAR", NULL, "EAR PGA"},
30278da9db0cSSrinivas Kandagatla };
30288da9db0cSSrinivas Kandagatla
wcd938x_set_micbias_data(struct wcd938x_priv * wcd938x)30298d78602aSSrinivas Kandagatla static int wcd938x_set_micbias_data(struct wcd938x_priv *wcd938x)
30308d78602aSSrinivas Kandagatla {
30318d78602aSSrinivas Kandagatla int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
30328d78602aSSrinivas Kandagatla
30338d78602aSSrinivas Kandagatla /* set micbias voltage */
30348d78602aSSrinivas Kandagatla vout_ctl_1 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb1_mv);
30358d78602aSSrinivas Kandagatla vout_ctl_2 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb2_mv);
30368d78602aSSrinivas Kandagatla vout_ctl_3 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb3_mv);
30378d78602aSSrinivas Kandagatla vout_ctl_4 = wcd938x_get_micb_vout_ctl_val(wcd938x->micb4_mv);
30388d78602aSSrinivas Kandagatla if (vout_ctl_1 < 0 || vout_ctl_2 < 0 || vout_ctl_3 < 0 || vout_ctl_4 < 0)
30398d78602aSSrinivas Kandagatla return -EINVAL;
30408d78602aSSrinivas Kandagatla
30418d78602aSSrinivas Kandagatla regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB1,
30428d78602aSSrinivas Kandagatla WCD938X_MICB_VOUT_MASK, vout_ctl_1);
30438d78602aSSrinivas Kandagatla regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB2,
30448d78602aSSrinivas Kandagatla WCD938X_MICB_VOUT_MASK, vout_ctl_2);
30458d78602aSSrinivas Kandagatla regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB3,
30468d78602aSSrinivas Kandagatla WCD938X_MICB_VOUT_MASK, vout_ctl_3);
30478d78602aSSrinivas Kandagatla regmap_update_bits(wcd938x->regmap, WCD938X_ANA_MICB4,
30488d78602aSSrinivas Kandagatla WCD938X_MICB_VOUT_MASK, vout_ctl_4);
30498d78602aSSrinivas Kandagatla
30508d78602aSSrinivas Kandagatla return 0;
30518d78602aSSrinivas Kandagatla }
30528d78602aSSrinivas Kandagatla
wcd938x_wd_handle_irq(int irq,void * data)30538d78602aSSrinivas Kandagatla static irqreturn_t wcd938x_wd_handle_irq(int irq, void *data)
30548d78602aSSrinivas Kandagatla {
30558d78602aSSrinivas Kandagatla return IRQ_HANDLED;
30568d78602aSSrinivas Kandagatla }
30578d78602aSSrinivas Kandagatla
30588d78602aSSrinivas Kandagatla static struct irq_chip wcd_irq_chip = {
30598d78602aSSrinivas Kandagatla .name = "WCD938x",
30608d78602aSSrinivas Kandagatla };
30618d78602aSSrinivas Kandagatla
wcd_irq_chip_map(struct irq_domain * irqd,unsigned int virq,irq_hw_number_t hw)30628d78602aSSrinivas Kandagatla static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq,
30638d78602aSSrinivas Kandagatla irq_hw_number_t hw)
30648d78602aSSrinivas Kandagatla {
30658d78602aSSrinivas Kandagatla irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq);
30668d78602aSSrinivas Kandagatla irq_set_nested_thread(virq, 1);
30678d78602aSSrinivas Kandagatla irq_set_noprobe(virq);
30688d78602aSSrinivas Kandagatla
30698d78602aSSrinivas Kandagatla return 0;
30708d78602aSSrinivas Kandagatla }
30718d78602aSSrinivas Kandagatla
30728d78602aSSrinivas Kandagatla static const struct irq_domain_ops wcd_domain_ops = {
30738d78602aSSrinivas Kandagatla .map = wcd_irq_chip_map,
30748d78602aSSrinivas Kandagatla };
30758d78602aSSrinivas Kandagatla
wcd938x_irq_init(struct wcd938x_priv * wcd,struct device * dev)30768d78602aSSrinivas Kandagatla static int wcd938x_irq_init(struct wcd938x_priv *wcd, struct device *dev)
30778d78602aSSrinivas Kandagatla {
30788d78602aSSrinivas Kandagatla
30798d78602aSSrinivas Kandagatla wcd->virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL);
30808d78602aSSrinivas Kandagatla if (!(wcd->virq)) {
30818d78602aSSrinivas Kandagatla dev_err(dev, "%s: Failed to add IRQ domain\n", __func__);
30828d78602aSSrinivas Kandagatla return -EINVAL;
30838d78602aSSrinivas Kandagatla }
30848d78602aSSrinivas Kandagatla
30858d78602aSSrinivas Kandagatla return devm_regmap_add_irq_chip(dev, wcd->regmap,
30868d78602aSSrinivas Kandagatla irq_create_mapping(wcd->virq, 0),
30878d78602aSSrinivas Kandagatla IRQF_ONESHOT, 0, &wcd938x_regmap_irq_chip,
30888d78602aSSrinivas Kandagatla &wcd->irq_chip);
30898d78602aSSrinivas Kandagatla }
30908d78602aSSrinivas Kandagatla
wcd938x_soc_codec_probe(struct snd_soc_component * component)30918d78602aSSrinivas Kandagatla static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
30928d78602aSSrinivas Kandagatla {
30938d78602aSSrinivas Kandagatla struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
30946f492568SJohan Hovold struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev;
30958d78602aSSrinivas Kandagatla struct device *dev = component->dev;
30966f492568SJohan Hovold unsigned long time_left;
30978d78602aSSrinivas Kandagatla int ret, i;
30988d78602aSSrinivas Kandagatla
30996f492568SJohan Hovold time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete,
31006f492568SJohan Hovold msecs_to_jiffies(2000));
31016f492568SJohan Hovold if (!time_left) {
31026f492568SJohan Hovold dev_err(dev, "soundwire device init timeout\n");
31036f492568SJohan Hovold return -ETIMEDOUT;
31046f492568SJohan Hovold }
31056f492568SJohan Hovold
31068d78602aSSrinivas Kandagatla snd_soc_component_init_regmap(component, wcd938x->regmap);
31078d78602aSSrinivas Kandagatla
310885a61b1cSJohan Hovold ret = pm_runtime_resume_and_get(dev);
310985a61b1cSJohan Hovold if (ret < 0)
311085a61b1cSJohan Hovold return ret;
311185a61b1cSJohan Hovold
31128d78602aSSrinivas Kandagatla wcd938x->variant = snd_soc_component_read_field(component,
31138d78602aSSrinivas Kandagatla WCD938X_DIGITAL_EFUSE_REG_0,
31148d78602aSSrinivas Kandagatla WCD938X_ID_MASK);
31158d78602aSSrinivas Kandagatla
31168d78602aSSrinivas Kandagatla wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X);
3117ed0dd920SJohan Hovold if (IS_ERR(wcd938x->clsh_info)) {
3118ed0dd920SJohan Hovold pm_runtime_put(dev);
3119ed0dd920SJohan Hovold return PTR_ERR(wcd938x->clsh_info);
3120ed0dd920SJohan Hovold }
31218d78602aSSrinivas Kandagatla
31228d78602aSSrinivas Kandagatla wcd938x_io_init(wcd938x);
31238d78602aSSrinivas Kandagatla /* Set all interrupts as edge triggered */
31248d78602aSSrinivas Kandagatla for (i = 0; i < wcd938x_regmap_irq_chip.num_regs; i++) {
31258d78602aSSrinivas Kandagatla regmap_write(wcd938x->regmap,
31268d78602aSSrinivas Kandagatla (WCD938X_DIGITAL_INTR_LEVEL_0 + i), 0);
31278d78602aSSrinivas Kandagatla }
31288d78602aSSrinivas Kandagatla
312985a61b1cSJohan Hovold pm_runtime_put(dev);
313085a61b1cSJohan Hovold
31318d78602aSSrinivas Kandagatla wcd938x->hphr_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
31328d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHR_PDM_WD_INT);
31338d78602aSSrinivas Kandagatla wcd938x->hphl_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
31348d78602aSSrinivas Kandagatla WCD938X_IRQ_HPHL_PDM_WD_INT);
31358d78602aSSrinivas Kandagatla wcd938x->aux_pdm_wd_int = regmap_irq_get_virq(wcd938x->irq_chip,
31368d78602aSSrinivas Kandagatla WCD938X_IRQ_AUX_PDM_WD_INT);
31378d78602aSSrinivas Kandagatla
31388d78602aSSrinivas Kandagatla /* Request for watchdog interrupt */
31398d78602aSSrinivas Kandagatla ret = request_threaded_irq(wcd938x->hphr_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
31408d78602aSSrinivas Kandagatla IRQF_ONESHOT | IRQF_TRIGGER_RISING,
31418d78602aSSrinivas Kandagatla "HPHR PDM WD INT", wcd938x);
3142a3406f87SJohan Hovold if (ret) {
31438d78602aSSrinivas Kandagatla dev_err(dev, "Failed to request HPHR WD interrupt (%d)\n", ret);
3144a3406f87SJohan Hovold goto err_free_clsh_ctrl;
3145a3406f87SJohan Hovold }
31468d78602aSSrinivas Kandagatla
31478d78602aSSrinivas Kandagatla ret = request_threaded_irq(wcd938x->hphl_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
31488d78602aSSrinivas Kandagatla IRQF_ONESHOT | IRQF_TRIGGER_RISING,
31498d78602aSSrinivas Kandagatla "HPHL PDM WD INT", wcd938x);
3150a3406f87SJohan Hovold if (ret) {
31518d78602aSSrinivas Kandagatla dev_err(dev, "Failed to request HPHL WD interrupt (%d)\n", ret);
3152a3406f87SJohan Hovold goto err_free_hphr_pdm_wd_int;
3153a3406f87SJohan Hovold }
31548d78602aSSrinivas Kandagatla
31558d78602aSSrinivas Kandagatla ret = request_threaded_irq(wcd938x->aux_pdm_wd_int, NULL, wcd938x_wd_handle_irq,
31568d78602aSSrinivas Kandagatla IRQF_ONESHOT | IRQF_TRIGGER_RISING,
31578d78602aSSrinivas Kandagatla "AUX PDM WD INT", wcd938x);
3158a3406f87SJohan Hovold if (ret) {
31598d78602aSSrinivas Kandagatla dev_err(dev, "Failed to request Aux WD interrupt (%d)\n", ret);
3160a3406f87SJohan Hovold goto err_free_hphl_pdm_wd_int;
3161a3406f87SJohan Hovold }
31628d78602aSSrinivas Kandagatla
31638d78602aSSrinivas Kandagatla /* Disable watchdog interrupt for HPH and AUX */
31648d78602aSSrinivas Kandagatla disable_irq_nosync(wcd938x->hphr_pdm_wd_int);
31658d78602aSSrinivas Kandagatla disable_irq_nosync(wcd938x->hphl_pdm_wd_int);
31668d78602aSSrinivas Kandagatla disable_irq_nosync(wcd938x->aux_pdm_wd_int);
31678d78602aSSrinivas Kandagatla
3168e8ba1e05SSrinivas Kandagatla switch (wcd938x->variant) {
3169e8ba1e05SSrinivas Kandagatla case WCD9380:
3170e8ba1e05SSrinivas Kandagatla ret = snd_soc_add_component_controls(component, wcd9380_snd_controls,
3171e8ba1e05SSrinivas Kandagatla ARRAY_SIZE(wcd9380_snd_controls));
3172e8ba1e05SSrinivas Kandagatla if (ret < 0) {
3173e8ba1e05SSrinivas Kandagatla dev_err(component->dev,
3174e8ba1e05SSrinivas Kandagatla "%s: Failed to add snd ctrls for variant: %d\n",
3175e8ba1e05SSrinivas Kandagatla __func__, wcd938x->variant);
3176a3406f87SJohan Hovold goto err_free_aux_pdm_wd_int;
3177e8ba1e05SSrinivas Kandagatla }
3178e8ba1e05SSrinivas Kandagatla break;
3179e8ba1e05SSrinivas Kandagatla case WCD9385:
3180e8ba1e05SSrinivas Kandagatla ret = snd_soc_add_component_controls(component, wcd9385_snd_controls,
3181e8ba1e05SSrinivas Kandagatla ARRAY_SIZE(wcd9385_snd_controls));
3182e8ba1e05SSrinivas Kandagatla if (ret < 0) {
3183e8ba1e05SSrinivas Kandagatla dev_err(component->dev,
3184e8ba1e05SSrinivas Kandagatla "%s: Failed to add snd ctrls for variant: %d\n",
3185e8ba1e05SSrinivas Kandagatla __func__, wcd938x->variant);
3186a3406f87SJohan Hovold goto err_free_aux_pdm_wd_int;
3187e8ba1e05SSrinivas Kandagatla }
3188e8ba1e05SSrinivas Kandagatla break;
3189e8ba1e05SSrinivas Kandagatla default:
3190e8ba1e05SSrinivas Kandagatla break;
3191e8ba1e05SSrinivas Kandagatla }
3192bcee7ed0SSrinivas Kandagatla
3193bcee7ed0SSrinivas Kandagatla ret = wcd938x_mbhc_init(component);
3194a3406f87SJohan Hovold if (ret) {
3195bcee7ed0SSrinivas Kandagatla dev_err(component->dev, "mbhc initialization failed\n");
3196a3406f87SJohan Hovold goto err_free_aux_pdm_wd_int;
3197a3406f87SJohan Hovold }
3198a3406f87SJohan Hovold
3199a3406f87SJohan Hovold return 0;
3200a3406f87SJohan Hovold
3201a3406f87SJohan Hovold err_free_aux_pdm_wd_int:
3202a3406f87SJohan Hovold free_irq(wcd938x->aux_pdm_wd_int, wcd938x);
3203a3406f87SJohan Hovold err_free_hphl_pdm_wd_int:
3204a3406f87SJohan Hovold free_irq(wcd938x->hphl_pdm_wd_int, wcd938x);
3205a3406f87SJohan Hovold err_free_hphr_pdm_wd_int:
3206a3406f87SJohan Hovold free_irq(wcd938x->hphr_pdm_wd_int, wcd938x);
3207a3406f87SJohan Hovold err_free_clsh_ctrl:
3208a3406f87SJohan Hovold wcd_clsh_ctrl_free(wcd938x->clsh_info);
3209a3406f87SJohan Hovold
32108d78602aSSrinivas Kandagatla return ret;
32118d78602aSSrinivas Kandagatla }
32128d78602aSSrinivas Kandagatla
wcd938x_soc_codec_remove(struct snd_soc_component * component)3213a3406f87SJohan Hovold static void wcd938x_soc_codec_remove(struct snd_soc_component *component)
3214a3406f87SJohan Hovold {
3215a3406f87SJohan Hovold struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
3216a3406f87SJohan Hovold
3217a3406f87SJohan Hovold wcd938x_mbhc_deinit(component);
3218a3406f87SJohan Hovold
3219a3406f87SJohan Hovold free_irq(wcd938x->aux_pdm_wd_int, wcd938x);
3220a3406f87SJohan Hovold free_irq(wcd938x->hphl_pdm_wd_int, wcd938x);
3221a3406f87SJohan Hovold free_irq(wcd938x->hphr_pdm_wd_int, wcd938x);
3222a3406f87SJohan Hovold
3223a3406f87SJohan Hovold wcd_clsh_ctrl_free(wcd938x->clsh_info);
3224a3406f87SJohan Hovold }
3225a3406f87SJohan Hovold
wcd938x_codec_set_jack(struct snd_soc_component * comp,struct snd_soc_jack * jack,void * data)3226bcee7ed0SSrinivas Kandagatla static int wcd938x_codec_set_jack(struct snd_soc_component *comp,
3227bcee7ed0SSrinivas Kandagatla struct snd_soc_jack *jack, void *data)
3228bcee7ed0SSrinivas Kandagatla {
3229bcee7ed0SSrinivas Kandagatla struct wcd938x_priv *wcd = dev_get_drvdata(comp->dev);
3230bcee7ed0SSrinivas Kandagatla
3231db0767b8SSrinivasa Rao Mandadapu if (jack)
3232bcee7ed0SSrinivas Kandagatla return wcd_mbhc_start(wcd->wcd_mbhc, &wcd->mbhc_cfg, jack);
3233db0767b8SSrinivasa Rao Mandadapu else
3234bcee7ed0SSrinivas Kandagatla wcd_mbhc_stop(wcd->wcd_mbhc);
3235bcee7ed0SSrinivas Kandagatla
3236bcee7ed0SSrinivas Kandagatla return 0;
3237bcee7ed0SSrinivas Kandagatla }
3238bcee7ed0SSrinivas Kandagatla
32398d78602aSSrinivas Kandagatla static const struct snd_soc_component_driver soc_codec_dev_wcd938x = {
32408d78602aSSrinivas Kandagatla .name = "wcd938x_codec",
32418d78602aSSrinivas Kandagatla .probe = wcd938x_soc_codec_probe,
3242a3406f87SJohan Hovold .remove = wcd938x_soc_codec_remove,
3243e8ba1e05SSrinivas Kandagatla .controls = wcd938x_snd_controls,
3244e8ba1e05SSrinivas Kandagatla .num_controls = ARRAY_SIZE(wcd938x_snd_controls),
32458da9db0cSSrinivas Kandagatla .dapm_widgets = wcd938x_dapm_widgets,
32468da9db0cSSrinivas Kandagatla .num_dapm_widgets = ARRAY_SIZE(wcd938x_dapm_widgets),
324704544222SSrinivas Kandagatla .dapm_routes = wcd938x_audio_map,
324804544222SSrinivas Kandagatla .num_dapm_routes = ARRAY_SIZE(wcd938x_audio_map),
3249bcee7ed0SSrinivas Kandagatla .set_jack = wcd938x_codec_set_jack,
3250ff7f9aa5SCharles Keepax .endianness = 1,
32518d78602aSSrinivas Kandagatla };
32528d78602aSSrinivas Kandagatla
wcd938x_dt_parse_micbias_info(struct device * dev,struct wcd938x_priv * wcd)32538d78602aSSrinivas Kandagatla static void wcd938x_dt_parse_micbias_info(struct device *dev, struct wcd938x_priv *wcd)
32548d78602aSSrinivas Kandagatla {
32558d78602aSSrinivas Kandagatla struct device_node *np = dev->of_node;
32568d78602aSSrinivas Kandagatla u32 prop_val = 0;
32578d78602aSSrinivas Kandagatla int rc = 0;
32588d78602aSSrinivas Kandagatla
32598d78602aSSrinivas Kandagatla rc = of_property_read_u32(np, "qcom,micbias1-microvolt", &prop_val);
32608d78602aSSrinivas Kandagatla if (!rc)
32618d78602aSSrinivas Kandagatla wcd->micb1_mv = prop_val/1000;
32628d78602aSSrinivas Kandagatla else
32638d78602aSSrinivas Kandagatla dev_info(dev, "%s: Micbias1 DT property not found\n", __func__);
32648d78602aSSrinivas Kandagatla
32658d78602aSSrinivas Kandagatla rc = of_property_read_u32(np, "qcom,micbias2-microvolt", &prop_val);
32668d78602aSSrinivas Kandagatla if (!rc)
32678d78602aSSrinivas Kandagatla wcd->micb2_mv = prop_val/1000;
32688d78602aSSrinivas Kandagatla else
32698d78602aSSrinivas Kandagatla dev_info(dev, "%s: Micbias2 DT property not found\n", __func__);
32708d78602aSSrinivas Kandagatla
32718d78602aSSrinivas Kandagatla rc = of_property_read_u32(np, "qcom,micbias3-microvolt", &prop_val);
32728d78602aSSrinivas Kandagatla if (!rc)
32738d78602aSSrinivas Kandagatla wcd->micb3_mv = prop_val/1000;
32748d78602aSSrinivas Kandagatla else
32758d78602aSSrinivas Kandagatla dev_info(dev, "%s: Micbias3 DT property not found\n", __func__);
32768d78602aSSrinivas Kandagatla
32778d78602aSSrinivas Kandagatla rc = of_property_read_u32(np, "qcom,micbias4-microvolt", &prop_val);
32788d78602aSSrinivas Kandagatla if (!rc)
32798d78602aSSrinivas Kandagatla wcd->micb4_mv = prop_val/1000;
32808d78602aSSrinivas Kandagatla else
32818d78602aSSrinivas Kandagatla dev_info(dev, "%s: Micbias4 DT property not found\n", __func__);
32828d78602aSSrinivas Kandagatla }
32838d78602aSSrinivas Kandagatla
wcd938x_swap_gnd_mic(struct snd_soc_component * component,bool active)3284013cc2aeSSrinivasa Rao Mandadapu static bool wcd938x_swap_gnd_mic(struct snd_soc_component *component, bool active)
3285013cc2aeSSrinivasa Rao Mandadapu {
3286013cc2aeSSrinivasa Rao Mandadapu int value;
3287013cc2aeSSrinivasa Rao Mandadapu
3288013cc2aeSSrinivasa Rao Mandadapu struct wcd938x_priv *wcd938x;
3289013cc2aeSSrinivasa Rao Mandadapu
3290013cc2aeSSrinivasa Rao Mandadapu wcd938x = snd_soc_component_get_drvdata(component);
3291013cc2aeSSrinivasa Rao Mandadapu
3292db0b4aedSSrinivasa Rao Mandadapu value = gpiod_get_value(wcd938x->us_euro_gpio);
3293013cc2aeSSrinivasa Rao Mandadapu
3294db0b4aedSSrinivasa Rao Mandadapu gpiod_set_value(wcd938x->us_euro_gpio, !value);
3295013cc2aeSSrinivasa Rao Mandadapu
3296013cc2aeSSrinivasa Rao Mandadapu return true;
3297013cc2aeSSrinivasa Rao Mandadapu }
3298013cc2aeSSrinivasa Rao Mandadapu
3299013cc2aeSSrinivasa Rao Mandadapu
wcd938x_populate_dt_data(struct wcd938x_priv * wcd938x,struct device * dev)33008d78602aSSrinivas Kandagatla static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device *dev)
33018d78602aSSrinivas Kandagatla {
3302bcee7ed0SSrinivas Kandagatla struct wcd_mbhc_config *cfg = &wcd938x->mbhc_cfg;
33038d78602aSSrinivas Kandagatla int ret;
33048d78602aSSrinivas Kandagatla
33058d78602aSSrinivas Kandagatla wcd938x->reset_gpio = of_get_named_gpio(dev->of_node, "reset-gpios", 0);
330660ba2fdaSKrzysztof Kozlowski if (wcd938x->reset_gpio < 0)
330760ba2fdaSKrzysztof Kozlowski return dev_err_probe(dev, wcd938x->reset_gpio,
330860ba2fdaSKrzysztof Kozlowski "Failed to get reset gpio\n");
33098d78602aSSrinivas Kandagatla
3310db0b4aedSSrinivasa Rao Mandadapu wcd938x->us_euro_gpio = devm_gpiod_get_optional(dev, "us-euro",
3311db0b4aedSSrinivasa Rao Mandadapu GPIOD_OUT_LOW);
331260ba2fdaSKrzysztof Kozlowski if (IS_ERR(wcd938x->us_euro_gpio))
331360ba2fdaSKrzysztof Kozlowski return dev_err_probe(dev, PTR_ERR(wcd938x->us_euro_gpio),
331460ba2fdaSKrzysztof Kozlowski "us-euro swap Control GPIO not found\n");
3315013cc2aeSSrinivasa Rao Mandadapu
3316db0b4aedSSrinivasa Rao Mandadapu cfg->swap_gnd_mic = wcd938x_swap_gnd_mic;
3317db0b4aedSSrinivasa Rao Mandadapu
33188d78602aSSrinivas Kandagatla wcd938x->supplies[0].supply = "vdd-rxtx";
33198d78602aSSrinivas Kandagatla wcd938x->supplies[1].supply = "vdd-io";
33208d78602aSSrinivas Kandagatla wcd938x->supplies[2].supply = "vdd-buck";
33218d78602aSSrinivas Kandagatla wcd938x->supplies[3].supply = "vdd-mic-bias";
33228d78602aSSrinivas Kandagatla
33238d78602aSSrinivas Kandagatla ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies);
332460ba2fdaSKrzysztof Kozlowski if (ret)
332560ba2fdaSKrzysztof Kozlowski return dev_err_probe(dev, ret, "Failed to get supplies\n");
33268d78602aSSrinivas Kandagatla
33278d78602aSSrinivas Kandagatla ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
332869a026a2SJohan Hovold if (ret) {
332969a026a2SJohan Hovold regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
333060ba2fdaSKrzysztof Kozlowski return dev_err_probe(dev, ret, "Failed to enable supplies\n");
333169a026a2SJohan Hovold }
33328d78602aSSrinivas Kandagatla
33338d78602aSSrinivas Kandagatla wcd938x_dt_parse_micbias_info(dev, wcd938x);
33348d78602aSSrinivas Kandagatla
3335bcee7ed0SSrinivas Kandagatla cfg->mbhc_micbias = MIC_BIAS_2;
3336bcee7ed0SSrinivas Kandagatla cfg->anc_micbias = MIC_BIAS_2;
3337bcee7ed0SSrinivas Kandagatla cfg->v_hs_max = WCD_MBHC_HS_V_MAX;
3338bcee7ed0SSrinivas Kandagatla cfg->num_btn = WCD938X_MBHC_MAX_BUTTONS;
3339bcee7ed0SSrinivas Kandagatla cfg->micb_mv = wcd938x->micb2_mv;
3340bcee7ed0SSrinivas Kandagatla cfg->linein_th = 5000;
3341bcee7ed0SSrinivas Kandagatla cfg->hs_thr = 1700;
3342bcee7ed0SSrinivas Kandagatla cfg->hph_thr = 50;
3343bcee7ed0SSrinivas Kandagatla
3344bcee7ed0SSrinivas Kandagatla wcd_dt_parse_mbhc_data(dev, cfg);
3345bcee7ed0SSrinivas Kandagatla
33468d78602aSSrinivas Kandagatla return 0;
33478d78602aSSrinivas Kandagatla }
33488d78602aSSrinivas Kandagatla
wcd938x_reset(struct wcd938x_priv * wcd938x)33498d78602aSSrinivas Kandagatla static int wcd938x_reset(struct wcd938x_priv *wcd938x)
33508d78602aSSrinivas Kandagatla {
33518d78602aSSrinivas Kandagatla gpio_direction_output(wcd938x->reset_gpio, 0);
33528d78602aSSrinivas Kandagatla /* 20us sleep required after pulling the reset gpio to LOW */
33538d78602aSSrinivas Kandagatla usleep_range(20, 30);
33548d78602aSSrinivas Kandagatla gpio_set_value(wcd938x->reset_gpio, 1);
33558d78602aSSrinivas Kandagatla /* 20us sleep required after pulling the reset gpio to HIGH */
33568d78602aSSrinivas Kandagatla usleep_range(20, 30);
33578d78602aSSrinivas Kandagatla
33588d78602aSSrinivas Kandagatla return 0;
33598d78602aSSrinivas Kandagatla }
33608d78602aSSrinivas Kandagatla
wcd938x_codec_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)336116572522SSrinivas Kandagatla static int wcd938x_codec_hw_params(struct snd_pcm_substream *substream,
336216572522SSrinivas Kandagatla struct snd_pcm_hw_params *params,
336316572522SSrinivas Kandagatla struct snd_soc_dai *dai)
336416572522SSrinivas Kandagatla {
336516572522SSrinivas Kandagatla struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
336616572522SSrinivas Kandagatla struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
336716572522SSrinivas Kandagatla
336816572522SSrinivas Kandagatla return wcd938x_sdw_hw_params(wcd, substream, params, dai);
336916572522SSrinivas Kandagatla }
337016572522SSrinivas Kandagatla
wcd938x_codec_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)337116572522SSrinivas Kandagatla static int wcd938x_codec_free(struct snd_pcm_substream *substream,
337216572522SSrinivas Kandagatla struct snd_soc_dai *dai)
337316572522SSrinivas Kandagatla {
337416572522SSrinivas Kandagatla struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
337516572522SSrinivas Kandagatla struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
337616572522SSrinivas Kandagatla
337716572522SSrinivas Kandagatla return wcd938x_sdw_free(wcd, substream, dai);
337816572522SSrinivas Kandagatla }
337916572522SSrinivas Kandagatla
wcd938x_codec_set_sdw_stream(struct snd_soc_dai * dai,void * stream,int direction)338016572522SSrinivas Kandagatla static int wcd938x_codec_set_sdw_stream(struct snd_soc_dai *dai,
338116572522SSrinivas Kandagatla void *stream, int direction)
338216572522SSrinivas Kandagatla {
338316572522SSrinivas Kandagatla struct wcd938x_priv *wcd938x = dev_get_drvdata(dai->dev);
338416572522SSrinivas Kandagatla struct wcd938x_sdw_priv *wcd = wcd938x->sdw_priv[dai->id];
338516572522SSrinivas Kandagatla
338616572522SSrinivas Kandagatla return wcd938x_sdw_set_sdw_stream(wcd, dai, stream, direction);
338716572522SSrinivas Kandagatla
338816572522SSrinivas Kandagatla }
338916572522SSrinivas Kandagatla
3390355af6c0SPu Lehui static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = {
339116572522SSrinivas Kandagatla .hw_params = wcd938x_codec_hw_params,
339216572522SSrinivas Kandagatla .hw_free = wcd938x_codec_free,
3393e8444560SPierre-Louis Bossart .set_stream = wcd938x_codec_set_sdw_stream,
33948d78602aSSrinivas Kandagatla };
33958d78602aSSrinivas Kandagatla
33968d78602aSSrinivas Kandagatla static struct snd_soc_dai_driver wcd938x_dais[] = {
33978d78602aSSrinivas Kandagatla [0] = {
33988d78602aSSrinivas Kandagatla .name = "wcd938x-sdw-rx",
33998d78602aSSrinivas Kandagatla .playback = {
34008d78602aSSrinivas Kandagatla .stream_name = "WCD AIF1 Playback",
34018d78602aSSrinivas Kandagatla .rates = WCD938X_RATES_MASK | WCD938X_FRAC_RATES_MASK,
34028d78602aSSrinivas Kandagatla .formats = WCD938X_FORMATS_S16_S24_LE,
34038d78602aSSrinivas Kandagatla .rate_max = 192000,
34048d78602aSSrinivas Kandagatla .rate_min = 8000,
34058d78602aSSrinivas Kandagatla .channels_min = 1,
34068d78602aSSrinivas Kandagatla .channels_max = 2,
34078d78602aSSrinivas Kandagatla },
34088d78602aSSrinivas Kandagatla .ops = &wcd938x_sdw_dai_ops,
34098d78602aSSrinivas Kandagatla },
34108d78602aSSrinivas Kandagatla [1] = {
34118d78602aSSrinivas Kandagatla .name = "wcd938x-sdw-tx",
34128d78602aSSrinivas Kandagatla .capture = {
34138d78602aSSrinivas Kandagatla .stream_name = "WCD AIF1 Capture",
34148d78602aSSrinivas Kandagatla .rates = WCD938X_RATES_MASK,
34158d78602aSSrinivas Kandagatla .formats = SNDRV_PCM_FMTBIT_S16_LE,
34168d78602aSSrinivas Kandagatla .rate_min = 8000,
34178d78602aSSrinivas Kandagatla .rate_max = 192000,
34188d78602aSSrinivas Kandagatla .channels_min = 1,
34198d78602aSSrinivas Kandagatla .channels_max = 4,
34208d78602aSSrinivas Kandagatla },
34218d78602aSSrinivas Kandagatla .ops = &wcd938x_sdw_dai_ops,
34228d78602aSSrinivas Kandagatla },
34238d78602aSSrinivas Kandagatla };
34248d78602aSSrinivas Kandagatla
wcd938x_bind(struct device * dev)34258d78602aSSrinivas Kandagatla static int wcd938x_bind(struct device *dev)
34268d78602aSSrinivas Kandagatla {
34278d78602aSSrinivas Kandagatla struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
34288d78602aSSrinivas Kandagatla int ret;
34298d78602aSSrinivas Kandagatla
34308d78602aSSrinivas Kandagatla ret = component_bind_all(dev, wcd938x);
34318d78602aSSrinivas Kandagatla if (ret) {
34328d78602aSSrinivas Kandagatla dev_err(dev, "%s: Slave bind failed, ret = %d\n",
34338d78602aSSrinivas Kandagatla __func__, ret);
34348d78602aSSrinivas Kandagatla return ret;
34358d78602aSSrinivas Kandagatla }
34368d78602aSSrinivas Kandagatla
343716572522SSrinivas Kandagatla wcd938x->rxdev = wcd938x_sdw_device_get(wcd938x->rxnode);
343816572522SSrinivas Kandagatla if (!wcd938x->rxdev) {
343916572522SSrinivas Kandagatla dev_err(dev, "could not find slave with matching of node\n");
3440da29b94eSJohan Hovold ret = -EINVAL;
3441da29b94eSJohan Hovold goto err_unbind;
344216572522SSrinivas Kandagatla }
344316572522SSrinivas Kandagatla wcd938x->sdw_priv[AIF1_PB] = dev_get_drvdata(wcd938x->rxdev);
344416572522SSrinivas Kandagatla wcd938x->sdw_priv[AIF1_PB]->wcd938x = wcd938x;
344516572522SSrinivas Kandagatla
344616572522SSrinivas Kandagatla wcd938x->txdev = wcd938x_sdw_device_get(wcd938x->txnode);
344716572522SSrinivas Kandagatla if (!wcd938x->txdev) {
344816572522SSrinivas Kandagatla dev_err(dev, "could not find txslave with matching of node\n");
3449da29b94eSJohan Hovold ret = -EINVAL;
3450da29b94eSJohan Hovold goto err_put_rxdev;
345116572522SSrinivas Kandagatla }
345216572522SSrinivas Kandagatla wcd938x->sdw_priv[AIF1_CAP] = dev_get_drvdata(wcd938x->txdev);
345316572522SSrinivas Kandagatla wcd938x->sdw_priv[AIF1_CAP]->wcd938x = wcd938x;
345416572522SSrinivas Kandagatla wcd938x->tx_sdw_dev = dev_to_sdw_dev(wcd938x->txdev);
345516572522SSrinivas Kandagatla
345616572522SSrinivas Kandagatla /* As TX is main CSR reg interface, which should not be suspended first.
345716572522SSrinivas Kandagatla * expicilty add the dependency link */
345816572522SSrinivas Kandagatla if (!device_link_add(wcd938x->rxdev, wcd938x->txdev, DL_FLAG_STATELESS |
345916572522SSrinivas Kandagatla DL_FLAG_PM_RUNTIME)) {
346016572522SSrinivas Kandagatla dev_err(dev, "could not devlink tx and rx\n");
3461da29b94eSJohan Hovold ret = -EINVAL;
3462da29b94eSJohan Hovold goto err_put_txdev;
346316572522SSrinivas Kandagatla }
346416572522SSrinivas Kandagatla
346516572522SSrinivas Kandagatla if (!device_link_add(dev, wcd938x->txdev, DL_FLAG_STATELESS |
346616572522SSrinivas Kandagatla DL_FLAG_PM_RUNTIME)) {
346716572522SSrinivas Kandagatla dev_err(dev, "could not devlink wcd and tx\n");
3468da29b94eSJohan Hovold ret = -EINVAL;
3469da29b94eSJohan Hovold goto err_remove_rxtx_link;
347016572522SSrinivas Kandagatla }
347116572522SSrinivas Kandagatla
347216572522SSrinivas Kandagatla if (!device_link_add(dev, wcd938x->rxdev, DL_FLAG_STATELESS |
347316572522SSrinivas Kandagatla DL_FLAG_PM_RUNTIME)) {
347416572522SSrinivas Kandagatla dev_err(dev, "could not devlink wcd and rx\n");
3475da29b94eSJohan Hovold ret = -EINVAL;
3476da29b94eSJohan Hovold goto err_remove_tx_link;
347716572522SSrinivas Kandagatla }
347816572522SSrinivas Kandagatla
347984822215SKrzysztof Kozlowski wcd938x->regmap = dev_get_regmap(&wcd938x->tx_sdw_dev->dev, NULL);
348084822215SKrzysztof Kozlowski if (!wcd938x->regmap) {
348184822215SKrzysztof Kozlowski dev_err(dev, "could not get TX device regmap\n");
3482da29b94eSJohan Hovold ret = -EINVAL;
3483da29b94eSJohan Hovold goto err_remove_rx_link;
348416572522SSrinivas Kandagatla }
348516572522SSrinivas Kandagatla
3486f99986c0SSrinivas Kandagatla ret = wcd938x_irq_init(wcd938x, dev);
3487f99986c0SSrinivas Kandagatla if (ret) {
3488f99986c0SSrinivas Kandagatla dev_err(dev, "%s: IRQ init failed: %d\n", __func__, ret);
3489da29b94eSJohan Hovold goto err_remove_rx_link;
3490f99986c0SSrinivas Kandagatla }
3491f99986c0SSrinivas Kandagatla
3492f99986c0SSrinivas Kandagatla wcd938x->sdw_priv[AIF1_PB]->slave_irq = wcd938x->virq;
3493f99986c0SSrinivas Kandagatla wcd938x->sdw_priv[AIF1_CAP]->slave_irq = wcd938x->virq;
3494f99986c0SSrinivas Kandagatla
34958d78602aSSrinivas Kandagatla ret = wcd938x_set_micbias_data(wcd938x);
34968d78602aSSrinivas Kandagatla if (ret < 0) {
34978d78602aSSrinivas Kandagatla dev_err(dev, "%s: bad micbias pdata\n", __func__);
3498da29b94eSJohan Hovold goto err_remove_rx_link;
34998d78602aSSrinivas Kandagatla }
35008d78602aSSrinivas Kandagatla
35018d78602aSSrinivas Kandagatla ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
35028d78602aSSrinivas Kandagatla wcd938x_dais, ARRAY_SIZE(wcd938x_dais));
3503da29b94eSJohan Hovold if (ret) {
35048d78602aSSrinivas Kandagatla dev_err(dev, "%s: Codec registration failed\n",
35058d78602aSSrinivas Kandagatla __func__);
3506da29b94eSJohan Hovold goto err_remove_rx_link;
3507da29b94eSJohan Hovold }
3508da29b94eSJohan Hovold
3509da29b94eSJohan Hovold return 0;
3510da29b94eSJohan Hovold
3511da29b94eSJohan Hovold err_remove_rx_link:
3512da29b94eSJohan Hovold device_link_remove(dev, wcd938x->rxdev);
3513da29b94eSJohan Hovold err_remove_tx_link:
3514da29b94eSJohan Hovold device_link_remove(dev, wcd938x->txdev);
3515da29b94eSJohan Hovold err_remove_rxtx_link:
3516da29b94eSJohan Hovold device_link_remove(wcd938x->rxdev, wcd938x->txdev);
3517da29b94eSJohan Hovold err_put_txdev:
3518da29b94eSJohan Hovold put_device(wcd938x->txdev);
3519da29b94eSJohan Hovold err_put_rxdev:
3520da29b94eSJohan Hovold put_device(wcd938x->rxdev);
3521da29b94eSJohan Hovold err_unbind:
3522da29b94eSJohan Hovold component_unbind_all(dev, wcd938x);
35238d78602aSSrinivas Kandagatla
35248d78602aSSrinivas Kandagatla return ret;
35258d78602aSSrinivas Kandagatla }
35268d78602aSSrinivas Kandagatla
wcd938x_unbind(struct device * dev)35278d78602aSSrinivas Kandagatla static void wcd938x_unbind(struct device *dev)
35288d78602aSSrinivas Kandagatla {
35298d78602aSSrinivas Kandagatla struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
35308d78602aSSrinivas Kandagatla
3531fa2f8a99SJohan Hovold snd_soc_unregister_component(dev);
353216572522SSrinivas Kandagatla device_link_remove(dev, wcd938x->txdev);
353316572522SSrinivas Kandagatla device_link_remove(dev, wcd938x->rxdev);
353416572522SSrinivas Kandagatla device_link_remove(wcd938x->rxdev, wcd938x->txdev);
3535da29b94eSJohan Hovold put_device(wcd938x->txdev);
3536da29b94eSJohan Hovold put_device(wcd938x->rxdev);
35378d78602aSSrinivas Kandagatla component_unbind_all(dev, wcd938x);
35388d78602aSSrinivas Kandagatla }
35398d78602aSSrinivas Kandagatla
35408d78602aSSrinivas Kandagatla static const struct component_master_ops wcd938x_comp_ops = {
35418d78602aSSrinivas Kandagatla .bind = wcd938x_bind,
35428d78602aSSrinivas Kandagatla .unbind = wcd938x_unbind,
35438d78602aSSrinivas Kandagatla };
35448d78602aSSrinivas Kandagatla
wcd938x_add_slave_components(struct wcd938x_priv * wcd938x,struct device * dev,struct component_match ** matchptr)35458d78602aSSrinivas Kandagatla static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
35468d78602aSSrinivas Kandagatla struct device *dev,
35478d78602aSSrinivas Kandagatla struct component_match **matchptr)
35488d78602aSSrinivas Kandagatla {
35498d78602aSSrinivas Kandagatla struct device_node *np;
35508d78602aSSrinivas Kandagatla
35518d78602aSSrinivas Kandagatla np = dev->of_node;
35528d78602aSSrinivas Kandagatla
35538d78602aSSrinivas Kandagatla wcd938x->rxnode = of_parse_phandle(np, "qcom,rx-device", 0);
35548d78602aSSrinivas Kandagatla if (!wcd938x->rxnode) {
35558d78602aSSrinivas Kandagatla dev_err(dev, "%s: Rx-device node not defined\n", __func__);
35568d78602aSSrinivas Kandagatla return -ENODEV;
35578d78602aSSrinivas Kandagatla }
35588d78602aSSrinivas Kandagatla
35598d78602aSSrinivas Kandagatla of_node_get(wcd938x->rxnode);
3560a8271d7eSYong Wu component_match_add_release(dev, matchptr, component_release_of,
3561a8271d7eSYong Wu component_compare_of, wcd938x->rxnode);
35628d78602aSSrinivas Kandagatla
35638d78602aSSrinivas Kandagatla wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
35648d78602aSSrinivas Kandagatla if (!wcd938x->txnode) {
35658d78602aSSrinivas Kandagatla dev_err(dev, "%s: Tx-device node not defined\n", __func__);
35668d78602aSSrinivas Kandagatla return -ENODEV;
35678d78602aSSrinivas Kandagatla }
35688d78602aSSrinivas Kandagatla of_node_get(wcd938x->txnode);
3569a8271d7eSYong Wu component_match_add_release(dev, matchptr, component_release_of,
3570a8271d7eSYong Wu component_compare_of, wcd938x->txnode);
35718d78602aSSrinivas Kandagatla return 0;
35728d78602aSSrinivas Kandagatla }
35738d78602aSSrinivas Kandagatla
wcd938x_probe(struct platform_device * pdev)35748d78602aSSrinivas Kandagatla static int wcd938x_probe(struct platform_device *pdev)
35758d78602aSSrinivas Kandagatla {
35768d78602aSSrinivas Kandagatla struct component_match *match = NULL;
35778d78602aSSrinivas Kandagatla struct wcd938x_priv *wcd938x = NULL;
35788d78602aSSrinivas Kandagatla struct device *dev = &pdev->dev;
35798d78602aSSrinivas Kandagatla int ret;
35808d78602aSSrinivas Kandagatla
35818d78602aSSrinivas Kandagatla wcd938x = devm_kzalloc(dev, sizeof(struct wcd938x_priv),
35828d78602aSSrinivas Kandagatla GFP_KERNEL);
35838d78602aSSrinivas Kandagatla if (!wcd938x)
35848d78602aSSrinivas Kandagatla return -ENOMEM;
35858d78602aSSrinivas Kandagatla
35868d78602aSSrinivas Kandagatla dev_set_drvdata(dev, wcd938x);
3587bcee7ed0SSrinivas Kandagatla mutex_init(&wcd938x->micb_lock);
35888d78602aSSrinivas Kandagatla
35898d78602aSSrinivas Kandagatla ret = wcd938x_populate_dt_data(wcd938x, dev);
35908d78602aSSrinivas Kandagatla if (ret) {
35918d78602aSSrinivas Kandagatla dev_err(dev, "%s: Fail to obtain platform data\n", __func__);
3592*4629bf52SKrzysztof Kozlowski return ret;
35938d78602aSSrinivas Kandagatla }
35948d78602aSSrinivas Kandagatla
35958d78602aSSrinivas Kandagatla ret = wcd938x_add_slave_components(wcd938x, dev, &match);
35968d78602aSSrinivas Kandagatla if (ret)
359769a026a2SJohan Hovold goto err_disable_regulators;
35988d78602aSSrinivas Kandagatla
35998d78602aSSrinivas Kandagatla wcd938x_reset(wcd938x);
36008d78602aSSrinivas Kandagatla
36018d78602aSSrinivas Kandagatla ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match);
36028d78602aSSrinivas Kandagatla if (ret)
360369a026a2SJohan Hovold goto err_disable_regulators;
36048d78602aSSrinivas Kandagatla
36058d78602aSSrinivas Kandagatla pm_runtime_set_autosuspend_delay(dev, 1000);
36068d78602aSSrinivas Kandagatla pm_runtime_use_autosuspend(dev);
36078d78602aSSrinivas Kandagatla pm_runtime_mark_last_busy(dev);
36088d78602aSSrinivas Kandagatla pm_runtime_set_active(dev);
36098d78602aSSrinivas Kandagatla pm_runtime_enable(dev);
36108d78602aSSrinivas Kandagatla pm_runtime_idle(dev);
36118d78602aSSrinivas Kandagatla
36128c62dbcbSPierre-Louis Bossart return 0;
361369a026a2SJohan Hovold
361469a026a2SJohan Hovold err_disable_regulators:
361569a026a2SJohan Hovold regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
361669a026a2SJohan Hovold regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
361769a026a2SJohan Hovold
361869a026a2SJohan Hovold return ret;
36198d78602aSSrinivas Kandagatla }
36208d78602aSSrinivas Kandagatla
wcd938x_remove(struct platform_device * pdev)36217cd686a5SUwe Kleine-König static void wcd938x_remove(struct platform_device *pdev)
36228d78602aSSrinivas Kandagatla {
36233ebebb2cSJohan Hovold struct device *dev = &pdev->dev;
36243ebebb2cSJohan Hovold struct wcd938x_priv *wcd938x = dev_get_drvdata(dev);
362569a026a2SJohan Hovold
36263ebebb2cSJohan Hovold component_master_del(dev, &wcd938x_comp_ops);
36273ebebb2cSJohan Hovold
36283ebebb2cSJohan Hovold pm_runtime_disable(dev);
36293ebebb2cSJohan Hovold pm_runtime_set_suspended(dev);
36303ebebb2cSJohan Hovold pm_runtime_dont_use_autosuspend(dev);
36313ebebb2cSJohan Hovold
363269a026a2SJohan Hovold regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
363369a026a2SJohan Hovold regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
36348d78602aSSrinivas Kandagatla }
36358d78602aSSrinivas Kandagatla
36368c4863c2SSrinivas Kandagatla #if defined(CONFIG_OF)
36378d78602aSSrinivas Kandagatla static const struct of_device_id wcd938x_dt_match[] = {
36388d78602aSSrinivas Kandagatla { .compatible = "qcom,wcd9380-codec" },
36398d78602aSSrinivas Kandagatla { .compatible = "qcom,wcd9385-codec" },
36408d78602aSSrinivas Kandagatla {}
36418d78602aSSrinivas Kandagatla };
36428d78602aSSrinivas Kandagatla MODULE_DEVICE_TABLE(of, wcd938x_dt_match);
36438c4863c2SSrinivas Kandagatla #endif
36448d78602aSSrinivas Kandagatla
36458d78602aSSrinivas Kandagatla static struct platform_driver wcd938x_codec_driver = {
36468d78602aSSrinivas Kandagatla .probe = wcd938x_probe,
36477cd686a5SUwe Kleine-König .remove_new = wcd938x_remove,
36488d78602aSSrinivas Kandagatla .driver = {
36498d78602aSSrinivas Kandagatla .name = "wcd938x_codec",
36508d78602aSSrinivas Kandagatla .of_match_table = of_match_ptr(wcd938x_dt_match),
36518d78602aSSrinivas Kandagatla .suppress_bind_attrs = true,
36528d78602aSSrinivas Kandagatla },
36538d78602aSSrinivas Kandagatla };
36548d78602aSSrinivas Kandagatla
36558d78602aSSrinivas Kandagatla module_platform_driver(wcd938x_codec_driver);
36568d78602aSSrinivas Kandagatla MODULE_DESCRIPTION("WCD938X Codec driver");
36578d78602aSSrinivas Kandagatla MODULE_LICENSE("GPL");
3658