linux/sound/soc/codecs/msm8916-wcd-analog.c
<<
>>
Prefs
   1#include <linux/module.h>
   2#include <linux/err.h>
   3#include <linux/kernel.h>
   4#include <linux/delay.h>
   5#include <linux/regulator/consumer.h>
   6#include <linux/types.h>
   7#include <linux/clk.h>
   8#include <linux/of.h>
   9#include <linux/platform_device.h>
  10#include <linux/regmap.h>
  11#include <sound/soc.h>
  12#include <sound/pcm.h>
  13#include <sound/pcm_params.h>
  14#include <sound/tlv.h>
  15
  16#define CDC_D_REVISION1                 (0xf000)
  17#define CDC_D_PERPH_SUBTYPE             (0xf005)
  18#define CDC_D_CDC_RST_CTL               (0xf046)
  19#define RST_CTL_DIG_SW_RST_N_MASK       BIT(7)
  20#define RST_CTL_DIG_SW_RST_N_RESET      0
  21#define RST_CTL_DIG_SW_RST_N_REMOVE_RESET BIT(7)
  22
  23#define CDC_D_CDC_TOP_CLK_CTL           (0xf048)
  24#define TOP_CLK_CTL_A_MCLK_MCLK2_EN_MASK (BIT(2) | BIT(3))
  25#define TOP_CLK_CTL_A_MCLK_EN_ENABLE     BIT(2)
  26#define TOP_CLK_CTL_A_MCLK2_EN_ENABLE   BIT(3)
  27
  28#define CDC_D_CDC_ANA_CLK_CTL           (0xf049)
  29#define ANA_CLK_CTL_EAR_HPHR_CLK_EN_MASK BIT(0)
  30#define ANA_CLK_CTL_EAR_HPHR_CLK_EN     BIT(0)
  31#define ANA_CLK_CTL_EAR_HPHL_CLK_EN     BIT(1)
  32#define ANA_CLK_CTL_SPKR_CLK_EN_MASK    BIT(4)
  33#define ANA_CLK_CTL_SPKR_CLK_EN BIT(4)
  34#define ANA_CLK_CTL_TXA_CLK25_EN        BIT(5)
  35
  36#define CDC_D_CDC_DIG_CLK_CTL           (0xf04A)
  37#define DIG_CLK_CTL_RXD1_CLK_EN         BIT(0)
  38#define DIG_CLK_CTL_RXD2_CLK_EN         BIT(1)
  39#define DIG_CLK_CTL_RXD3_CLK_EN         BIT(2)
  40#define DIG_CLK_CTL_TXD_CLK_EN          BIT(4)
  41#define DIG_CLK_CTL_NCP_CLK_EN_MASK     BIT(6)
  42#define DIG_CLK_CTL_NCP_CLK_EN          BIT(6)
  43#define DIG_CLK_CTL_RXD_PDM_CLK_EN_MASK BIT(7)
  44#define DIG_CLK_CTL_RXD_PDM_CLK_EN      BIT(7)
  45
  46#define CDC_D_CDC_CONN_TX1_CTL          (0xf050)
  47#define CONN_TX1_SERIAL_TX1_MUX         GENMASK(1, 0)
  48#define CONN_TX1_SERIAL_TX1_ADC_1       0x0
  49#define CONN_TX1_SERIAL_TX1_RX_PDM_LB   0x1
  50#define CONN_TX1_SERIAL_TX1_ZERO        0x2
  51
  52#define CDC_D_CDC_CONN_TX2_CTL          (0xf051)
  53#define CONN_TX2_SERIAL_TX2_MUX         GENMASK(1, 0)
  54#define CONN_TX2_SERIAL_TX2_ADC_2       0x0
  55#define CONN_TX2_SERIAL_TX2_RX_PDM_LB   0x1
  56#define CONN_TX2_SERIAL_TX2_ZERO        0x2
  57#define CDC_D_CDC_CONN_HPHR_DAC_CTL     (0xf052)
  58#define CDC_D_CDC_CONN_RX1_CTL          (0xf053)
  59#define CDC_D_CDC_CONN_RX2_CTL          (0xf054)
  60#define CDC_D_CDC_CONN_RX3_CTL          (0xf055)
  61#define CDC_D_CDC_CONN_RX_LB_CTL        (0xf056)
  62#define CDC_D_SEC_ACCESS                (0xf0D0)
  63#define CDC_D_PERPH_RESET_CTL3          (0xf0DA)
  64#define CDC_D_PERPH_RESET_CTL4          (0xf0DB)
  65#define CDC_A_REVISION1                 (0xf100)
  66#define CDC_A_REVISION2                 (0xf101)
  67#define CDC_A_REVISION3                 (0xf102)
  68#define CDC_A_REVISION4                 (0xf103)
  69#define CDC_A_PERPH_TYPE                (0xf104)
  70#define CDC_A_PERPH_SUBTYPE             (0xf105)
  71#define CDC_A_INT_RT_STS                (0xf110)
  72#define CDC_A_INT_SET_TYPE              (0xf111)
  73#define CDC_A_INT_POLARITY_HIGH         (0xf112)
  74#define CDC_A_INT_POLARITY_LOW          (0xf113)
  75#define CDC_A_INT_LATCHED_CLR           (0xf114)
  76#define CDC_A_INT_EN_SET                (0xf115)
  77#define CDC_A_INT_EN_CLR                (0xf116)
  78#define CDC_A_INT_LATCHED_STS           (0xf118)
  79#define CDC_A_INT_PENDING_STS           (0xf119)
  80#define CDC_A_INT_MID_SEL               (0xf11A)
  81#define CDC_A_INT_PRIORITY              (0xf11B)
  82#define CDC_A_MICB_1_EN                 (0xf140)
  83#define MICB_1_EN_MICB_ENABLE           BIT(7)
  84#define MICB_1_EN_BYP_CAP_MASK          BIT(6)
  85#define MICB_1_EN_NO_EXT_BYP_CAP        BIT(6)
  86#define MICB_1_EN_EXT_BYP_CAP           0
  87#define MICB_1_EN_PULL_DOWN_EN_MASK     BIT(5)
  88#define MICB_1_EN_PULL_DOWN_EN_ENABLE   BIT(5)
  89#define MICB_1_EN_OPA_STG2_TAIL_CURR_MASK GENMASK(3, 1)
  90#define MICB_1_EN_OPA_STG2_TAIL_CURR_1_60UA     (0x4)
  91#define MICB_1_EN_PULL_UP_EN_MASK       BIT(4)
  92#define MICB_1_EN_TX3_GND_SEL_MASK      BIT(0)
  93#define MICB_1_EN_TX3_GND_SEL_TX_GND    0
  94
  95#define CDC_A_MICB_1_VAL                (0xf141)
  96#define MICB_1_VAL_MICB_OUT_VAL_MASK    GENMASK(7, 3)
  97#define MICB_1_VAL_MICB_OUT_VAL_V2P70V  ((0x16)  << 3)
  98#define CDC_A_MICB_1_CTL                (0xf142)
  99
 100#define MICB_1_CTL_CFILT_REF_SEL_MASK           BIT(1)
 101#define MICB_1_CTL_CFILT_REF_SEL_HPF_REF        BIT(1)
 102#define MICB_1_CTL_EXT_PRECHARG_EN_MASK         BIT(5)
 103#define MICB_1_CTL_EXT_PRECHARG_EN_ENABLE       BIT(5)
 104#define MICB_1_CTL_INT_PRECHARG_BYP_MASK        BIT(6)
 105#define MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL     BIT(6)
 106
 107#define CDC_A_MICB_1_INT_RBIAS                  (0xf143)
 108#define MICB_1_INT_TX1_INT_RBIAS_EN_MASK        BIT(7)
 109#define MICB_1_INT_TX1_INT_RBIAS_EN_ENABLE      BIT(7)
 110#define MICB_1_INT_TX1_INT_RBIAS_EN_DISABLE     0
 111
 112#define MICB_1_INT_TX1_INT_PULLUP_EN_MASK       BIT(6)
 113#define MICB_1_INT_TX1_INT_PULLUP_EN_TX1N_TO_MICBIAS BIT(6)
 114#define MICB_1_INT_TX1_INT_PULLUP_EN_TX1N_TO_GND        0
 115
 116#define MICB_1_INT_TX2_INT_RBIAS_EN_MASK        BIT(4)
 117#define MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE      BIT(4)
 118#define MICB_1_INT_TX2_INT_RBIAS_EN_DISABLE     0
 119#define MICB_1_INT_TX2_INT_PULLUP_EN_MASK       BIT(3)
 120#define MICB_1_INT_TX2_INT_PULLUP_EN_TX1N_TO_MICBIAS BIT(3)
 121#define MICB_1_INT_TX2_INT_PULLUP_EN_TX1N_TO_GND        0
 122
 123#define MICB_1_INT_TX3_INT_RBIAS_EN_MASK        BIT(1)
 124#define MICB_1_INT_TX3_INT_RBIAS_EN_ENABLE      BIT(1)
 125#define MICB_1_INT_TX3_INT_RBIAS_EN_DISABLE     0
 126#define MICB_1_INT_TX3_INT_PULLUP_EN_MASK       BIT(0)
 127#define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_MICBIAS BIT(0)
 128#define MICB_1_INT_TX3_INT_PULLUP_EN_TX1N_TO_GND        0
 129
 130#define CDC_A_MICB_2_EN                 (0xf144)
 131#define CDC_A_TX_1_2_ATEST_CTL_2        (0xf145)
 132#define CDC_A_MASTER_BIAS_CTL           (0xf146)
 133#define CDC_A_TX_1_EN                   (0xf160)
 134#define CDC_A_TX_2_EN                   (0xf161)
 135#define CDC_A_TX_1_2_TEST_CTL_1         (0xf162)
 136#define CDC_A_TX_1_2_TEST_CTL_2         (0xf163)
 137#define CDC_A_TX_1_2_ATEST_CTL          (0xf164)
 138#define CDC_A_TX_1_2_OPAMP_BIAS         (0xf165)
 139#define CDC_A_TX_3_EN                   (0xf167)
 140#define CDC_A_NCP_EN                    (0xf180)
 141#define CDC_A_NCP_CLK                   (0xf181)
 142#define CDC_A_NCP_FBCTRL                (0xf183)
 143#define CDC_A_NCP_FBCTRL_FB_CLK_INV_MASK        BIT(5)
 144#define CDC_A_NCP_FBCTRL_FB_CLK_INV             BIT(5)
 145#define CDC_A_NCP_BIAS                  (0xf184)
 146#define CDC_A_NCP_VCTRL                 (0xf185)
 147#define CDC_A_NCP_TEST                  (0xf186)
 148#define CDC_A_NCP_CLIM_ADDR             (0xf187)
 149#define CDC_A_RX_CLOCK_DIVIDER          (0xf190)
 150#define CDC_A_RX_COM_OCP_CTL            (0xf191)
 151#define CDC_A_RX_COM_OCP_COUNT          (0xf192)
 152#define CDC_A_RX_COM_BIAS_DAC           (0xf193)
 153#define RX_COM_BIAS_DAC_RX_BIAS_EN_MASK         BIT(7)
 154#define RX_COM_BIAS_DAC_RX_BIAS_EN_ENABLE       BIT(7)
 155#define RX_COM_BIAS_DAC_DAC_REF_EN_MASK         BIT(0)
 156#define RX_COM_BIAS_DAC_DAC_REF_EN_ENABLE       BIT(0)
 157
 158#define CDC_A_RX_HPH_BIAS_PA            (0xf194)
 159#define CDC_A_RX_HPH_BIAS_LDO_OCP       (0xf195)
 160#define CDC_A_RX_HPH_BIAS_CNP           (0xf196)
 161#define CDC_A_RX_HPH_CNP_EN             (0xf197)
 162#define CDC_A_RX_HPH_L_PA_DAC_CTL       (0xf19B)
 163#define RX_HPA_L_PA_DAC_CTL_DATA_RESET_MASK     BIT(1)
 164#define RX_HPA_L_PA_DAC_CTL_DATA_RESET_RESET    BIT(1)
 165#define CDC_A_RX_HPH_R_PA_DAC_CTL       (0xf19D)
 166#define RX_HPH_R_PA_DAC_CTL_DATA_RESET  BIT(1)
 167#define RX_HPH_R_PA_DAC_CTL_DATA_RESET_MASK BIT(1)
 168
 169#define CDC_A_RX_EAR_CTL                        (0xf19E)
 170#define RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK         BIT(0)
 171#define RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE       BIT(0)
 172
 173#define CDC_A_SPKR_DAC_CTL              (0xf1B0)
 174#define SPKR_DAC_CTL_DAC_RESET_MASK     BIT(4)
 175#define SPKR_DAC_CTL_DAC_RESET_NORMAL   0
 176
 177#define CDC_A_SPKR_DRV_CTL              (0xf1B2)
 178#define SPKR_DRV_CTL_DEF_MASK           0xEF
 179#define SPKR_DRV_CLASSD_PA_EN_MASK      BIT(7)
 180#define SPKR_DRV_CLASSD_PA_EN_ENABLE    BIT(7)
 181#define SPKR_DRV_CAL_EN                 BIT(6)
 182#define SPKR_DRV_SETTLE_EN              BIT(5)
 183#define SPKR_DRV_FW_EN                  BIT(3)
 184#define SPKR_DRV_BOOST_SET              BIT(2)
 185#define SPKR_DRV_CMFB_SET               BIT(1)
 186#define SPKR_DRV_GAIN_SET               BIT(0)
 187#define SPKR_DRV_CTL_DEF_VAL (SPKR_DRV_CLASSD_PA_EN_ENABLE | \
 188                SPKR_DRV_CAL_EN | SPKR_DRV_SETTLE_EN | \
 189                SPKR_DRV_FW_EN | SPKR_DRV_BOOST_SET | \
 190                SPKR_DRV_CMFB_SET | SPKR_DRV_GAIN_SET)
 191#define CDC_A_SPKR_OCP_CTL              (0xf1B4)
 192#define CDC_A_SPKR_PWRSTG_CTL           (0xf1B5)
 193#define SPKR_PWRSTG_CTL_DAC_EN_MASK     BIT(0)
 194#define SPKR_PWRSTG_CTL_DAC_EN          BIT(0)
 195#define SPKR_PWRSTG_CTL_MASK            0xE0
 196#define SPKR_PWRSTG_CTL_BBM_MASK        BIT(7)
 197#define SPKR_PWRSTG_CTL_BBM_EN          BIT(7)
 198#define SPKR_PWRSTG_CTL_HBRDGE_EN_MASK  BIT(6)
 199#define SPKR_PWRSTG_CTL_HBRDGE_EN       BIT(6)
 200#define SPKR_PWRSTG_CTL_CLAMP_EN_MASK   BIT(5)
 201#define SPKR_PWRSTG_CTL_CLAMP_EN        BIT(5)
 202
 203#define CDC_A_SPKR_DRV_DBG              (0xf1B7)
 204#define CDC_A_CURRENT_LIMIT             (0xf1C0)
 205#define CDC_A_BOOST_EN_CTL              (0xf1C3)
 206#define CDC_A_SLOPE_COMP_IP_ZERO        (0xf1C4)
 207#define CDC_A_SEC_ACCESS                (0xf1D0)
 208#define CDC_A_PERPH_RESET_CTL3          (0xf1DA)
 209#define CDC_A_PERPH_RESET_CTL4          (0xf1DB)
 210
 211#define MSM8916_WCD_ANALOG_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
 212                        SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
 213#define MSM8916_WCD_ANALOG_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
 214                                    SNDRV_PCM_FMTBIT_S24_LE)
 215
 216static const char * const supply_names[] = {
 217        "vdd-cdc-io",
 218        "vdd-cdc-tx-rx-cx",
 219};
 220
 221struct pm8916_wcd_analog_priv {
 222        u16 pmic_rev;
 223        u16 codec_version;
 224        struct clk *mclk;
 225        struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
 226        unsigned int micbias1_cap_mode;
 227        unsigned int micbias2_cap_mode;
 228};
 229
 230static const char *const adc2_mux_text[] = { "ZERO", "INP2", "INP3" };
 231static const char *const rdac2_mux_text[] = { "ZERO", "RX2", "RX1" };
 232static const char *const hph_text[] = { "ZERO", "Switch", };
 233
 234static const struct soc_enum hph_enum = SOC_ENUM_SINGLE_VIRT(
 235                                        ARRAY_SIZE(hph_text), hph_text);
 236
 237static const struct snd_kcontrol_new hphl_mux = SOC_DAPM_ENUM("HPHL", hph_enum);
 238static const struct snd_kcontrol_new hphr_mux = SOC_DAPM_ENUM("HPHR", hph_enum);
 239
 240/* ADC2 MUX */
 241static const struct soc_enum adc2_enum = SOC_ENUM_SINGLE_VIRT(
 242                        ARRAY_SIZE(adc2_mux_text), adc2_mux_text);
 243
 244/* RDAC2 MUX */
 245static const struct soc_enum rdac2_mux_enum = SOC_ENUM_SINGLE(
 246                        CDC_D_CDC_CONN_HPHR_DAC_CTL, 0, 3, rdac2_mux_text);
 247
 248static const struct snd_kcontrol_new spkr_switch[] = {
 249        SOC_DAPM_SINGLE("Switch", CDC_A_SPKR_DAC_CTL, 7, 1, 0)
 250};
 251
 252static const struct snd_kcontrol_new rdac2_mux = SOC_DAPM_ENUM(
 253                                        "RDAC2 MUX Mux", rdac2_mux_enum);
 254static const struct snd_kcontrol_new tx_adc2_mux = SOC_DAPM_ENUM(
 255                                        "ADC2 MUX Mux", adc2_enum);
 256
 257/* Analog Gain control 0 dB to +24 dB in 6 dB steps */
 258static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 600, 0);
 259
 260static const struct snd_kcontrol_new pm8916_wcd_analog_snd_controls[] = {
 261        SOC_SINGLE_TLV("ADC1 Volume", CDC_A_TX_1_EN, 3, 8, 0, analog_gain),
 262        SOC_SINGLE_TLV("ADC2 Volume", CDC_A_TX_2_EN, 3, 8, 0, analog_gain),
 263        SOC_SINGLE_TLV("ADC3 Volume", CDC_A_TX_3_EN, 3, 8, 0, analog_gain),
 264};
 265
 266static void pm8916_wcd_analog_micbias_enable(struct snd_soc_codec *codec)
 267{
 268        snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
 269                            MICB_1_CTL_EXT_PRECHARG_EN_MASK |
 270                            MICB_1_CTL_INT_PRECHARG_BYP_MASK,
 271                            MICB_1_CTL_INT_PRECHARG_BYP_EXT_PRECHRG_SEL
 272                            | MICB_1_CTL_EXT_PRECHARG_EN_ENABLE);
 273
 274        snd_soc_write(codec, CDC_A_MICB_1_VAL, MICB_1_VAL_MICB_OUT_VAL_V2P70V);
 275        /*
 276         * Special headset needs MICBIAS as 2.7V so wait for
 277         * 50 msec for the MICBIAS to reach 2.7 volts.
 278         */
 279        msleep(50);
 280        snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
 281                            MICB_1_CTL_EXT_PRECHARG_EN_MASK |
 282                            MICB_1_CTL_INT_PRECHARG_BYP_MASK, 0);
 283
 284}
 285
 286static int pm8916_wcd_analog_enable_micbias_ext(struct snd_soc_codec
 287                                                 *codec, int event,
 288                                                 int reg, unsigned int cap_mode)
 289{
 290        switch (event) {
 291        case SND_SOC_DAPM_POST_PMU:
 292                pm8916_wcd_analog_micbias_enable(codec);
 293                snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
 294                                    MICB_1_EN_BYP_CAP_MASK, cap_mode);
 295                break;
 296        }
 297
 298        return 0;
 299}
 300
 301static int pm8916_wcd_analog_enable_micbias_int(struct snd_soc_codec
 302                                                 *codec, int event,
 303                                                 int reg, u32 cap_mode)
 304{
 305
 306        switch (event) {
 307        case SND_SOC_DAPM_PRE_PMU:
 308                snd_soc_update_bits(codec, CDC_A_MICB_1_INT_RBIAS,
 309                                    MICB_1_INT_TX2_INT_RBIAS_EN_MASK,
 310                                    MICB_1_INT_TX2_INT_RBIAS_EN_ENABLE);
 311                snd_soc_update_bits(codec, reg, MICB_1_EN_PULL_DOWN_EN_MASK, 0);
 312                snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
 313                                    MICB_1_EN_OPA_STG2_TAIL_CURR_MASK,
 314                                    MICB_1_EN_OPA_STG2_TAIL_CURR_1_60UA);
 315
 316                break;
 317        case SND_SOC_DAPM_POST_PMU:
 318                pm8916_wcd_analog_micbias_enable(codec);
 319                snd_soc_update_bits(codec, CDC_A_MICB_1_EN,
 320                                    MICB_1_EN_BYP_CAP_MASK, cap_mode);
 321                break;
 322        }
 323
 324        return 0;
 325}
 326
 327static int pm8916_wcd_analog_enable_micbias_ext1(struct
 328                                                  snd_soc_dapm_widget
 329                                                  *w, struct snd_kcontrol
 330                                                  *kcontrol, int event)
 331{
 332        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 333        struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
 334
 335        return pm8916_wcd_analog_enable_micbias_ext(codec, event, w->reg,
 336                                                     wcd->micbias1_cap_mode);
 337}
 338
 339static int pm8916_wcd_analog_enable_micbias_ext2(struct
 340                                                  snd_soc_dapm_widget
 341                                                  *w, struct snd_kcontrol
 342                                                  *kcontrol, int event)
 343{
 344        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 345        struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
 346
 347        return pm8916_wcd_analog_enable_micbias_ext(codec, event, w->reg,
 348                                                     wcd->micbias2_cap_mode);
 349
 350}
 351
 352static int pm8916_wcd_analog_enable_micbias_int1(struct
 353                                                  snd_soc_dapm_widget
 354                                                  *w, struct snd_kcontrol
 355                                                  *kcontrol, int event)
 356{
 357        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 358        struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
 359
 360        return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
 361                                                     wcd->micbias1_cap_mode);
 362}
 363
 364static int pm8916_wcd_analog_enable_micbias_int2(struct
 365                                                  snd_soc_dapm_widget
 366                                                  *w, struct snd_kcontrol
 367                                                  *kcontrol, int event)
 368{
 369        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 370        struct pm8916_wcd_analog_priv *wcd = snd_soc_codec_get_drvdata(codec);
 371
 372        return pm8916_wcd_analog_enable_micbias_int(codec, event, w->reg,
 373                                                     wcd->micbias2_cap_mode);
 374}
 375
 376static int pm8916_wcd_analog_enable_adc(struct snd_soc_dapm_widget *w,
 377                                         struct snd_kcontrol *kcontrol,
 378                                         int event)
 379{
 380        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 381        u16 adc_reg = CDC_A_TX_1_2_TEST_CTL_2;
 382        u8 init_bit_shift;
 383
 384        if (w->reg == CDC_A_TX_1_EN)
 385                init_bit_shift = 5;
 386        else
 387                init_bit_shift = 4;
 388
 389        switch (event) {
 390        case SND_SOC_DAPM_PRE_PMU:
 391                if (w->reg == CDC_A_TX_2_EN)
 392                        snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
 393                                            MICB_1_CTL_CFILT_REF_SEL_MASK,
 394                                            MICB_1_CTL_CFILT_REF_SEL_HPF_REF);
 395                /*
 396                 * Add delay of 10 ms to give sufficient time for the voltage
 397                 * to shoot up and settle so that the txfe init does not
 398                 * happen when the input voltage is changing too much.
 399                 */
 400                usleep_range(10000, 10010);
 401                snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift,
 402                                    1 << init_bit_shift);
 403                switch (w->reg) {
 404                case CDC_A_TX_1_EN:
 405                        snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX1_CTL,
 406                                            CONN_TX1_SERIAL_TX1_MUX,
 407                                            CONN_TX1_SERIAL_TX1_ADC_1);
 408                        break;
 409                case CDC_A_TX_2_EN:
 410                case CDC_A_TX_3_EN:
 411                        snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
 412                                            CONN_TX2_SERIAL_TX2_MUX,
 413                                            CONN_TX2_SERIAL_TX2_ADC_2);
 414                        break;
 415                }
 416                break;
 417        case SND_SOC_DAPM_POST_PMU:
 418                /*
 419                 * Add delay of 12 ms before deasserting the init
 420                 * to reduce the tx pop
 421                 */
 422                usleep_range(12000, 12010);
 423                snd_soc_update_bits(codec, adc_reg, 1 << init_bit_shift, 0x00);
 424                break;
 425        case SND_SOC_DAPM_POST_PMD:
 426                switch (w->reg) {
 427                case CDC_A_TX_1_EN:
 428                        snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX1_CTL,
 429                                            CONN_TX1_SERIAL_TX1_MUX,
 430                                            CONN_TX1_SERIAL_TX1_ZERO);
 431                        break;
 432                case CDC_A_TX_2_EN:
 433                        snd_soc_update_bits(codec, CDC_A_MICB_1_CTL,
 434                                            MICB_1_CTL_CFILT_REF_SEL_MASK, 0);
 435                case CDC_A_TX_3_EN:
 436                        snd_soc_update_bits(codec, CDC_D_CDC_CONN_TX2_CTL,
 437                                            CONN_TX2_SERIAL_TX2_MUX,
 438                                            CONN_TX2_SERIAL_TX2_ZERO);
 439                        break;
 440                }
 441
 442
 443                break;
 444        }
 445        return 0;
 446}
 447
 448static int pm8916_wcd_analog_enable_spk_pa(struct snd_soc_dapm_widget *w,
 449                                            struct snd_kcontrol *kcontrol,
 450                                            int event)
 451{
 452        struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 453
 454        switch (event) {
 455        case SND_SOC_DAPM_PRE_PMU:
 456                snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
 457                                    SPKR_PWRSTG_CTL_DAC_EN_MASK |
 458                                    SPKR_PWRSTG_CTL_BBM_MASK |
 459                                    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
 460                                    SPKR_PWRSTG_CTL_CLAMP_EN_MASK,
 461                                    SPKR_PWRSTG_CTL_DAC_EN|
 462                                    SPKR_PWRSTG_CTL_BBM_EN |
 463                                    SPKR_PWRSTG_CTL_HBRDGE_EN |
 464                                    SPKR_PWRSTG_CTL_CLAMP_EN);
 465
 466                snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
 467                                    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK,
 468                                    RX_EAR_CTL_SPK_VBAT_LDO_EN_ENABLE);
 469                break;
 470        case SND_SOC_DAPM_POST_PMU:
 471                snd_soc_update_bits(codec, CDC_A_SPKR_DRV_CTL,
 472                                    SPKR_DRV_CTL_DEF_MASK,
 473                                    SPKR_DRV_CTL_DEF_VAL);
 474                snd_soc_update_bits(codec, w->reg,
 475                                    SPKR_DRV_CLASSD_PA_EN_MASK,
 476                                    SPKR_DRV_CLASSD_PA_EN_ENABLE);
 477                break;
 478        case SND_SOC_DAPM_POST_PMD:
 479                snd_soc_update_bits(codec, CDC_A_SPKR_PWRSTG_CTL,
 480                                    SPKR_PWRSTG_CTL_DAC_EN_MASK|
 481                                    SPKR_PWRSTG_CTL_BBM_MASK |
 482                                    SPKR_PWRSTG_CTL_HBRDGE_EN_MASK |
 483                                    SPKR_PWRSTG_CTL_CLAMP_EN_MASK, 0);
 484
 485                snd_soc_update_bits(codec, CDC_A_SPKR_DAC_CTL,
 486                                    SPKR_DAC_CTL_DAC_RESET_MASK,
 487                                    SPKR_DAC_CTL_DAC_RESET_NORMAL);
 488                snd_soc_update_bits(codec, CDC_A_RX_EAR_CTL,
 489                                    RX_EAR_CTL_SPK_VBAT_LDO_EN_MASK, 0);
 490                break;
 491        }
 492        return 0;
 493}
 494
 495static const struct reg_default wcd_reg_defaults_2_0[] = {
 496        {CDC_A_RX_COM_OCP_CTL, 0xD1},
 497        {CDC_A_RX_COM_OCP_COUNT, 0xFF},
 498        {CDC_D_SEC_ACCESS, 0xA5},
 499        {CDC_D_PERPH_RESET_CTL3, 0x0F},
 500        {CDC_A_TX_1_2_OPAMP_BIAS, 0x4F},
 501        {CDC_A_NCP_FBCTRL, 0x28},
 502        {CDC_A_SPKR_DRV_CTL, 0x69},
 503        {CDC_A_SPKR_DRV_DBG, 0x01},
 504        {CDC_A_BOOST_EN_CTL, 0x5F},
 505        {CDC_A_SLOPE_COMP_IP_ZERO, 0x88},
 506        {CDC_A_SEC_ACCESS, 0xA5},
 507        {CDC_A_PERPH_RESET_CTL3, 0x0F},
 508        {CDC_A_CURRENT_LIMIT, 0x82},
 509        {CDC_A_SPKR_DAC_CTL, 0x03},
 510        {CDC_A_SPKR_OCP_CTL, 0xE1},
 511        {CDC_A_MASTER_BIAS_CTL, 0x30},
 512};
 513
 514static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec)
 515{
 516        struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
 517        int err, reg;
 518
 519        err = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
 520        if (err != 0) {
 521                dev_err(codec->dev, "failed to enable regulators (%d)\n", err);
 522                return err;
 523        }
 524
 525        snd_soc_codec_set_drvdata(codec, priv);
 526        priv->pmic_rev = snd_soc_read(codec, CDC_D_REVISION1);
 527        priv->codec_version = snd_soc_read(codec, CDC_D_PERPH_SUBTYPE);
 528
 529        dev_info(codec->dev, "PMIC REV: %d\t CODEC Version: %d\n",
 530                 priv->pmic_rev, priv->codec_version);
 531
 532        snd_soc_write(codec, CDC_D_PERPH_RESET_CTL4, 0x01);
 533        snd_soc_write(codec, CDC_A_PERPH_RESET_CTL4, 0x01);
 534
 535        for (reg = 0; reg < ARRAY_SIZE(wcd_reg_defaults_2_0); reg++)
 536                snd_soc_write(codec, wcd_reg_defaults_2_0[reg].reg,
 537                              wcd_reg_defaults_2_0[reg].def);
 538
 539        return 0;
 540}
 541
 542static int pm8916_wcd_analog_remove(struct snd_soc_codec *codec)
 543{
 544        struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(codec->dev);
 545
 546        return regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
 547                                      priv->supplies);
 548}
 549
 550static const struct snd_soc_dapm_route pm8916_wcd_analog_audio_map[] = {
 551
 552        {"PDM_RX1", NULL, "PDM Playback"},
 553        {"PDM_RX2", NULL, "PDM Playback"},
 554        {"PDM_RX3", NULL, "PDM Playback"},
 555        {"PDM Capture", NULL, "PDM_TX"},
 556
 557        /* ADC Connections */
 558        {"PDM_TX", NULL, "ADC2"},
 559        {"PDM_TX", NULL, "ADC3"},
 560        {"ADC2", NULL, "ADC2 MUX"},
 561        {"ADC3", NULL, "ADC2 MUX"},
 562        {"ADC2 MUX", "INP2", "ADC2_INP2"},
 563        {"ADC2 MUX", "INP3", "ADC2_INP3"},
 564
 565        {"PDM_TX", NULL, "ADC1"},
 566        {"ADC1", NULL, "AMIC1"},
 567        {"ADC2_INP2", NULL, "AMIC2"},
 568        {"ADC2_INP3", NULL, "AMIC3"},
 569
 570        /* RDAC Connections */
 571        {"HPHR DAC", NULL, "RDAC2 MUX"},
 572        {"RDAC2 MUX", "RX1", "PDM_RX1"},
 573        {"RDAC2 MUX", "RX2", "PDM_RX2"},
 574        {"HPHL DAC", NULL, "PDM_RX1"},
 575        {"PDM_RX1", NULL, "RXD1_CLK"},
 576        {"PDM_RX2", NULL, "RXD2_CLK"},
 577        {"PDM_RX3", NULL, "RXD3_CLK"},
 578
 579        {"PDM_RX1", NULL, "RXD_PDM_CLK"},
 580        {"PDM_RX2", NULL, "RXD_PDM_CLK"},
 581        {"PDM_RX3", NULL, "RXD_PDM_CLK"},
 582
 583        {"ADC1", NULL, "TXD_CLK"},
 584        {"ADC2", NULL, "TXD_CLK"},
 585        {"ADC3", NULL, "TXD_CLK"},
 586
 587        {"ADC1", NULL, "TXA_CLK25"},
 588        {"ADC2", NULL, "TXA_CLK25"},
 589        {"ADC3", NULL, "TXA_CLK25"},
 590
 591        {"PDM_RX1", NULL, "A_MCLK2"},
 592        {"PDM_RX2", NULL, "A_MCLK2"},
 593        {"PDM_RX3", NULL, "A_MCLK2"},
 594
 595        {"PDM_TX", NULL, "A_MCLK2"},
 596        {"A_MCLK2", NULL, "A_MCLK"},
 597
 598        /* Headset (RX MIX1 and RX MIX2) */
 599        {"HEADPHONE", NULL, "HPHL PA"},
 600        {"HEADPHONE", NULL, "HPHR PA"},
 601
 602        {"HPHL PA", NULL, "EAR_HPHL_CLK"},
 603        {"HPHR PA", NULL, "EAR_HPHR_CLK"},
 604
 605        {"CP", NULL, "NCP_CLK"},
 606
 607        {"HPHL PA", NULL, "HPHL"},
 608        {"HPHR PA", NULL, "HPHR"},
 609        {"HPHL PA", NULL, "CP"},
 610        {"HPHL PA", NULL, "RX_BIAS"},
 611        {"HPHR PA", NULL, "CP"},
 612        {"HPHR PA", NULL, "RX_BIAS"},
 613        {"HPHL", "Switch", "HPHL DAC"},
 614        {"HPHR", "Switch", "HPHR DAC"},
 615
 616        {"RX_BIAS", NULL, "DAC_REF"},
 617
 618        {"SPK_OUT", NULL, "SPK PA"},
 619        {"SPK PA", NULL, "RX_BIAS"},
 620        {"SPK PA", NULL, "SPKR_CLK"},
 621        {"SPK PA", NULL, "SPK DAC"},
 622        {"SPK DAC", "Switch", "PDM_RX3"},
 623
 624        {"MIC BIAS Internal1", NULL, "INT_LDO_H"},
 625        {"MIC BIAS Internal2", NULL, "INT_LDO_H"},
 626        {"MIC BIAS External1", NULL, "INT_LDO_H"},
 627        {"MIC BIAS External2", NULL, "INT_LDO_H"},
 628        {"MIC BIAS Internal1", NULL, "vdd-micbias"},
 629        {"MIC BIAS Internal2", NULL, "vdd-micbias"},
 630        {"MIC BIAS External1", NULL, "vdd-micbias"},
 631        {"MIC BIAS External2", NULL, "vdd-micbias"},
 632};
 633
 634static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
 635
 636        SND_SOC_DAPM_AIF_IN("PDM_RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
 637        SND_SOC_DAPM_AIF_IN("PDM_RX2", NULL, 0, SND_SOC_NOPM, 0, 0),
 638        SND_SOC_DAPM_AIF_IN("PDM_RX3", NULL, 0, SND_SOC_NOPM, 0, 0),
 639        SND_SOC_DAPM_AIF_OUT("PDM_TX", NULL, 0, SND_SOC_NOPM, 0, 0),
 640
 641        SND_SOC_DAPM_INPUT("AMIC1"),
 642        SND_SOC_DAPM_INPUT("AMIC3"),
 643        SND_SOC_DAPM_INPUT("AMIC2"),
 644        SND_SOC_DAPM_OUTPUT("HEADPHONE"),
 645
 646        /* RX stuff */
 647        SND_SOC_DAPM_SUPPLY("INT_LDO_H", SND_SOC_NOPM, 1, 0, NULL, 0),
 648
 649        SND_SOC_DAPM_PGA("HPHL PA", CDC_A_RX_HPH_CNP_EN, 5, 0, NULL, 0),
 650        SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, &hphl_mux),
 651        SND_SOC_DAPM_MIXER("HPHL DAC", CDC_A_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL,
 652                           0),
 653        SND_SOC_DAPM_PGA("HPHR PA", CDC_A_RX_HPH_CNP_EN, 4, 0, NULL, 0),
 654        SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, &hphr_mux),
 655        SND_SOC_DAPM_MIXER("HPHR DAC", CDC_A_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL,
 656                           0),
 657        SND_SOC_DAPM_MIXER("SPK DAC", SND_SOC_NOPM, 0, 0,
 658                           spkr_switch, ARRAY_SIZE(spkr_switch)),
 659
 660        /* Speaker */
 661        SND_SOC_DAPM_OUTPUT("SPK_OUT"),
 662        SND_SOC_DAPM_PGA_E("SPK PA", CDC_A_SPKR_DRV_CTL,
 663                           6, 0, NULL, 0,
 664                           pm8916_wcd_analog_enable_spk_pa,
 665                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 666                           SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 667        SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-micbias", 0, 0),
 668        SND_SOC_DAPM_SUPPLY("CP", CDC_A_NCP_EN, 0, 0, NULL, 0),
 669
 670        SND_SOC_DAPM_SUPPLY("DAC_REF", CDC_A_RX_COM_BIAS_DAC, 0, 0, NULL, 0),
 671        SND_SOC_DAPM_SUPPLY("RX_BIAS", CDC_A_RX_COM_BIAS_DAC, 7, 0, NULL, 0),
 672
 673        /* TX */
 674        SND_SOC_DAPM_SUPPLY("MIC BIAS Internal1", CDC_A_MICB_1_EN, 7, 0,
 675                            pm8916_wcd_analog_enable_micbias_int1,
 676                            SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 677                            SND_SOC_DAPM_POST_PMD),
 678        SND_SOC_DAPM_SUPPLY("MIC BIAS Internal2", CDC_A_MICB_2_EN, 7, 0,
 679                            pm8916_wcd_analog_enable_micbias_int2,
 680                            SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 681                            SND_SOC_DAPM_POST_PMD),
 682
 683        SND_SOC_DAPM_SUPPLY("MIC BIAS External1", CDC_A_MICB_1_EN, 7, 0,
 684                            pm8916_wcd_analog_enable_micbias_ext1,
 685                            SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 686        SND_SOC_DAPM_SUPPLY("MIC BIAS External2", CDC_A_MICB_2_EN, 7, 0,
 687                            pm8916_wcd_analog_enable_micbias_ext2,
 688                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 689
 690        SND_SOC_DAPM_ADC_E("ADC1", NULL, CDC_A_TX_1_EN, 7, 0,
 691                           pm8916_wcd_analog_enable_adc,
 692                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 693                           SND_SOC_DAPM_POST_PMD),
 694        SND_SOC_DAPM_ADC_E("ADC2_INP2", NULL, CDC_A_TX_2_EN, 7, 0,
 695                           pm8916_wcd_analog_enable_adc,
 696                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 697                           SND_SOC_DAPM_POST_PMD),
 698        SND_SOC_DAPM_ADC_E("ADC2_INP3", NULL, CDC_A_TX_3_EN, 7, 0,
 699                           pm8916_wcd_analog_enable_adc,
 700                           SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 701                           SND_SOC_DAPM_POST_PMD),
 702
 703        SND_SOC_DAPM_MIXER("ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
 704        SND_SOC_DAPM_MIXER("ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
 705
 706        SND_SOC_DAPM_MUX("ADC2 MUX", SND_SOC_NOPM, 0, 0, &tx_adc2_mux),
 707        SND_SOC_DAPM_MUX("RDAC2 MUX", SND_SOC_NOPM, 0, 0, &rdac2_mux),
 708
 709        /* Analog path clocks */
 710        SND_SOC_DAPM_SUPPLY("EAR_HPHR_CLK", CDC_D_CDC_ANA_CLK_CTL, 0, 0, NULL,
 711                            0),
 712        SND_SOC_DAPM_SUPPLY("EAR_HPHL_CLK", CDC_D_CDC_ANA_CLK_CTL, 1, 0, NULL,
 713                            0),
 714        SND_SOC_DAPM_SUPPLY("SPKR_CLK", CDC_D_CDC_ANA_CLK_CTL, 4, 0, NULL, 0),
 715        SND_SOC_DAPM_SUPPLY("TXA_CLK25", CDC_D_CDC_ANA_CLK_CTL, 5, 0, NULL, 0),
 716
 717        /* Digital path clocks */
 718
 719        SND_SOC_DAPM_SUPPLY("RXD1_CLK", CDC_D_CDC_DIG_CLK_CTL, 0, 0, NULL, 0),
 720        SND_SOC_DAPM_SUPPLY("RXD2_CLK", CDC_D_CDC_DIG_CLK_CTL, 1, 0, NULL, 0),
 721        SND_SOC_DAPM_SUPPLY("RXD3_CLK", CDC_D_CDC_DIG_CLK_CTL, 2, 0, NULL, 0),
 722
 723        SND_SOC_DAPM_SUPPLY("TXD_CLK", CDC_D_CDC_DIG_CLK_CTL, 4, 0, NULL, 0),
 724        SND_SOC_DAPM_SUPPLY("NCP_CLK", CDC_D_CDC_DIG_CLK_CTL, 6, 0, NULL, 0),
 725        SND_SOC_DAPM_SUPPLY("RXD_PDM_CLK", CDC_D_CDC_DIG_CLK_CTL, 7, 0, NULL,
 726                            0),
 727
 728        /* System Clock source */
 729        SND_SOC_DAPM_SUPPLY("A_MCLK", CDC_D_CDC_TOP_CLK_CTL, 2, 0, NULL, 0),
 730        /* TX ADC and RX DAC Clock source. */
 731        SND_SOC_DAPM_SUPPLY("A_MCLK2", CDC_D_CDC_TOP_CLK_CTL, 3, 0, NULL, 0),
 732};
 733
 734static struct regmap *pm8916_get_regmap(struct device *dev)
 735{
 736        return dev_get_regmap(dev->parent, NULL);
 737}
 738
 739static int pm8916_wcd_analog_startup(struct snd_pcm_substream *substream,
 740                                      struct snd_soc_dai *dai)
 741{
 742        snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL,
 743                            RST_CTL_DIG_SW_RST_N_MASK,
 744                            RST_CTL_DIG_SW_RST_N_REMOVE_RESET);
 745
 746        return 0;
 747}
 748
 749static void pm8916_wcd_analog_shutdown(struct snd_pcm_substream *substream,
 750                                         struct snd_soc_dai *dai)
 751{
 752        snd_soc_update_bits(dai->codec, CDC_D_CDC_RST_CTL,
 753                            RST_CTL_DIG_SW_RST_N_MASK, 0);
 754}
 755
 756static struct snd_soc_dai_ops pm8916_wcd_analog_dai_ops = {
 757        .startup = pm8916_wcd_analog_startup,
 758        .shutdown = pm8916_wcd_analog_shutdown,
 759};
 760
 761static struct snd_soc_dai_driver pm8916_wcd_analog_dai[] = {
 762        [0] = {
 763               .name = "pm8916_wcd_analog_pdm_rx",
 764               .id = 0,
 765               .playback = {
 766                            .stream_name = "PDM Playback",
 767                            .rates = MSM8916_WCD_ANALOG_RATES,
 768                            .formats = MSM8916_WCD_ANALOG_FORMATS,
 769                            .channels_min = 1,
 770                            .channels_max = 3,
 771                            },
 772               .ops = &pm8916_wcd_analog_dai_ops,
 773               },
 774        [1] = {
 775               .name = "pm8916_wcd_analog_pdm_tx",
 776               .id = 1,
 777               .capture = {
 778                           .stream_name = "PDM Capture",
 779                           .rates = MSM8916_WCD_ANALOG_RATES,
 780                           .formats = MSM8916_WCD_ANALOG_FORMATS,
 781                           .channels_min = 1,
 782                           .channels_max = 4,
 783                           },
 784               .ops = &pm8916_wcd_analog_dai_ops,
 785               },
 786};
 787
 788static struct snd_soc_codec_driver pm8916_wcd_analog = {
 789        .probe = pm8916_wcd_analog_probe,
 790        .remove = pm8916_wcd_analog_remove,
 791        .get_regmap = pm8916_get_regmap,
 792        .component_driver = {
 793                .controls = pm8916_wcd_analog_snd_controls,
 794                .num_controls = ARRAY_SIZE(pm8916_wcd_analog_snd_controls),
 795                .dapm_widgets = pm8916_wcd_analog_dapm_widgets,
 796                .num_dapm_widgets = ARRAY_SIZE(pm8916_wcd_analog_dapm_widgets),
 797                .dapm_routes = pm8916_wcd_analog_audio_map,
 798                .num_dapm_routes = ARRAY_SIZE(pm8916_wcd_analog_audio_map),
 799        },
 800};
 801
 802static int pm8916_wcd_analog_parse_dt(struct device *dev,
 803                                       struct pm8916_wcd_analog_priv *priv)
 804{
 805
 806        if (of_property_read_bool(dev->of_node, "qcom,micbias1-ext-cap"))
 807                priv->micbias1_cap_mode = MICB_1_EN_EXT_BYP_CAP;
 808        else
 809                priv->micbias1_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP;
 810
 811        if (of_property_read_bool(dev->of_node, "qcom,micbias2-ext-cap"))
 812                priv->micbias2_cap_mode = MICB_1_EN_EXT_BYP_CAP;
 813        else
 814                priv->micbias2_cap_mode = MICB_1_EN_NO_EXT_BYP_CAP;
 815
 816        return 0;
 817}
 818
 819static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
 820{
 821        struct pm8916_wcd_analog_priv *priv;
 822        struct device *dev = &pdev->dev;
 823        int ret, i;
 824
 825        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 826        if (!priv)
 827                return -ENOMEM;
 828
 829        ret = pm8916_wcd_analog_parse_dt(dev, priv);
 830        if (ret < 0)
 831                return ret;
 832
 833        priv->mclk = devm_clk_get(dev, "mclk");
 834        if (IS_ERR(priv->mclk)) {
 835                dev_err(dev, "failed to get mclk\n");
 836                return PTR_ERR(priv->mclk);
 837        }
 838
 839        for (i = 0; i < ARRAY_SIZE(supply_names); i++)
 840                priv->supplies[i].supply = supply_names[i];
 841
 842        ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies),
 843                                    priv->supplies);
 844        if (ret) {
 845                dev_err(dev, "Failed to get regulator supplies %d\n", ret);
 846                return ret;
 847        }
 848
 849        ret = clk_prepare_enable(priv->mclk);
 850        if (ret < 0) {
 851                dev_err(dev, "failed to enable mclk %d\n", ret);
 852                return ret;
 853        }
 854
 855        dev_set_drvdata(dev, priv);
 856
 857        return snd_soc_register_codec(dev, &pm8916_wcd_analog,
 858                                      pm8916_wcd_analog_dai,
 859                                      ARRAY_SIZE(pm8916_wcd_analog_dai));
 860}
 861
 862static int pm8916_wcd_analog_spmi_remove(struct platform_device *pdev)
 863{
 864        struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(&pdev->dev);
 865
 866        snd_soc_unregister_codec(&pdev->dev);
 867        clk_disable_unprepare(priv->mclk);
 868
 869        return 0;
 870}
 871
 872static const struct of_device_id pm8916_wcd_analog_spmi_match_table[] = {
 873        { .compatible = "qcom,pm8916-wcd-analog-codec", },
 874        { }
 875};
 876
 877static struct platform_driver pm8916_wcd_analog_spmi_driver = {
 878        .driver = {
 879                   .name = "qcom,pm8916-wcd-spmi-codec",
 880                   .of_match_table = pm8916_wcd_analog_spmi_match_table,
 881        },
 882        .probe = pm8916_wcd_analog_spmi_probe,
 883        .remove = pm8916_wcd_analog_spmi_remove,
 884};
 885
 886module_platform_driver(pm8916_wcd_analog_spmi_driver);
 887
 888MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
 889MODULE_DESCRIPTION("PMIC PM8916 WCD Analog Codec driver");
 890MODULE_LICENSE("GPL v2");
 891