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