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