linux/sound/soc/codecs/cs35l35.c
<<
>>
Prefs
   1/*
   2 * cs35l35.c -- CS35L35 ALSA SoC audio driver
   3 *
   4 * Copyright 2017 Cirrus Logic, Inc.
   5 *
   6 * Author: Brian Austin <brian.austin@cirrus.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/moduleparam.h>
  16#include <linux/version.h>
  17#include <linux/kernel.h>
  18#include <linux/init.h>
  19#include <linux/delay.h>
  20#include <linux/i2c.h>
  21#include <linux/slab.h>
  22#include <linux/platform_device.h>
  23#include <linux/regulator/consumer.h>
  24#include <linux/gpio/consumer.h>
  25#include <linux/of_device.h>
  26#include <linux/of_gpio.h>
  27#include <linux/regmap.h>
  28#include <sound/core.h>
  29#include <sound/pcm.h>
  30#include <sound/pcm_params.h>
  31#include <sound/soc.h>
  32#include <sound/soc-dapm.h>
  33#include <linux/gpio.h>
  34#include <sound/initval.h>
  35#include <sound/tlv.h>
  36#include <sound/cs35l35.h>
  37#include <linux/of_irq.h>
  38#include <linux/completion.h>
  39
  40#include "cs35l35.h"
  41
  42/*
  43 * Some fields take zero as a valid value so use a high bit flag that won't
  44 * get written to the device to mark those.
  45 */
  46#define CS35L35_VALID_PDATA 0x80000000
  47
  48static const struct reg_default cs35l35_reg[] = {
  49        {CS35L35_PWRCTL1,               0x01},
  50        {CS35L35_PWRCTL2,               0x11},
  51        {CS35L35_PWRCTL3,               0x00},
  52        {CS35L35_CLK_CTL1,              0x04},
  53        {CS35L35_CLK_CTL2,              0x12},
  54        {CS35L35_CLK_CTL3,              0xCF},
  55        {CS35L35_SP_FMT_CTL1,           0x20},
  56        {CS35L35_SP_FMT_CTL2,           0x00},
  57        {CS35L35_SP_FMT_CTL3,           0x02},
  58        {CS35L35_MAG_COMP_CTL,          0x00},
  59        {CS35L35_AMP_INP_DRV_CTL,       0x01},
  60        {CS35L35_AMP_DIG_VOL_CTL,       0x12},
  61        {CS35L35_AMP_DIG_VOL,           0x00},
  62        {CS35L35_ADV_DIG_VOL,           0x00},
  63        {CS35L35_PROTECT_CTL,           0x06},
  64        {CS35L35_AMP_GAIN_AUD_CTL,      0x13},
  65        {CS35L35_AMP_GAIN_PDM_CTL,      0x00},
  66        {CS35L35_AMP_GAIN_ADV_CTL,      0x00},
  67        {CS35L35_GPI_CTL,               0x00},
  68        {CS35L35_BST_CVTR_V_CTL,        0x00},
  69        {CS35L35_BST_PEAK_I,            0x07},
  70        {CS35L35_BST_RAMP_CTL,          0x85},
  71        {CS35L35_BST_CONV_COEF_1,       0x24},
  72        {CS35L35_BST_CONV_COEF_2,       0x24},
  73        {CS35L35_BST_CONV_SLOPE_COMP,   0x4E},
  74        {CS35L35_BST_CONV_SW_FREQ,      0x04},
  75        {CS35L35_CLASS_H_CTL,           0x0B},
  76        {CS35L35_CLASS_H_HEADRM_CTL,    0x0B},
  77        {CS35L35_CLASS_H_RELEASE_RATE,  0x08},
  78        {CS35L35_CLASS_H_FET_DRIVE_CTL, 0x41},
  79        {CS35L35_CLASS_H_VP_CTL,        0xC5},
  80        {CS35L35_VPBR_CTL,              0x0A},
  81        {CS35L35_VPBR_VOL_CTL,          0x90},
  82        {CS35L35_VPBR_TIMING_CTL,       0x6A},
  83        {CS35L35_VPBR_MODE_VOL_CTL,     0x00},
  84        {CS35L35_SPKR_MON_CTL,          0xC0},
  85        {CS35L35_IMON_SCALE_CTL,        0x30},
  86        {CS35L35_AUDIN_RXLOC_CTL,       0x00},
  87        {CS35L35_ADVIN_RXLOC_CTL,       0x80},
  88        {CS35L35_VMON_TXLOC_CTL,        0x00},
  89        {CS35L35_IMON_TXLOC_CTL,        0x80},
  90        {CS35L35_VPMON_TXLOC_CTL,       0x04},
  91        {CS35L35_VBSTMON_TXLOC_CTL,     0x84},
  92        {CS35L35_VPBR_STATUS_TXLOC_CTL, 0x04},
  93        {CS35L35_ZERO_FILL_LOC_CTL,     0x00},
  94        {CS35L35_AUDIN_DEPTH_CTL,       0x0F},
  95        {CS35L35_SPKMON_DEPTH_CTL,      0x0F},
  96        {CS35L35_SUPMON_DEPTH_CTL,      0x0F},
  97        {CS35L35_ZEROFILL_DEPTH_CTL,    0x00},
  98        {CS35L35_MULT_DEV_SYNCH1,       0x02},
  99        {CS35L35_MULT_DEV_SYNCH2,       0x80},
 100        {CS35L35_PROT_RELEASE_CTL,      0x00},
 101        {CS35L35_DIAG_MODE_REG_LOCK,    0x00},
 102        {CS35L35_DIAG_MODE_CTL_1,       0x40},
 103        {CS35L35_DIAG_MODE_CTL_2,       0x00},
 104        {CS35L35_INT_MASK_1,            0xFF},
 105        {CS35L35_INT_MASK_2,            0xFF},
 106        {CS35L35_INT_MASK_3,            0xFF},
 107        {CS35L35_INT_MASK_4,            0xFF},
 108
 109};
 110
 111static bool cs35l35_volatile_register(struct device *dev, unsigned int reg)
 112{
 113        switch (reg) {
 114        case CS35L35_INT_STATUS_1:
 115        case CS35L35_INT_STATUS_2:
 116        case CS35L35_INT_STATUS_3:
 117        case CS35L35_INT_STATUS_4:
 118        case CS35L35_PLL_STATUS:
 119        case CS35L35_OTP_TRIM_STATUS:
 120                return true;
 121        default:
 122                return false;
 123        }
 124}
 125
 126static bool cs35l35_readable_register(struct device *dev, unsigned int reg)
 127{
 128        switch (reg) {
 129        case CS35L35_DEVID_AB ... CS35L35_PWRCTL3:
 130        case CS35L35_CLK_CTL1 ... CS35L35_SP_FMT_CTL3:
 131        case CS35L35_MAG_COMP_CTL ... CS35L35_AMP_GAIN_AUD_CTL:
 132        case CS35L35_AMP_GAIN_PDM_CTL ... CS35L35_BST_PEAK_I:
 133        case CS35L35_BST_RAMP_CTL ... CS35L35_BST_CONV_SW_FREQ:
 134        case CS35L35_CLASS_H_CTL ... CS35L35_CLASS_H_VP_CTL:
 135        case CS35L35_CLASS_H_STATUS:
 136        case CS35L35_VPBR_CTL ... CS35L35_VPBR_MODE_VOL_CTL:
 137        case CS35L35_VPBR_ATTEN_STATUS:
 138        case CS35L35_SPKR_MON_CTL:
 139        case CS35L35_IMON_SCALE_CTL ... CS35L35_ZEROFILL_DEPTH_CTL:
 140        case CS35L35_MULT_DEV_SYNCH1 ... CS35L35_PROT_RELEASE_CTL:
 141        case CS35L35_DIAG_MODE_REG_LOCK ... CS35L35_DIAG_MODE_CTL_2:
 142        case CS35L35_INT_MASK_1 ... CS35L35_PLL_STATUS:
 143        case CS35L35_OTP_TRIM_STATUS:
 144                return true;
 145        default:
 146                return false;
 147        }
 148}
 149
 150static bool cs35l35_precious_register(struct device *dev, unsigned int reg)
 151{
 152        switch (reg) {
 153        case CS35L35_INT_STATUS_1:
 154        case CS35L35_INT_STATUS_2:
 155        case CS35L35_INT_STATUS_3:
 156        case CS35L35_INT_STATUS_4:
 157        case CS35L35_PLL_STATUS:
 158        case CS35L35_OTP_TRIM_STATUS:
 159                return true;
 160        default:
 161                return false;
 162        }
 163}
 164
 165static void cs35l35_reset(struct cs35l35_private *cs35l35)
 166{
 167        gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
 168        usleep_range(2000, 2100);
 169        gpiod_set_value_cansleep(cs35l35->reset_gpio, 1);
 170        usleep_range(1000, 1100);
 171}
 172
 173static int cs35l35_wait_for_pdn(struct cs35l35_private *cs35l35)
 174{
 175        int ret;
 176
 177        if (cs35l35->pdata.ext_bst) {
 178                usleep_range(5000, 5500);
 179                return 0;
 180        }
 181
 182        reinit_completion(&cs35l35->pdn_done);
 183
 184        ret = wait_for_completion_timeout(&cs35l35->pdn_done,
 185                                          msecs_to_jiffies(100));
 186        if (ret == 0) {
 187                dev_err(cs35l35->dev, "PDN_DONE did not complete\n");
 188                return -ETIMEDOUT;
 189        }
 190
 191        return 0;
 192}
 193
 194static int cs35l35_sdin_event(struct snd_soc_dapm_widget *w,
 195                struct snd_kcontrol *kcontrol, int event)
 196{
 197        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 198        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 199        int ret = 0;
 200
 201        switch (event) {
 202        case SND_SOC_DAPM_PRE_PMU:
 203                regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
 204                                        CS35L35_MCLK_DIS_MASK,
 205                                        0 << CS35L35_MCLK_DIS_SHIFT);
 206                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
 207                                        CS35L35_DISCHG_FILT_MASK,
 208                                        0 << CS35L35_DISCHG_FILT_SHIFT);
 209                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
 210                                        CS35L35_PDN_ALL_MASK, 0);
 211                break;
 212        case SND_SOC_DAPM_POST_PMD:
 213                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
 214                                        CS35L35_DISCHG_FILT_MASK,
 215                                        1 << CS35L35_DISCHG_FILT_SHIFT);
 216                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
 217                                          CS35L35_PDN_ALL_MASK, 1);
 218
 219                /* Already muted, so disable volume ramp for faster shutdown */
 220                regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
 221                                   CS35L35_AMP_DIGSFT_MASK, 0);
 222
 223                ret = cs35l35_wait_for_pdn(cs35l35);
 224
 225                regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
 226                                        CS35L35_MCLK_DIS_MASK,
 227                                        1 << CS35L35_MCLK_DIS_SHIFT);
 228
 229                regmap_update_bits(cs35l35->regmap, CS35L35_AMP_DIG_VOL_CTL,
 230                                   CS35L35_AMP_DIGSFT_MASK,
 231                                   1 << CS35L35_AMP_DIGSFT_SHIFT);
 232                break;
 233        default:
 234                dev_err(component->dev, "Invalid event = 0x%x\n", event);
 235                ret = -EINVAL;
 236        }
 237        return ret;
 238}
 239
 240static int cs35l35_main_amp_event(struct snd_soc_dapm_widget *w,
 241                struct snd_kcontrol *kcontrol, int event)
 242{
 243        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 244        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 245        unsigned int reg[4];
 246        int i;
 247
 248        switch (event) {
 249        case SND_SOC_DAPM_PRE_PMU:
 250                if (cs35l35->pdata.bst_pdn_fet_on)
 251                        regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
 252                                CS35L35_PDN_BST_MASK,
 253                                0 << CS35L35_PDN_BST_FETON_SHIFT);
 254                else
 255                        regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
 256                                CS35L35_PDN_BST_MASK,
 257                                0 << CS35L35_PDN_BST_FETOFF_SHIFT);
 258                break;
 259        case SND_SOC_DAPM_POST_PMU:
 260                usleep_range(5000, 5100);
 261                /* If in PDM mode we must use VP for Voltage control */
 262                if (cs35l35->pdm_mode)
 263                        regmap_update_bits(cs35l35->regmap,
 264                                        CS35L35_BST_CVTR_V_CTL,
 265                                        CS35L35_BST_CTL_MASK,
 266                                        0 << CS35L35_BST_CTL_SHIFT);
 267
 268                regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
 269                        CS35L35_AMP_MUTE_MASK, 0);
 270
 271                for (i = 0; i < 2; i++)
 272                        regmap_bulk_read(cs35l35->regmap, CS35L35_INT_STATUS_1,
 273                                        &reg, ARRAY_SIZE(reg));
 274
 275                break;
 276        case SND_SOC_DAPM_PRE_PMD:
 277                regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
 278                                CS35L35_AMP_MUTE_MASK,
 279                                1 << CS35L35_AMP_MUTE_SHIFT);
 280                if (cs35l35->pdata.bst_pdn_fet_on)
 281                        regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
 282                                CS35L35_PDN_BST_MASK,
 283                                1 << CS35L35_PDN_BST_FETON_SHIFT);
 284                else
 285                        regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
 286                                CS35L35_PDN_BST_MASK,
 287                                1 << CS35L35_PDN_BST_FETOFF_SHIFT);
 288                break;
 289        case SND_SOC_DAPM_POST_PMD:
 290                usleep_range(5000, 5100);
 291                /*
 292                 * If PDM mode we should switch back to pdata value
 293                 * for Voltage control when we go down
 294                 */
 295                if (cs35l35->pdm_mode)
 296                        regmap_update_bits(cs35l35->regmap,
 297                                        CS35L35_BST_CVTR_V_CTL,
 298                                        CS35L35_BST_CTL_MASK,
 299                                        cs35l35->pdata.bst_vctl
 300                                        << CS35L35_BST_CTL_SHIFT);
 301
 302                break;
 303        default:
 304                dev_err(component->dev, "Invalid event = 0x%x\n", event);
 305        }
 306        return 0;
 307}
 308
 309static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
 310static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);
 311
 312static const struct snd_kcontrol_new cs35l35_aud_controls[] = {
 313        SOC_SINGLE_SX_TLV("Digital Audio Volume", CS35L35_AMP_DIG_VOL,
 314                      0, 0x34, 0xE4, dig_vol_tlv),
 315        SOC_SINGLE_TLV("Analog Audio Volume", CS35L35_AMP_GAIN_AUD_CTL, 0, 19, 0,
 316                        amp_gain_tlv),
 317        SOC_SINGLE_TLV("PDM Volume", CS35L35_AMP_GAIN_PDM_CTL, 0, 19, 0,
 318                        amp_gain_tlv),
 319};
 320
 321static const struct snd_kcontrol_new cs35l35_adv_controls[] = {
 322        SOC_SINGLE_SX_TLV("Digital Advisory Volume", CS35L35_ADV_DIG_VOL,
 323                      0, 0x34, 0xE4, dig_vol_tlv),
 324        SOC_SINGLE_TLV("Analog Advisory Volume", CS35L35_AMP_GAIN_ADV_CTL, 0, 19, 0,
 325                        amp_gain_tlv),
 326};
 327
 328static const struct snd_soc_dapm_widget cs35l35_dapm_widgets[] = {
 329        SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L35_PWRCTL3, 1, 1,
 330                                cs35l35_sdin_event, SND_SOC_DAPM_PRE_PMU |
 331                                SND_SOC_DAPM_POST_PMD),
 332        SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L35_PWRCTL3, 2, 1),
 333
 334        SND_SOC_DAPM_OUTPUT("SPK"),
 335
 336        SND_SOC_DAPM_INPUT("VP"),
 337        SND_SOC_DAPM_INPUT("VBST"),
 338        SND_SOC_DAPM_INPUT("ISENSE"),
 339        SND_SOC_DAPM_INPUT("VSENSE"),
 340
 341        SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L35_PWRCTL2, 7, 1),
 342        SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L35_PWRCTL2, 6, 1),
 343        SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L35_PWRCTL3, 3, 1),
 344        SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L35_PWRCTL3, 4, 1),
 345        SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L35_PWRCTL2, 5, 1),
 346
 347        SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L35_PWRCTL2, 0, 1, NULL, 0,
 348                cs35l35_main_amp_event, SND_SOC_DAPM_PRE_PMU |
 349                                SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU |
 350                                SND_SOC_DAPM_PRE_PMD),
 351};
 352
 353static const struct snd_soc_dapm_route cs35l35_audio_map[] = {
 354        {"VPMON ADC", NULL, "VP"},
 355        {"VBSTMON ADC", NULL, "VBST"},
 356        {"IMON ADC", NULL, "ISENSE"},
 357        {"VMON ADC", NULL, "VSENSE"},
 358        {"SDOUT", NULL, "IMON ADC"},
 359        {"SDOUT", NULL, "VMON ADC"},
 360        {"SDOUT", NULL, "VBSTMON ADC"},
 361        {"SDOUT", NULL, "VPMON ADC"},
 362        {"AMP Capture", NULL, "SDOUT"},
 363
 364        {"SDIN", NULL, "AMP Playback"},
 365        {"CLASS H", NULL, "SDIN"},
 366        {"Main AMP", NULL, "CLASS H"},
 367        {"SPK", NULL, "Main AMP"},
 368};
 369
 370static int cs35l35_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 371{
 372        struct snd_soc_component *component = codec_dai->component;
 373        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 374
 375        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 376        case SND_SOC_DAIFMT_CBM_CFM:
 377                regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
 378                                    CS35L35_MS_MASK, 1 << CS35L35_MS_SHIFT);
 379                cs35l35->slave_mode = false;
 380                break;
 381        case SND_SOC_DAIFMT_CBS_CFS:
 382                regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
 383                                    CS35L35_MS_MASK, 0 << CS35L35_MS_SHIFT);
 384                cs35l35->slave_mode = true;
 385                break;
 386        default:
 387                return -EINVAL;
 388        }
 389
 390        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 391        case SND_SOC_DAIFMT_I2S:
 392                cs35l35->i2s_mode = true;
 393                cs35l35->pdm_mode = false;
 394                break;
 395        case SND_SOC_DAIFMT_PDM:
 396                cs35l35->pdm_mode = true;
 397                cs35l35->i2s_mode = false;
 398                break;
 399        default:
 400                return -EINVAL;
 401        }
 402
 403        return 0;
 404}
 405
 406struct cs35l35_sysclk_config {
 407        int sysclk;
 408        int srate;
 409        u8 clk_cfg;
 410};
 411
 412static struct cs35l35_sysclk_config cs35l35_clk_ctl[] = {
 413
 414        /* SYSCLK, Sample Rate, Serial Port Cfg */
 415        {5644800, 44100, 0x00},
 416        {5644800, 88200, 0x40},
 417        {6144000, 48000, 0x10},
 418        {6144000, 96000, 0x50},
 419        {11289600, 44100, 0x01},
 420        {11289600, 88200, 0x41},
 421        {11289600, 176400, 0x81},
 422        {12000000, 44100, 0x03},
 423        {12000000, 48000, 0x13},
 424        {12000000, 88200, 0x43},
 425        {12000000, 96000, 0x53},
 426        {12000000, 176400, 0x83},
 427        {12000000, 192000, 0x93},
 428        {12288000, 48000, 0x11},
 429        {12288000, 96000, 0x51},
 430        {12288000, 192000, 0x91},
 431        {13000000, 44100, 0x07},
 432        {13000000, 48000, 0x17},
 433        {13000000, 88200, 0x47},
 434        {13000000, 96000, 0x57},
 435        {13000000, 176400, 0x87},
 436        {13000000, 192000, 0x97},
 437        {22579200, 44100, 0x02},
 438        {22579200, 88200, 0x42},
 439        {22579200, 176400, 0x82},
 440        {24000000, 44100, 0x0B},
 441        {24000000, 48000, 0x1B},
 442        {24000000, 88200, 0x4B},
 443        {24000000, 96000, 0x5B},
 444        {24000000, 176400, 0x8B},
 445        {24000000, 192000, 0x9B},
 446        {24576000, 48000, 0x12},
 447        {24576000, 96000, 0x52},
 448        {24576000, 192000, 0x92},
 449        {26000000, 44100, 0x0F},
 450        {26000000, 48000, 0x1F},
 451        {26000000, 88200, 0x4F},
 452        {26000000, 96000, 0x5F},
 453        {26000000, 176400, 0x8F},
 454        {26000000, 192000, 0x9F},
 455};
 456
 457static int cs35l35_get_clk_config(int sysclk, int srate)
 458{
 459        int i;
 460
 461        for (i = 0; i < ARRAY_SIZE(cs35l35_clk_ctl); i++) {
 462                if (cs35l35_clk_ctl[i].sysclk == sysclk &&
 463                        cs35l35_clk_ctl[i].srate == srate)
 464                        return cs35l35_clk_ctl[i].clk_cfg;
 465        }
 466        return -EINVAL;
 467}
 468
 469static int cs35l35_hw_params(struct snd_pcm_substream *substream,
 470                                 struct snd_pcm_hw_params *params,
 471                                 struct snd_soc_dai *dai)
 472{
 473        struct snd_soc_component *component = dai->component;
 474        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 475        struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
 476        int srate = params_rate(params);
 477        int ret = 0;
 478        u8 sp_sclks;
 479        int audin_format;
 480        int errata_chk;
 481
 482        int clk_ctl = cs35l35_get_clk_config(cs35l35->sysclk, srate);
 483
 484        if (clk_ctl < 0) {
 485                dev_err(component->dev, "Invalid CLK:Rate %d:%d\n",
 486                        cs35l35->sysclk, srate);
 487                return -EINVAL;
 488        }
 489
 490        ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL2,
 491                          CS35L35_CLK_CTL2_MASK, clk_ctl);
 492        if (ret != 0) {
 493                dev_err(component->dev, "Failed to set port config %d\n", ret);
 494                return ret;
 495        }
 496
 497        /*
 498         * Rev A0 Errata
 499         * When configured for the weak-drive detection path (CH_WKFET_DIS = 0)
 500         * the Class H algorithm does not enable weak-drive operation for
 501         * nonzero values of CH_WKFET_DELAY if SP_RATE = 01 or 10
 502         */
 503        errata_chk = clk_ctl & CS35L35_SP_RATE_MASK;
 504
 505        if (classh->classh_wk_fet_disable == 0x00 &&
 506                (errata_chk == 0x01 || errata_chk == 0x03)) {
 507                ret = regmap_update_bits(cs35l35->regmap,
 508                                        CS35L35_CLASS_H_FET_DRIVE_CTL,
 509                                        CS35L35_CH_WKFET_DEL_MASK,
 510                                        0 << CS35L35_CH_WKFET_DEL_SHIFT);
 511                if (ret != 0) {
 512                        dev_err(component->dev, "Failed to set fet config %d\n",
 513                                ret);
 514                        return ret;
 515                }
 516        }
 517
 518        /*
 519         * You can pull more Monitor data from the SDOUT pin than going to SDIN
 520         * Just make sure your SCLK is fast enough to fill the frame
 521         */
 522        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 523                switch (params_width(params)) {
 524                case 8:
 525                        audin_format = CS35L35_SDIN_DEPTH_8;
 526                        break;
 527                case 16:
 528                        audin_format = CS35L35_SDIN_DEPTH_16;
 529                        break;
 530                case 24:
 531                        audin_format = CS35L35_SDIN_DEPTH_24;
 532                        break;
 533                default:
 534                        dev_err(component->dev, "Unsupported Width %d\n",
 535                                params_width(params));
 536                        return -EINVAL;
 537                }
 538                regmap_update_bits(cs35l35->regmap,
 539                                CS35L35_AUDIN_DEPTH_CTL,
 540                                CS35L35_AUDIN_DEPTH_MASK,
 541                                audin_format <<
 542                                CS35L35_AUDIN_DEPTH_SHIFT);
 543                if (cs35l35->pdata.stereo) {
 544                        regmap_update_bits(cs35l35->regmap,
 545                                        CS35L35_AUDIN_DEPTH_CTL,
 546                                        CS35L35_ADVIN_DEPTH_MASK,
 547                                        audin_format <<
 548                                        CS35L35_ADVIN_DEPTH_SHIFT);
 549                }
 550        }
 551
 552        if (cs35l35->i2s_mode) {
 553                /* We have to take the SCLK to derive num sclks
 554                 * to configure the CLOCK_CTL3 register correctly
 555                 */
 556                if ((cs35l35->sclk / srate) % 4) {
 557                        dev_err(component->dev, "Unsupported sclk/fs ratio %d:%d\n",
 558                                        cs35l35->sclk, srate);
 559                        return -EINVAL;
 560                }
 561                sp_sclks = ((cs35l35->sclk / srate) / 4) - 1;
 562
 563                /* Only certain ratios are supported in I2S Slave Mode */
 564                if (cs35l35->slave_mode) {
 565                        switch (sp_sclks) {
 566                        case CS35L35_SP_SCLKS_32FS:
 567                        case CS35L35_SP_SCLKS_48FS:
 568                        case CS35L35_SP_SCLKS_64FS:
 569                                break;
 570                        default:
 571                                dev_err(component->dev, "ratio not supported\n");
 572                                return -EINVAL;
 573                        }
 574                } else {
 575                        /* Only certain ratios supported in I2S MASTER Mode */
 576                        switch (sp_sclks) {
 577                        case CS35L35_SP_SCLKS_32FS:
 578                        case CS35L35_SP_SCLKS_64FS:
 579                                break;
 580                        default:
 581                                dev_err(component->dev, "ratio not supported\n");
 582                                return -EINVAL;
 583                        }
 584                }
 585                ret = regmap_update_bits(cs35l35->regmap,
 586                                        CS35L35_CLK_CTL3,
 587                                        CS35L35_SP_SCLKS_MASK, sp_sclks <<
 588                                        CS35L35_SP_SCLKS_SHIFT);
 589                if (ret != 0) {
 590                        dev_err(component->dev, "Failed to set fsclk %d\n", ret);
 591                        return ret;
 592                }
 593        }
 594
 595        return ret;
 596}
 597
 598static const unsigned int cs35l35_src_rates[] = {
 599        44100, 48000, 88200, 96000, 176400, 192000
 600};
 601
 602static const struct snd_pcm_hw_constraint_list cs35l35_constraints = {
 603        .count  = ARRAY_SIZE(cs35l35_src_rates),
 604        .list   = cs35l35_src_rates,
 605};
 606
 607static int cs35l35_pcm_startup(struct snd_pcm_substream *substream,
 608                               struct snd_soc_dai *dai)
 609{
 610        struct snd_soc_component *component = dai->component;
 611        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 612
 613        if (!substream->runtime)
 614                return 0;
 615
 616        snd_pcm_hw_constraint_list(substream->runtime, 0,
 617                                SNDRV_PCM_HW_PARAM_RATE, &cs35l35_constraints);
 618
 619        regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
 620                                        CS35L35_PDM_MODE_MASK,
 621                                        0 << CS35L35_PDM_MODE_SHIFT);
 622
 623        return 0;
 624}
 625
 626static const unsigned int cs35l35_pdm_rates[] = {
 627        44100, 48000, 88200, 96000
 628};
 629
 630static const struct snd_pcm_hw_constraint_list cs35l35_pdm_constraints = {
 631        .count  = ARRAY_SIZE(cs35l35_pdm_rates),
 632        .list   = cs35l35_pdm_rates,
 633};
 634
 635static int cs35l35_pdm_startup(struct snd_pcm_substream *substream,
 636                               struct snd_soc_dai *dai)
 637{
 638        struct snd_soc_component *component = dai->component;
 639        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 640
 641        if (!substream->runtime)
 642                return 0;
 643
 644        snd_pcm_hw_constraint_list(substream->runtime, 0,
 645                                SNDRV_PCM_HW_PARAM_RATE,
 646                                &cs35l35_pdm_constraints);
 647
 648        regmap_update_bits(cs35l35->regmap, CS35L35_AMP_INP_DRV_CTL,
 649                                        CS35L35_PDM_MODE_MASK,
 650                                        1 << CS35L35_PDM_MODE_SHIFT);
 651
 652        return 0;
 653}
 654
 655static int cs35l35_dai_set_sysclk(struct snd_soc_dai *dai,
 656                                int clk_id, unsigned int freq, int dir)
 657{
 658        struct snd_soc_component *component = dai->component;
 659        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 660
 661        /* Need the SCLK Frequency regardless of sysclk source for I2S */
 662        cs35l35->sclk = freq;
 663
 664        return 0;
 665}
 666
 667static const struct snd_soc_dai_ops cs35l35_ops = {
 668        .startup = cs35l35_pcm_startup,
 669        .set_fmt = cs35l35_set_dai_fmt,
 670        .hw_params = cs35l35_hw_params,
 671        .set_sysclk = cs35l35_dai_set_sysclk,
 672};
 673
 674static const struct snd_soc_dai_ops cs35l35_pdm_ops = {
 675        .startup = cs35l35_pdm_startup,
 676        .set_fmt = cs35l35_set_dai_fmt,
 677        .hw_params = cs35l35_hw_params,
 678};
 679
 680static struct snd_soc_dai_driver cs35l35_dai[] = {
 681        {
 682                .name = "cs35l35-pcm",
 683                .id = 0,
 684                .playback = {
 685                        .stream_name = "AMP Playback",
 686                        .channels_min = 1,
 687                        .channels_max = 8,
 688                        .rates = SNDRV_PCM_RATE_KNOT,
 689                        .formats = CS35L35_FORMATS,
 690                },
 691                .capture = {
 692                        .stream_name = "AMP Capture",
 693                        .channels_min = 1,
 694                        .channels_max = 8,
 695                        .rates = SNDRV_PCM_RATE_KNOT,
 696                        .formats = CS35L35_FORMATS,
 697                },
 698                .ops = &cs35l35_ops,
 699                .symmetric_rates = 1,
 700        },
 701        {
 702                .name = "cs35l35-pdm",
 703                .id = 1,
 704                .playback = {
 705                        .stream_name = "PDM Playback",
 706                        .channels_min = 1,
 707                        .channels_max = 2,
 708                        .rates = SNDRV_PCM_RATE_KNOT,
 709                        .formats = CS35L35_FORMATS,
 710                },
 711                .ops = &cs35l35_pdm_ops,
 712        },
 713};
 714
 715static int cs35l35_component_set_sysclk(struct snd_soc_component *component,
 716                                int clk_id, int source, unsigned int freq,
 717                                int dir)
 718{
 719        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 720        int clksrc;
 721        int ret = 0;
 722
 723        switch (clk_id) {
 724        case 0:
 725                clksrc = CS35L35_CLK_SOURCE_MCLK;
 726                break;
 727        case 1:
 728                clksrc = CS35L35_CLK_SOURCE_SCLK;
 729                break;
 730        case 2:
 731                clksrc = CS35L35_CLK_SOURCE_PDM;
 732                break;
 733        default:
 734                dev_err(component->dev, "Invalid CLK Source\n");
 735                return -EINVAL;
 736        }
 737
 738        switch (freq) {
 739        case 5644800:
 740        case 6144000:
 741        case 11289600:
 742        case 12000000:
 743        case 12288000:
 744        case 13000000:
 745        case 22579200:
 746        case 24000000:
 747        case 24576000:
 748        case 26000000:
 749                cs35l35->sysclk = freq;
 750                break;
 751        default:
 752                dev_err(component->dev, "Invalid CLK Frequency Input : %d\n", freq);
 753                return -EINVAL;
 754        }
 755
 756        ret = regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
 757                                CS35L35_CLK_SOURCE_MASK,
 758                                clksrc << CS35L35_CLK_SOURCE_SHIFT);
 759        if (ret != 0) {
 760                dev_err(component->dev, "Failed to set sysclk %d\n", ret);
 761                return ret;
 762        }
 763
 764        return ret;
 765}
 766
 767static int cs35l35_boost_inductor(struct cs35l35_private *cs35l35,
 768                                  int inductor)
 769{
 770        struct regmap *regmap = cs35l35->regmap;
 771        unsigned int bst_ipk = 0;
 772
 773        /*
 774         * Digital Boost Converter Configuration for feedback,
 775         * ramping, switching frequency, and estimation block seeding.
 776         */
 777
 778        regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
 779                           CS35L35_BST_CONV_SWFREQ_MASK, 0x00);
 780
 781        regmap_read(regmap, CS35L35_BST_PEAK_I, &bst_ipk);
 782        bst_ipk &= CS35L35_BST_IPK_MASK;
 783
 784        switch (inductor) {
 785        case 1000: /* 1 uH */
 786                regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x24);
 787                regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x24);
 788                regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
 789                                   CS35L35_BST_CONV_LBST_MASK, 0x00);
 790
 791                if (bst_ipk < 0x04)
 792                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
 793                else
 794                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x4E);
 795                break;
 796        case 1200: /* 1.2 uH */
 797                regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);
 798                regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);
 799                regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
 800                                   CS35L35_BST_CONV_LBST_MASK, 0x01);
 801
 802                if (bst_ipk < 0x04)
 803                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
 804                else
 805                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x47);
 806                break;
 807        case 1500: /* 1.5uH */
 808                regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x20);
 809                regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x20);
 810                regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
 811                                   CS35L35_BST_CONV_LBST_MASK, 0x02);
 812
 813                if (bst_ipk < 0x04)
 814                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
 815                else
 816                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x3C);
 817                break;
 818        case 2200: /* 2.2uH */
 819                regmap_write(regmap, CS35L35_BST_CONV_COEF_1, 0x19);
 820                regmap_write(regmap, CS35L35_BST_CONV_COEF_2, 0x25);
 821                regmap_update_bits(regmap, CS35L35_BST_CONV_SW_FREQ,
 822                                   CS35L35_BST_CONV_LBST_MASK, 0x03);
 823
 824                if (bst_ipk < 0x04)
 825                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x1B);
 826                else
 827                        regmap_write(regmap, CS35L35_BST_CONV_SLOPE_COMP, 0x23);
 828                break;
 829        default:
 830                dev_err(cs35l35->dev, "Invalid Inductor Value %d uH\n",
 831                        inductor);
 832                return -EINVAL;
 833        }
 834        return 0;
 835}
 836
 837static int cs35l35_component_probe(struct snd_soc_component *component)
 838{
 839        struct cs35l35_private *cs35l35 = snd_soc_component_get_drvdata(component);
 840        struct classh_cfg *classh = &cs35l35->pdata.classh_algo;
 841        struct monitor_cfg *monitor_config = &cs35l35->pdata.mon_cfg;
 842        int ret;
 843
 844        /* Set Platform Data */
 845        if (cs35l35->pdata.bst_vctl)
 846                regmap_update_bits(cs35l35->regmap, CS35L35_BST_CVTR_V_CTL,
 847                                CS35L35_BST_CTL_MASK,
 848                                cs35l35->pdata.bst_vctl);
 849
 850        if (cs35l35->pdata.bst_ipk)
 851                regmap_update_bits(cs35l35->regmap, CS35L35_BST_PEAK_I,
 852                                CS35L35_BST_IPK_MASK,
 853                                cs35l35->pdata.bst_ipk <<
 854                                CS35L35_BST_IPK_SHIFT);
 855
 856        ret = cs35l35_boost_inductor(cs35l35, cs35l35->pdata.boost_ind);
 857        if (ret)
 858                return ret;
 859
 860        if (cs35l35->pdata.gain_zc)
 861                regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
 862                                CS35L35_AMP_GAIN_ZC_MASK,
 863                                cs35l35->pdata.gain_zc <<
 864                                CS35L35_AMP_GAIN_ZC_SHIFT);
 865
 866        if (cs35l35->pdata.aud_channel)
 867                regmap_update_bits(cs35l35->regmap,
 868                                CS35L35_AUDIN_RXLOC_CTL,
 869                                CS35L35_AUD_IN_LR_MASK,
 870                                cs35l35->pdata.aud_channel <<
 871                                CS35L35_AUD_IN_LR_SHIFT);
 872
 873        if (cs35l35->pdata.stereo) {
 874                regmap_update_bits(cs35l35->regmap,
 875                                CS35L35_ADVIN_RXLOC_CTL,
 876                                CS35L35_ADV_IN_LR_MASK,
 877                                cs35l35->pdata.adv_channel <<
 878                                CS35L35_ADV_IN_LR_SHIFT);
 879                if (cs35l35->pdata.shared_bst)
 880                        regmap_update_bits(cs35l35->regmap, CS35L35_CLASS_H_CTL,
 881                                        CS35L35_CH_STEREO_MASK,
 882                                        1 << CS35L35_CH_STEREO_SHIFT);
 883                ret = snd_soc_add_component_controls(component, cs35l35_adv_controls,
 884                                        ARRAY_SIZE(cs35l35_adv_controls));
 885                if (ret)
 886                        return ret;
 887        }
 888
 889        if (cs35l35->pdata.sp_drv_str)
 890                regmap_update_bits(cs35l35->regmap, CS35L35_CLK_CTL1,
 891                                CS35L35_SP_DRV_MASK,
 892                                cs35l35->pdata.sp_drv_str <<
 893                                CS35L35_SP_DRV_SHIFT);
 894        if (cs35l35->pdata.sp_drv_unused)
 895                regmap_update_bits(cs35l35->regmap, CS35L35_SP_FMT_CTL3,
 896                                   CS35L35_SP_I2S_DRV_MASK,
 897                                   cs35l35->pdata.sp_drv_unused <<
 898                                   CS35L35_SP_I2S_DRV_SHIFT);
 899
 900        if (classh->classh_algo_enable) {
 901                if (classh->classh_bst_override)
 902                        regmap_update_bits(cs35l35->regmap,
 903                                        CS35L35_CLASS_H_CTL,
 904                                        CS35L35_CH_BST_OVR_MASK,
 905                                        classh->classh_bst_override <<
 906                                        CS35L35_CH_BST_OVR_SHIFT);
 907                if (classh->classh_bst_max_limit)
 908                        regmap_update_bits(cs35l35->regmap,
 909                                        CS35L35_CLASS_H_CTL,
 910                                        CS35L35_CH_BST_LIM_MASK,
 911                                        classh->classh_bst_max_limit <<
 912                                        CS35L35_CH_BST_LIM_SHIFT);
 913                if (classh->classh_mem_depth)
 914                        regmap_update_bits(cs35l35->regmap,
 915                                        CS35L35_CLASS_H_CTL,
 916                                        CS35L35_CH_MEM_DEPTH_MASK,
 917                                        classh->classh_mem_depth <<
 918                                        CS35L35_CH_MEM_DEPTH_SHIFT);
 919                if (classh->classh_headroom)
 920                        regmap_update_bits(cs35l35->regmap,
 921                                        CS35L35_CLASS_H_HEADRM_CTL,
 922                                        CS35L35_CH_HDRM_CTL_MASK,
 923                                        classh->classh_headroom <<
 924                                        CS35L35_CH_HDRM_CTL_SHIFT);
 925                if (classh->classh_release_rate)
 926                        regmap_update_bits(cs35l35->regmap,
 927                                        CS35L35_CLASS_H_RELEASE_RATE,
 928                                        CS35L35_CH_REL_RATE_MASK,
 929                                        classh->classh_release_rate <<
 930                                        CS35L35_CH_REL_RATE_SHIFT);
 931                if (classh->classh_wk_fet_disable)
 932                        regmap_update_bits(cs35l35->regmap,
 933                                        CS35L35_CLASS_H_FET_DRIVE_CTL,
 934                                        CS35L35_CH_WKFET_DIS_MASK,
 935                                        classh->classh_wk_fet_disable <<
 936                                        CS35L35_CH_WKFET_DIS_SHIFT);
 937                if (classh->classh_wk_fet_delay)
 938                        regmap_update_bits(cs35l35->regmap,
 939                                        CS35L35_CLASS_H_FET_DRIVE_CTL,
 940                                        CS35L35_CH_WKFET_DEL_MASK,
 941                                        classh->classh_wk_fet_delay <<
 942                                        CS35L35_CH_WKFET_DEL_SHIFT);
 943                if (classh->classh_wk_fet_thld)
 944                        regmap_update_bits(cs35l35->regmap,
 945                                        CS35L35_CLASS_H_FET_DRIVE_CTL,
 946                                        CS35L35_CH_WKFET_THLD_MASK,
 947                                        classh->classh_wk_fet_thld <<
 948                                        CS35L35_CH_WKFET_THLD_SHIFT);
 949                if (classh->classh_vpch_auto)
 950                        regmap_update_bits(cs35l35->regmap,
 951                                        CS35L35_CLASS_H_VP_CTL,
 952                                        CS35L35_CH_VP_AUTO_MASK,
 953                                        classh->classh_vpch_auto <<
 954                                        CS35L35_CH_VP_AUTO_SHIFT);
 955                if (classh->classh_vpch_rate)
 956                        regmap_update_bits(cs35l35->regmap,
 957                                        CS35L35_CLASS_H_VP_CTL,
 958                                        CS35L35_CH_VP_RATE_MASK,
 959                                        classh->classh_vpch_rate <<
 960                                        CS35L35_CH_VP_RATE_SHIFT);
 961                if (classh->classh_vpch_man)
 962                        regmap_update_bits(cs35l35->regmap,
 963                                        CS35L35_CLASS_H_VP_CTL,
 964                                        CS35L35_CH_VP_MAN_MASK,
 965                                        classh->classh_vpch_man <<
 966                                        CS35L35_CH_VP_MAN_SHIFT);
 967        }
 968
 969        if (monitor_config->is_present) {
 970                if (monitor_config->vmon_specs) {
 971                        regmap_update_bits(cs35l35->regmap,
 972                                        CS35L35_SPKMON_DEPTH_CTL,
 973                                        CS35L35_VMON_DEPTH_MASK,
 974                                        monitor_config->vmon_dpth <<
 975                                        CS35L35_VMON_DEPTH_SHIFT);
 976                        regmap_update_bits(cs35l35->regmap,
 977                                        CS35L35_VMON_TXLOC_CTL,
 978                                        CS35L35_MON_TXLOC_MASK,
 979                                        monitor_config->vmon_loc <<
 980                                        CS35L35_MON_TXLOC_SHIFT);
 981                        regmap_update_bits(cs35l35->regmap,
 982                                        CS35L35_VMON_TXLOC_CTL,
 983                                        CS35L35_MON_FRM_MASK,
 984                                        monitor_config->vmon_frm <<
 985                                        CS35L35_MON_FRM_SHIFT);
 986                }
 987                if (monitor_config->imon_specs) {
 988                        regmap_update_bits(cs35l35->regmap,
 989                                        CS35L35_SPKMON_DEPTH_CTL,
 990                                        CS35L35_IMON_DEPTH_MASK,
 991                                        monitor_config->imon_dpth <<
 992                                        CS35L35_IMON_DEPTH_SHIFT);
 993                        regmap_update_bits(cs35l35->regmap,
 994                                        CS35L35_IMON_TXLOC_CTL,
 995                                        CS35L35_MON_TXLOC_MASK,
 996                                        monitor_config->imon_loc <<
 997                                        CS35L35_MON_TXLOC_SHIFT);
 998                        regmap_update_bits(cs35l35->regmap,
 999                                        CS35L35_IMON_TXLOC_CTL,
1000                                        CS35L35_MON_FRM_MASK,
1001                                        monitor_config->imon_frm <<
1002                                        CS35L35_MON_FRM_SHIFT);
1003                        regmap_update_bits(cs35l35->regmap,
1004                                        CS35L35_IMON_SCALE_CTL,
1005                                        CS35L35_IMON_SCALE_MASK,
1006                                        monitor_config->imon_scale <<
1007                                        CS35L35_IMON_SCALE_SHIFT);
1008                }
1009                if (monitor_config->vpmon_specs) {
1010                        regmap_update_bits(cs35l35->regmap,
1011                                        CS35L35_SUPMON_DEPTH_CTL,
1012                                        CS35L35_VPMON_DEPTH_MASK,
1013                                        monitor_config->vpmon_dpth <<
1014                                        CS35L35_VPMON_DEPTH_SHIFT);
1015                        regmap_update_bits(cs35l35->regmap,
1016                                        CS35L35_VPMON_TXLOC_CTL,
1017                                        CS35L35_MON_TXLOC_MASK,
1018                                        monitor_config->vpmon_loc <<
1019                                        CS35L35_MON_TXLOC_SHIFT);
1020                        regmap_update_bits(cs35l35->regmap,
1021                                        CS35L35_VPMON_TXLOC_CTL,
1022                                        CS35L35_MON_FRM_MASK,
1023                                        monitor_config->vpmon_frm <<
1024                                        CS35L35_MON_FRM_SHIFT);
1025                }
1026                if (monitor_config->vbstmon_specs) {
1027                        regmap_update_bits(cs35l35->regmap,
1028                                        CS35L35_SUPMON_DEPTH_CTL,
1029                                        CS35L35_VBSTMON_DEPTH_MASK,
1030                                        monitor_config->vpmon_dpth <<
1031                                        CS35L35_VBSTMON_DEPTH_SHIFT);
1032                        regmap_update_bits(cs35l35->regmap,
1033                                        CS35L35_VBSTMON_TXLOC_CTL,
1034                                        CS35L35_MON_TXLOC_MASK,
1035                                        monitor_config->vbstmon_loc <<
1036                                        CS35L35_MON_TXLOC_SHIFT);
1037                        regmap_update_bits(cs35l35->regmap,
1038                                        CS35L35_VBSTMON_TXLOC_CTL,
1039                                        CS35L35_MON_FRM_MASK,
1040                                        monitor_config->vbstmon_frm <<
1041                                        CS35L35_MON_FRM_SHIFT);
1042                }
1043                if (monitor_config->vpbrstat_specs) {
1044                        regmap_update_bits(cs35l35->regmap,
1045                                        CS35L35_SUPMON_DEPTH_CTL,
1046                                        CS35L35_VPBRSTAT_DEPTH_MASK,
1047                                        monitor_config->vpbrstat_dpth <<
1048                                        CS35L35_VPBRSTAT_DEPTH_SHIFT);
1049                        regmap_update_bits(cs35l35->regmap,
1050                                        CS35L35_VPBR_STATUS_TXLOC_CTL,
1051                                        CS35L35_MON_TXLOC_MASK,
1052                                        monitor_config->vpbrstat_loc <<
1053                                        CS35L35_MON_TXLOC_SHIFT);
1054                        regmap_update_bits(cs35l35->regmap,
1055                                        CS35L35_VPBR_STATUS_TXLOC_CTL,
1056                                        CS35L35_MON_FRM_MASK,
1057                                        monitor_config->vpbrstat_frm <<
1058                                        CS35L35_MON_FRM_SHIFT);
1059                }
1060                if (monitor_config->zerofill_specs) {
1061                        regmap_update_bits(cs35l35->regmap,
1062                                        CS35L35_SUPMON_DEPTH_CTL,
1063                                        CS35L35_ZEROFILL_DEPTH_MASK,
1064                                        monitor_config->zerofill_dpth <<
1065                                        CS35L35_ZEROFILL_DEPTH_SHIFT);
1066                        regmap_update_bits(cs35l35->regmap,
1067                                        CS35L35_ZERO_FILL_LOC_CTL,
1068                                        CS35L35_MON_TXLOC_MASK,
1069                                        monitor_config->zerofill_loc <<
1070                                        CS35L35_MON_TXLOC_SHIFT);
1071                        regmap_update_bits(cs35l35->regmap,
1072                                        CS35L35_ZERO_FILL_LOC_CTL,
1073                                        CS35L35_MON_FRM_MASK,
1074                                        monitor_config->zerofill_frm <<
1075                                        CS35L35_MON_FRM_SHIFT);
1076                }
1077        }
1078
1079        return 0;
1080}
1081
1082static const struct snd_soc_component_driver soc_component_dev_cs35l35 = {
1083        .probe                  = cs35l35_component_probe,
1084        .set_sysclk             = cs35l35_component_set_sysclk,
1085        .dapm_widgets           = cs35l35_dapm_widgets,
1086        .num_dapm_widgets       = ARRAY_SIZE(cs35l35_dapm_widgets),
1087        .dapm_routes            = cs35l35_audio_map,
1088        .num_dapm_routes        = ARRAY_SIZE(cs35l35_audio_map),
1089        .controls               = cs35l35_aud_controls,
1090        .num_controls           = ARRAY_SIZE(cs35l35_aud_controls),
1091        .idle_bias_on           = 1,
1092        .use_pmdown_time        = 1,
1093        .endianness             = 1,
1094        .non_legacy_dai_naming  = 1,
1095};
1096
1097static struct regmap_config cs35l35_regmap = {
1098        .reg_bits = 8,
1099        .val_bits = 8,
1100
1101        .max_register = CS35L35_MAX_REGISTER,
1102        .reg_defaults = cs35l35_reg,
1103        .num_reg_defaults = ARRAY_SIZE(cs35l35_reg),
1104        .volatile_reg = cs35l35_volatile_register,
1105        .readable_reg = cs35l35_readable_register,
1106        .precious_reg = cs35l35_precious_register,
1107        .cache_type = REGCACHE_RBTREE,
1108};
1109
1110static irqreturn_t cs35l35_irq(int irq, void *data)
1111{
1112        struct cs35l35_private *cs35l35 = data;
1113        unsigned int sticky1, sticky2, sticky3, sticky4;
1114        unsigned int mask1, mask2, mask3, mask4, current1;
1115
1116        /* ack the irq by reading all status registers */
1117        regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_4, &sticky4);
1118        regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_3, &sticky3);
1119        regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_2, &sticky2);
1120        regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &sticky1);
1121
1122        regmap_read(cs35l35->regmap, CS35L35_INT_MASK_4, &mask4);
1123        regmap_read(cs35l35->regmap, CS35L35_INT_MASK_3, &mask3);
1124        regmap_read(cs35l35->regmap, CS35L35_INT_MASK_2, &mask2);
1125        regmap_read(cs35l35->regmap, CS35L35_INT_MASK_1, &mask1);
1126
1127        /* Check to see if unmasked bits are active */
1128        if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)
1129                        && !(sticky4 & ~mask4))
1130                return IRQ_NONE;
1131
1132        if (sticky2 & CS35L35_PDN_DONE)
1133                complete(&cs35l35->pdn_done);
1134
1135        /* read the current values */
1136        regmap_read(cs35l35->regmap, CS35L35_INT_STATUS_1, &current1);
1137
1138        /* handle the interrupts */
1139        if (sticky1 & CS35L35_CAL_ERR) {
1140                dev_crit(cs35l35->dev, "Calibration Error\n");
1141
1142                /* error is no longer asserted; safe to reset */
1143                if (!(current1 & CS35L35_CAL_ERR)) {
1144                        pr_debug("%s : Cal error release\n", __func__);
1145                        regmap_update_bits(cs35l35->regmap,
1146                                        CS35L35_PROT_RELEASE_CTL,
1147                                        CS35L35_CAL_ERR_RLS, 0);
1148                        regmap_update_bits(cs35l35->regmap,
1149                                        CS35L35_PROT_RELEASE_CTL,
1150                                        CS35L35_CAL_ERR_RLS,
1151                                        CS35L35_CAL_ERR_RLS);
1152                        regmap_update_bits(cs35l35->regmap,
1153                                        CS35L35_PROT_RELEASE_CTL,
1154                                        CS35L35_CAL_ERR_RLS, 0);
1155                }
1156        }
1157
1158        if (sticky1 & CS35L35_AMP_SHORT) {
1159                dev_crit(cs35l35->dev, "AMP Short Error\n");
1160                /* error is no longer asserted; safe to reset */
1161                if (!(current1 & CS35L35_AMP_SHORT)) {
1162                        dev_dbg(cs35l35->dev, "Amp short error release\n");
1163                        regmap_update_bits(cs35l35->regmap,
1164                                        CS35L35_PROT_RELEASE_CTL,
1165                                        CS35L35_SHORT_RLS, 0);
1166                        regmap_update_bits(cs35l35->regmap,
1167                                        CS35L35_PROT_RELEASE_CTL,
1168                                        CS35L35_SHORT_RLS,
1169                                        CS35L35_SHORT_RLS);
1170                        regmap_update_bits(cs35l35->regmap,
1171                                        CS35L35_PROT_RELEASE_CTL,
1172                                        CS35L35_SHORT_RLS, 0);
1173                }
1174        }
1175
1176        if (sticky1 & CS35L35_OTW) {
1177                dev_warn(cs35l35->dev, "Over temperature warning\n");
1178
1179                /* error is no longer asserted; safe to reset */
1180                if (!(current1 & CS35L35_OTW)) {
1181                        dev_dbg(cs35l35->dev, "Over temperature warn release\n");
1182                        regmap_update_bits(cs35l35->regmap,
1183                                        CS35L35_PROT_RELEASE_CTL,
1184                                        CS35L35_OTW_RLS, 0);
1185                        regmap_update_bits(cs35l35->regmap,
1186                                        CS35L35_PROT_RELEASE_CTL,
1187                                        CS35L35_OTW_RLS,
1188                                        CS35L35_OTW_RLS);
1189                        regmap_update_bits(cs35l35->regmap,
1190                                        CS35L35_PROT_RELEASE_CTL,
1191                                        CS35L35_OTW_RLS, 0);
1192                }
1193        }
1194
1195        if (sticky1 & CS35L35_OTE) {
1196                dev_crit(cs35l35->dev, "Over temperature error\n");
1197                /* error is no longer asserted; safe to reset */
1198                if (!(current1 & CS35L35_OTE)) {
1199                        dev_dbg(cs35l35->dev, "Over temperature error release\n");
1200                        regmap_update_bits(cs35l35->regmap,
1201                                        CS35L35_PROT_RELEASE_CTL,
1202                                        CS35L35_OTE_RLS, 0);
1203                        regmap_update_bits(cs35l35->regmap,
1204                                        CS35L35_PROT_RELEASE_CTL,
1205                                        CS35L35_OTE_RLS,
1206                                        CS35L35_OTE_RLS);
1207                        regmap_update_bits(cs35l35->regmap,
1208                                        CS35L35_PROT_RELEASE_CTL,
1209                                        CS35L35_OTE_RLS, 0);
1210                }
1211        }
1212
1213        if (sticky3 & CS35L35_BST_HIGH) {
1214                dev_crit(cs35l35->dev, "VBST error: powering off!\n");
1215                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1216                        CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1217                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1218                        CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1219        }
1220
1221        if (sticky3 & CS35L35_LBST_SHORT) {
1222                dev_crit(cs35l35->dev, "LBST error: powering off!\n");
1223                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1224                        CS35L35_PDN_AMP, CS35L35_PDN_AMP);
1225                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL1,
1226                        CS35L35_PDN_ALL, CS35L35_PDN_ALL);
1227        }
1228
1229        if (sticky2 & CS35L35_VPBR_ERR)
1230                dev_dbg(cs35l35->dev, "Error: Reactive Brownout\n");
1231
1232        if (sticky4 & CS35L35_VMON_OVFL)
1233                dev_dbg(cs35l35->dev, "Error: VMON overflow\n");
1234
1235        if (sticky4 & CS35L35_IMON_OVFL)
1236                dev_dbg(cs35l35->dev, "Error: IMON overflow\n");
1237
1238        return IRQ_HANDLED;
1239}
1240
1241
1242static int cs35l35_handle_of_data(struct i2c_client *i2c_client,
1243                                struct cs35l35_platform_data *pdata)
1244{
1245        struct device_node *np = i2c_client->dev.of_node;
1246        struct device_node *classh, *signal_format;
1247        struct classh_cfg *classh_config = &pdata->classh_algo;
1248        struct monitor_cfg *monitor_config = &pdata->mon_cfg;
1249        unsigned int val32 = 0;
1250        u8 monitor_array[4];
1251        const int imon_array_size = ARRAY_SIZE(monitor_array);
1252        const int mon_array_size = imon_array_size - 1;
1253        int ret = 0;
1254
1255        if (!np)
1256                return 0;
1257
1258        pdata->bst_pdn_fet_on = of_property_read_bool(np,
1259                                        "cirrus,boost-pdn-fet-on");
1260
1261        ret = of_property_read_u32(np, "cirrus,boost-ctl-millivolt", &val32);
1262        if (ret >= 0) {
1263                if (val32 < 2600 || val32 > 9000) {
1264                        dev_err(&i2c_client->dev,
1265                                "Invalid Boost Voltage %d mV\n", val32);
1266                        return -EINVAL;
1267                }
1268                pdata->bst_vctl = ((val32 - 2600) / 100) + 1;
1269        }
1270
1271        ret = of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val32);
1272        if (ret >= 0) {
1273                if (val32 < 1680 || val32 > 4480) {
1274                        dev_err(&i2c_client->dev,
1275                                "Invalid Boost Peak Current %u mA\n", val32);
1276                        return -EINVAL;
1277                }
1278
1279                pdata->bst_ipk = ((val32 - 1680) / 110) | CS35L35_VALID_PDATA;
1280        }
1281
1282        ret = of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val32);
1283        if (ret >= 0) {
1284                pdata->boost_ind = val32;
1285        } else {
1286                dev_err(&i2c_client->dev, "Inductor not specified.\n");
1287                return -EINVAL;
1288        }
1289
1290        if (of_property_read_u32(np, "cirrus,sp-drv-strength", &val32) >= 0)
1291                pdata->sp_drv_str = val32;
1292        if (of_property_read_u32(np, "cirrus,sp-drv-unused", &val32) >= 0)
1293                pdata->sp_drv_unused = val32 | CS35L35_VALID_PDATA;
1294
1295        pdata->stereo = of_property_read_bool(np, "cirrus,stereo-config");
1296
1297        if (pdata->stereo) {
1298                ret = of_property_read_u32(np, "cirrus,audio-channel", &val32);
1299                if (ret >= 0)
1300                        pdata->aud_channel = val32;
1301
1302                ret = of_property_read_u32(np, "cirrus,advisory-channel",
1303                                           &val32);
1304                if (ret >= 0)
1305                        pdata->adv_channel = val32;
1306
1307                pdata->shared_bst = of_property_read_bool(np,
1308                                                "cirrus,shared-boost");
1309        }
1310
1311        pdata->ext_bst = of_property_read_bool(np, "cirrus,external-boost");
1312
1313        pdata->gain_zc = of_property_read_bool(np, "cirrus,amp-gain-zc");
1314
1315        classh = of_get_child_by_name(np, "cirrus,classh-internal-algo");
1316        classh_config->classh_algo_enable = classh ? true : false;
1317
1318        if (classh_config->classh_algo_enable) {
1319                classh_config->classh_bst_override =
1320                        of_property_read_bool(np, "cirrus,classh-bst-overide");
1321
1322                ret = of_property_read_u32(classh,
1323                                           "cirrus,classh-bst-max-limit",
1324                                           &val32);
1325                if (ret >= 0) {
1326                        val32 |= CS35L35_VALID_PDATA;
1327                        classh_config->classh_bst_max_limit = val32;
1328                }
1329
1330                ret = of_property_read_u32(classh,
1331                                           "cirrus,classh-bst-max-limit",
1332                                           &val32);
1333                if (ret >= 0) {
1334                        val32 |= CS35L35_VALID_PDATA;
1335                        classh_config->classh_bst_max_limit = val32;
1336                }
1337
1338                ret = of_property_read_u32(classh, "cirrus,classh-mem-depth",
1339                                           &val32);
1340                if (ret >= 0) {
1341                        val32 |= CS35L35_VALID_PDATA;
1342                        classh_config->classh_mem_depth = val32;
1343                }
1344
1345                ret = of_property_read_u32(classh, "cirrus,classh-release-rate",
1346                                           &val32);
1347                if (ret >= 0)
1348                        classh_config->classh_release_rate = val32;
1349
1350                ret = of_property_read_u32(classh, "cirrus,classh-headroom",
1351                                           &val32);
1352                if (ret >= 0) {
1353                        val32 |= CS35L35_VALID_PDATA;
1354                        classh_config->classh_headroom = val32;
1355                }
1356
1357                ret = of_property_read_u32(classh,
1358                                           "cirrus,classh-wk-fet-disable",
1359                                           &val32);
1360                if (ret >= 0)
1361                        classh_config->classh_wk_fet_disable = val32;
1362
1363                ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-delay",
1364                                           &val32);
1365                if (ret >= 0) {
1366                        val32 |= CS35L35_VALID_PDATA;
1367                        classh_config->classh_wk_fet_delay = val32;
1368                }
1369
1370                ret = of_property_read_u32(classh, "cirrus,classh-wk-fet-thld",
1371                                           &val32);
1372                if (ret >= 0)
1373                        classh_config->classh_wk_fet_thld = val32;
1374
1375                ret = of_property_read_u32(classh, "cirrus,classh-vpch-auto",
1376                                           &val32);
1377                if (ret >= 0) {
1378                        val32 |= CS35L35_VALID_PDATA;
1379                        classh_config->classh_vpch_auto = val32;
1380                }
1381
1382                ret = of_property_read_u32(classh, "cirrus,classh-vpch-rate",
1383                                           &val32);
1384                if (ret >= 0) {
1385                        val32 |= CS35L35_VALID_PDATA;
1386                        classh_config->classh_vpch_rate = val32;
1387                }
1388
1389                ret = of_property_read_u32(classh, "cirrus,classh-vpch-man",
1390                                           &val32);
1391                if (ret >= 0)
1392                        classh_config->classh_vpch_man = val32;
1393        }
1394        of_node_put(classh);
1395
1396        /* frame depth location */
1397        signal_format = of_get_child_by_name(np, "cirrus,monitor-signal-format");
1398        monitor_config->is_present = signal_format ? true : false;
1399        if (monitor_config->is_present) {
1400                ret = of_property_read_u8_array(signal_format, "cirrus,imon",
1401                                                monitor_array, imon_array_size);
1402                if (!ret) {
1403                        monitor_config->imon_specs = true;
1404                        monitor_config->imon_dpth = monitor_array[0];
1405                        monitor_config->imon_loc = monitor_array[1];
1406                        monitor_config->imon_frm = monitor_array[2];
1407                        monitor_config->imon_scale = monitor_array[3];
1408                }
1409                ret = of_property_read_u8_array(signal_format, "cirrus,vmon",
1410                                                monitor_array, mon_array_size);
1411                if (!ret) {
1412                        monitor_config->vmon_specs = true;
1413                        monitor_config->vmon_dpth = monitor_array[0];
1414                        monitor_config->vmon_loc = monitor_array[1];
1415                        monitor_config->vmon_frm = monitor_array[2];
1416                }
1417                ret = of_property_read_u8_array(signal_format, "cirrus,vpmon",
1418                                                monitor_array, mon_array_size);
1419                if (!ret) {
1420                        monitor_config->vpmon_specs = true;
1421                        monitor_config->vpmon_dpth = monitor_array[0];
1422                        monitor_config->vpmon_loc = monitor_array[1];
1423                        monitor_config->vpmon_frm = monitor_array[2];
1424                }
1425                ret = of_property_read_u8_array(signal_format, "cirrus,vbstmon",
1426                                                monitor_array, mon_array_size);
1427                if (!ret) {
1428                        monitor_config->vbstmon_specs = true;
1429                        monitor_config->vbstmon_dpth = monitor_array[0];
1430                        monitor_config->vbstmon_loc = monitor_array[1];
1431                        monitor_config->vbstmon_frm = monitor_array[2];
1432                }
1433                ret = of_property_read_u8_array(signal_format, "cirrus,vpbrstat",
1434                                                monitor_array, mon_array_size);
1435                if (!ret) {
1436                        monitor_config->vpbrstat_specs = true;
1437                        monitor_config->vpbrstat_dpth = monitor_array[0];
1438                        monitor_config->vpbrstat_loc = monitor_array[1];
1439                        monitor_config->vpbrstat_frm = monitor_array[2];
1440                }
1441                ret = of_property_read_u8_array(signal_format, "cirrus,zerofill",
1442                                                monitor_array, mon_array_size);
1443                if (!ret) {
1444                        monitor_config->zerofill_specs = true;
1445                        monitor_config->zerofill_dpth = monitor_array[0];
1446                        monitor_config->zerofill_loc = monitor_array[1];
1447                        monitor_config->zerofill_frm = monitor_array[2];
1448                }
1449        }
1450        of_node_put(signal_format);
1451
1452        return 0;
1453}
1454
1455/* Errata Rev A0 */
1456static const struct reg_sequence cs35l35_errata_patch[] = {
1457
1458        { 0x7F, 0x99 },
1459        { 0x00, 0x99 },
1460        { 0x52, 0x22 },
1461        { 0x04, 0x14 },
1462        { 0x6D, 0x44 },
1463        { 0x24, 0x10 },
1464        { 0x58, 0xC4 },
1465        { 0x00, 0x98 },
1466        { 0x18, 0x08 },
1467        { 0x00, 0x00 },
1468        { 0x7F, 0x00 },
1469};
1470
1471static int cs35l35_i2c_probe(struct i2c_client *i2c_client,
1472                              const struct i2c_device_id *id)
1473{
1474        struct cs35l35_private *cs35l35;
1475        struct device *dev = &i2c_client->dev;
1476        struct cs35l35_platform_data *pdata = dev_get_platdata(dev);
1477        int i;
1478        int ret;
1479        unsigned int devid = 0;
1480        unsigned int reg;
1481
1482        cs35l35 = devm_kzalloc(dev, sizeof(struct cs35l35_private), GFP_KERNEL);
1483        if (!cs35l35)
1484                return -ENOMEM;
1485
1486        cs35l35->dev = dev;
1487
1488        i2c_set_clientdata(i2c_client, cs35l35);
1489        cs35l35->regmap = devm_regmap_init_i2c(i2c_client, &cs35l35_regmap);
1490        if (IS_ERR(cs35l35->regmap)) {
1491                ret = PTR_ERR(cs35l35->regmap);
1492                dev_err(dev, "regmap_init() failed: %d\n", ret);
1493                goto err;
1494        }
1495
1496        for (i = 0; i < ARRAY_SIZE(cs35l35_supplies); i++)
1497                cs35l35->supplies[i].supply = cs35l35_supplies[i];
1498
1499        cs35l35->num_supplies = ARRAY_SIZE(cs35l35_supplies);
1500
1501        ret = devm_regulator_bulk_get(dev, cs35l35->num_supplies,
1502                                      cs35l35->supplies);
1503        if (ret != 0) {
1504                dev_err(dev, "Failed to request core supplies: %d\n", ret);
1505                return ret;
1506        }
1507
1508        if (pdata) {
1509                cs35l35->pdata = *pdata;
1510        } else {
1511                pdata = devm_kzalloc(dev, sizeof(struct cs35l35_platform_data),
1512                                     GFP_KERNEL);
1513                if (!pdata)
1514                        return -ENOMEM;
1515                if (i2c_client->dev.of_node) {
1516                        ret = cs35l35_handle_of_data(i2c_client, pdata);
1517                        if (ret != 0)
1518                                return ret;
1519
1520                }
1521                cs35l35->pdata = *pdata;
1522        }
1523
1524        ret = regulator_bulk_enable(cs35l35->num_supplies,
1525                                        cs35l35->supplies);
1526        if (ret != 0) {
1527                dev_err(dev, "Failed to enable core supplies: %d\n", ret);
1528                return ret;
1529        }
1530
1531        /* returning NULL can be valid if in stereo mode */
1532        cs35l35->reset_gpio = devm_gpiod_get_optional(dev, "reset",
1533                                                      GPIOD_OUT_LOW);
1534        if (IS_ERR(cs35l35->reset_gpio)) {
1535                ret = PTR_ERR(cs35l35->reset_gpio);
1536                cs35l35->reset_gpio = NULL;
1537                if (ret == -EBUSY) {
1538                        dev_info(dev,
1539                                 "Reset line busy, assuming shared reset\n");
1540                } else {
1541                        dev_err(dev, "Failed to get reset GPIO: %d\n", ret);
1542                        goto err;
1543                }
1544        }
1545
1546        cs35l35_reset(cs35l35);
1547
1548        init_completion(&cs35l35->pdn_done);
1549
1550        ret = devm_request_threaded_irq(dev, i2c_client->irq, NULL, cs35l35_irq,
1551                                        IRQF_ONESHOT | IRQF_TRIGGER_LOW |
1552                                        IRQF_SHARED, "cs35l35", cs35l35);
1553        if (ret != 0) {
1554                dev_err(dev, "Failed to request IRQ: %d\n", ret);
1555                goto err;
1556        }
1557        /* initialize codec */
1558        ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_AB, &reg);
1559
1560        devid = (reg & 0xFF) << 12;
1561        ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_CD, &reg);
1562        devid |= (reg & 0xFF) << 4;
1563        ret = regmap_read(cs35l35->regmap, CS35L35_DEVID_E, &reg);
1564        devid |= (reg & 0xF0) >> 4;
1565
1566        if (devid != CS35L35_CHIP_ID) {
1567                dev_err(dev, "CS35L35 Device ID (%X). Expected ID %X\n",
1568                        devid, CS35L35_CHIP_ID);
1569                ret = -ENODEV;
1570                goto err;
1571        }
1572
1573        ret = regmap_read(cs35l35->regmap, CS35L35_REV_ID, &reg);
1574        if (ret < 0) {
1575                dev_err(dev, "Get Revision ID failed: %d\n", ret);
1576                goto err;
1577        }
1578
1579        ret = regmap_register_patch(cs35l35->regmap, cs35l35_errata_patch,
1580                                    ARRAY_SIZE(cs35l35_errata_patch));
1581        if (ret < 0) {
1582                dev_err(dev, "Failed to apply errata patch: %d\n", ret);
1583                goto err;
1584        }
1585
1586        dev_info(dev, "Cirrus Logic CS35L35 (%x), Revision: %02X\n",
1587                 devid, reg & 0xFF);
1588
1589        /* Set the INT Masks for critical errors */
1590        regmap_write(cs35l35->regmap, CS35L35_INT_MASK_1,
1591                                CS35L35_INT1_CRIT_MASK);
1592        regmap_write(cs35l35->regmap, CS35L35_INT_MASK_2,
1593                                CS35L35_INT2_CRIT_MASK);
1594        regmap_write(cs35l35->regmap, CS35L35_INT_MASK_3,
1595                                CS35L35_INT3_CRIT_MASK);
1596        regmap_write(cs35l35->regmap, CS35L35_INT_MASK_4,
1597                                CS35L35_INT4_CRIT_MASK);
1598
1599        regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1600                        CS35L35_PWR2_PDN_MASK,
1601                        CS35L35_PWR2_PDN_MASK);
1602
1603        if (cs35l35->pdata.bst_pdn_fet_on)
1604                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1605                                        CS35L35_PDN_BST_MASK,
1606                                        1 << CS35L35_PDN_BST_FETON_SHIFT);
1607        else
1608                regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL2,
1609                                        CS35L35_PDN_BST_MASK,
1610                                        1 << CS35L35_PDN_BST_FETOFF_SHIFT);
1611
1612        regmap_update_bits(cs35l35->regmap, CS35L35_PWRCTL3,
1613                        CS35L35_PWR3_PDN_MASK,
1614                        CS35L35_PWR3_PDN_MASK);
1615
1616        regmap_update_bits(cs35l35->regmap, CS35L35_PROTECT_CTL,
1617                CS35L35_AMP_MUTE_MASK, 1 << CS35L35_AMP_MUTE_SHIFT);
1618
1619        ret = devm_snd_soc_register_component(dev, &soc_component_dev_cs35l35,
1620                                        cs35l35_dai, ARRAY_SIZE(cs35l35_dai));
1621        if (ret < 0) {
1622                dev_err(dev, "Failed to register component: %d\n", ret);
1623                goto err;
1624        }
1625
1626        return 0;
1627
1628err:
1629        regulator_bulk_disable(cs35l35->num_supplies,
1630                               cs35l35->supplies);
1631        gpiod_set_value_cansleep(cs35l35->reset_gpio, 0);
1632
1633        return ret;
1634}
1635
1636static const struct of_device_id cs35l35_of_match[] = {
1637        {.compatible = "cirrus,cs35l35"},
1638        {},
1639};
1640MODULE_DEVICE_TABLE(of, cs35l35_of_match);
1641
1642static const struct i2c_device_id cs35l35_id[] = {
1643        {"cs35l35", 0},
1644        {}
1645};
1646
1647MODULE_DEVICE_TABLE(i2c, cs35l35_id);
1648
1649static struct i2c_driver cs35l35_i2c_driver = {
1650        .driver = {
1651                .name = "cs35l35",
1652                .of_match_table = cs35l35_of_match,
1653        },
1654        .id_table = cs35l35_id,
1655        .probe = cs35l35_i2c_probe,
1656};
1657
1658module_i2c_driver(cs35l35_i2c_driver);
1659
1660MODULE_DESCRIPTION("ASoC CS35L35 driver");
1661MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>");
1662MODULE_LICENSE("GPL");
1663