linux/sound/soc/codecs/cs35l34.c
<<
>>
Prefs
   1/*
   2 * cs35l34.c -- CS35l34 ALSA SoC audio driver
   3 *
   4 * Copyright 2016 Cirrus Logic, Inc.
   5 *
   6 * Author: Paul Handrigan <Paul.Handrigan@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/kernel.h>
  17#include <linux/init.h>
  18#include <linux/delay.h>
  19#include <linux/i2c.h>
  20#include <linux/slab.h>
  21#include <linux/workqueue.h>
  22#include <linux/platform_device.h>
  23#include <linux/regulator/consumer.h>
  24#include <linux/regulator/machine.h>
  25#include <linux/pm_runtime.h>
  26#include <linux/of_device.h>
  27#include <linux/of_gpio.h>
  28#include <linux/of_irq.h>
  29#include <sound/core.h>
  30#include <sound/pcm.h>
  31#include <sound/pcm_params.h>
  32#include <sound/soc.h>
  33#include <sound/soc-dapm.h>
  34#include <linux/gpio.h>
  35#include <linux/gpio/consumer.h>
  36#include <sound/initval.h>
  37#include <sound/tlv.h>
  38#include <sound/cs35l34.h>
  39
  40#include "cs35l34.h"
  41
  42#define PDN_DONE_ATTEMPTS 10
  43#define CS35L34_START_DELAY 50
  44
  45struct  cs35l34_private {
  46        struct snd_soc_component *component;
  47        struct cs35l34_platform_data pdata;
  48        struct regmap *regmap;
  49        struct regulator_bulk_data core_supplies[2];
  50        int num_core_supplies;
  51        int mclk_int;
  52        bool tdm_mode;
  53        struct gpio_desc *reset_gpio;   /* Active-low reset GPIO */
  54};
  55
  56static const struct reg_default cs35l34_reg[] = {
  57        {CS35L34_PWRCTL1, 0x01},
  58        {CS35L34_PWRCTL2, 0x19},
  59        {CS35L34_PWRCTL3, 0x01},
  60        {CS35L34_ADSP_CLK_CTL, 0x08},
  61        {CS35L34_MCLK_CTL, 0x11},
  62        {CS35L34_AMP_INP_DRV_CTL, 0x01},
  63        {CS35L34_AMP_DIG_VOL_CTL, 0x12},
  64        {CS35L34_AMP_DIG_VOL, 0x00},
  65        {CS35L34_AMP_ANLG_GAIN_CTL, 0x0F},
  66        {CS35L34_PROTECT_CTL, 0x06},
  67        {CS35L34_AMP_KEEP_ALIVE_CTL, 0x04},
  68        {CS35L34_BST_CVTR_V_CTL, 0x00},
  69        {CS35L34_BST_PEAK_I, 0x10},
  70        {CS35L34_BST_RAMP_CTL, 0x87},
  71        {CS35L34_BST_CONV_COEF_1, 0x24},
  72        {CS35L34_BST_CONV_COEF_2, 0x24},
  73        {CS35L34_BST_CONV_SLOPE_COMP, 0x4E},
  74        {CS35L34_BST_CONV_SW_FREQ, 0x08},
  75        {CS35L34_CLASS_H_CTL, 0x0D},
  76        {CS35L34_CLASS_H_HEADRM_CTL, 0x0D},
  77        {CS35L34_CLASS_H_RELEASE_RATE, 0x08},
  78        {CS35L34_CLASS_H_FET_DRIVE_CTL, 0x41},
  79        {CS35L34_CLASS_H_STATUS, 0x05},
  80        {CS35L34_VPBR_CTL, 0x0A},
  81        {CS35L34_VPBR_VOL_CTL, 0x90},
  82        {CS35L34_VPBR_TIMING_CTL, 0x6A},
  83        {CS35L34_PRED_MAX_ATTEN_SPK_LOAD, 0x95},
  84        {CS35L34_PRED_BROWNOUT_THRESH, 0x1C},
  85        {CS35L34_PRED_BROWNOUT_VOL_CTL, 0x00},
  86        {CS35L34_PRED_BROWNOUT_RATE_CTL, 0x10},
  87        {CS35L34_PRED_WAIT_CTL, 0x10},
  88        {CS35L34_PRED_ZVP_INIT_IMP_CTL, 0x08},
  89        {CS35L34_PRED_MAN_SAFE_VPI_CTL, 0x80},
  90        {CS35L34_VPBR_ATTEN_STATUS, 0x00},
  91        {CS35L34_PRED_BRWNOUT_ATT_STATUS, 0x00},
  92        {CS35L34_SPKR_MON_CTL, 0xC6},
  93        {CS35L34_ADSP_I2S_CTL, 0x00},
  94        {CS35L34_ADSP_TDM_CTL, 0x00},
  95        {CS35L34_TDM_TX_CTL_1_VMON, 0x00},
  96        {CS35L34_TDM_TX_CTL_2_IMON, 0x04},
  97        {CS35L34_TDM_TX_CTL_3_VPMON, 0x03},
  98        {CS35L34_TDM_TX_CTL_4_VBSTMON, 0x07},
  99        {CS35L34_TDM_TX_CTL_5_FLAG1, 0x08},
 100        {CS35L34_TDM_TX_CTL_6_FLAG2, 0x09},
 101        {CS35L34_TDM_TX_SLOT_EN_1, 0x00},
 102        {CS35L34_TDM_TX_SLOT_EN_2, 0x00},
 103        {CS35L34_TDM_TX_SLOT_EN_3, 0x00},
 104        {CS35L34_TDM_TX_SLOT_EN_4, 0x00},
 105        {CS35L34_TDM_RX_CTL_1_AUDIN, 0x40},
 106        {CS35L34_TDM_RX_CTL_3_ALIVE, 0x04},
 107        {CS35L34_MULT_DEV_SYNCH1, 0x00},
 108        {CS35L34_MULT_DEV_SYNCH2, 0x80},
 109        {CS35L34_PROT_RELEASE_CTL, 0x00},
 110        {CS35L34_DIAG_MODE_REG_LOCK, 0x00},
 111        {CS35L34_DIAG_MODE_CTL_1, 0x00},
 112        {CS35L34_DIAG_MODE_CTL_2, 0x00},
 113        {CS35L34_INT_MASK_1, 0xFF},
 114        {CS35L34_INT_MASK_2, 0xFF},
 115        {CS35L34_INT_MASK_3, 0xFF},
 116        {CS35L34_INT_MASK_4, 0xFF},
 117        {CS35L34_INT_STATUS_1, 0x30},
 118        {CS35L34_INT_STATUS_2, 0x05},
 119        {CS35L34_INT_STATUS_3, 0x00},
 120        {CS35L34_INT_STATUS_4, 0x00},
 121        {CS35L34_OTP_TRIM_STATUS, 0x00},
 122};
 123
 124static bool cs35l34_volatile_register(struct device *dev, unsigned int reg)
 125{
 126        switch (reg) {
 127        case CS35L34_DEVID_AB:
 128        case CS35L34_DEVID_CD:
 129        case CS35L34_DEVID_E:
 130        case CS35L34_FAB_ID:
 131        case CS35L34_REV_ID:
 132        case CS35L34_INT_STATUS_1:
 133        case CS35L34_INT_STATUS_2:
 134        case CS35L34_INT_STATUS_3:
 135        case CS35L34_INT_STATUS_4:
 136        case CS35L34_CLASS_H_STATUS:
 137        case CS35L34_VPBR_ATTEN_STATUS:
 138        case CS35L34_OTP_TRIM_STATUS:
 139                return true;
 140        default:
 141                return false;
 142        }
 143}
 144
 145static bool cs35l34_readable_register(struct device *dev, unsigned int reg)
 146{
 147        switch (reg) {
 148        case    CS35L34_DEVID_AB:
 149        case    CS35L34_DEVID_CD:
 150        case    CS35L34_DEVID_E:
 151        case    CS35L34_FAB_ID:
 152        case    CS35L34_REV_ID:
 153        case    CS35L34_PWRCTL1:
 154        case    CS35L34_PWRCTL2:
 155        case    CS35L34_PWRCTL3:
 156        case    CS35L34_ADSP_CLK_CTL:
 157        case    CS35L34_MCLK_CTL:
 158        case    CS35L34_AMP_INP_DRV_CTL:
 159        case    CS35L34_AMP_DIG_VOL_CTL:
 160        case    CS35L34_AMP_DIG_VOL:
 161        case    CS35L34_AMP_ANLG_GAIN_CTL:
 162        case    CS35L34_PROTECT_CTL:
 163        case    CS35L34_AMP_KEEP_ALIVE_CTL:
 164        case    CS35L34_BST_CVTR_V_CTL:
 165        case    CS35L34_BST_PEAK_I:
 166        case    CS35L34_BST_RAMP_CTL:
 167        case    CS35L34_BST_CONV_COEF_1:
 168        case    CS35L34_BST_CONV_COEF_2:
 169        case    CS35L34_BST_CONV_SLOPE_COMP:
 170        case    CS35L34_BST_CONV_SW_FREQ:
 171        case    CS35L34_CLASS_H_CTL:
 172        case    CS35L34_CLASS_H_HEADRM_CTL:
 173        case    CS35L34_CLASS_H_RELEASE_RATE:
 174        case    CS35L34_CLASS_H_FET_DRIVE_CTL:
 175        case    CS35L34_CLASS_H_STATUS:
 176        case    CS35L34_VPBR_CTL:
 177        case    CS35L34_VPBR_VOL_CTL:
 178        case    CS35L34_VPBR_TIMING_CTL:
 179        case    CS35L34_PRED_MAX_ATTEN_SPK_LOAD:
 180        case    CS35L34_PRED_BROWNOUT_THRESH:
 181        case    CS35L34_PRED_BROWNOUT_VOL_CTL:
 182        case    CS35L34_PRED_BROWNOUT_RATE_CTL:
 183        case    CS35L34_PRED_WAIT_CTL:
 184        case    CS35L34_PRED_ZVP_INIT_IMP_CTL:
 185        case    CS35L34_PRED_MAN_SAFE_VPI_CTL:
 186        case    CS35L34_VPBR_ATTEN_STATUS:
 187        case    CS35L34_PRED_BRWNOUT_ATT_STATUS:
 188        case    CS35L34_SPKR_MON_CTL:
 189        case    CS35L34_ADSP_I2S_CTL:
 190        case    CS35L34_ADSP_TDM_CTL:
 191        case    CS35L34_TDM_TX_CTL_1_VMON:
 192        case    CS35L34_TDM_TX_CTL_2_IMON:
 193        case    CS35L34_TDM_TX_CTL_3_VPMON:
 194        case    CS35L34_TDM_TX_CTL_4_VBSTMON:
 195        case    CS35L34_TDM_TX_CTL_5_FLAG1:
 196        case    CS35L34_TDM_TX_CTL_6_FLAG2:
 197        case    CS35L34_TDM_TX_SLOT_EN_1:
 198        case    CS35L34_TDM_TX_SLOT_EN_2:
 199        case    CS35L34_TDM_TX_SLOT_EN_3:
 200        case    CS35L34_TDM_TX_SLOT_EN_4:
 201        case    CS35L34_TDM_RX_CTL_1_AUDIN:
 202        case    CS35L34_TDM_RX_CTL_3_ALIVE:
 203        case    CS35L34_MULT_DEV_SYNCH1:
 204        case    CS35L34_MULT_DEV_SYNCH2:
 205        case    CS35L34_PROT_RELEASE_CTL:
 206        case    CS35L34_DIAG_MODE_REG_LOCK:
 207        case    CS35L34_DIAG_MODE_CTL_1:
 208        case    CS35L34_DIAG_MODE_CTL_2:
 209        case    CS35L34_INT_MASK_1:
 210        case    CS35L34_INT_MASK_2:
 211        case    CS35L34_INT_MASK_3:
 212        case    CS35L34_INT_MASK_4:
 213        case    CS35L34_INT_STATUS_1:
 214        case    CS35L34_INT_STATUS_2:
 215        case    CS35L34_INT_STATUS_3:
 216        case    CS35L34_INT_STATUS_4:
 217        case    CS35L34_OTP_TRIM_STATUS:
 218                return true;
 219        default:
 220                return false;
 221        }
 222}
 223
 224static bool cs35l34_precious_register(struct device *dev, unsigned int reg)
 225{
 226        switch (reg) {
 227        case CS35L34_INT_STATUS_1:
 228        case CS35L34_INT_STATUS_2:
 229        case CS35L34_INT_STATUS_3:
 230        case CS35L34_INT_STATUS_4:
 231                return true;
 232        default:
 233                return false;
 234        }
 235}
 236
 237static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,
 238                struct snd_kcontrol *kcontrol, int event)
 239{
 240        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 241        struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 242        int ret;
 243
 244        switch (event) {
 245        case SND_SOC_DAPM_PRE_PMU:
 246                if (priv->tdm_mode)
 247                        regmap_update_bits(priv->regmap, CS35L34_PWRCTL3,
 248                                                CS35L34_PDN_TDM, 0x00);
 249
 250                ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,
 251                                                CS35L34_PDN_ALL, 0);
 252                if (ret < 0) {
 253                        dev_err(component->dev, "Cannot set Power bits %d\n", ret);
 254                        return ret;
 255                }
 256                usleep_range(5000, 5100);
 257        break;
 258        case SND_SOC_DAPM_POST_PMD:
 259                if (priv->tdm_mode) {
 260                        regmap_update_bits(priv->regmap, CS35L34_PWRCTL3,
 261                                        CS35L34_PDN_TDM, CS35L34_PDN_TDM);
 262                }
 263                ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,
 264                                        CS35L34_PDN_ALL, CS35L34_PDN_ALL);
 265        break;
 266        default:
 267                pr_err("Invalid event = 0x%x\n", event);
 268        }
 269        return 0;
 270}
 271
 272static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
 273                                unsigned int rx_mask, int slots, int slot_width)
 274{
 275        struct snd_soc_component *component = dai->component;
 276        struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 277        unsigned int reg, bit_pos;
 278        int slot, slot_num;
 279
 280        if (slot_width != 8)
 281                return -EINVAL;
 282
 283        priv->tdm_mode = true;
 284        /* scan rx_mask for aud slot */
 285        slot = ffs(rx_mask) - 1;
 286        if (slot >= 0)
 287                snd_soc_component_update_bits(component, CS35L34_TDM_RX_CTL_1_AUDIN,
 288                                        CS35L34_X_LOC, slot);
 289
 290        /* scan tx_mask: vmon(2 slots); imon (2 slots); vpmon (1 slot)
 291         * vbstmon (1 slot)
 292         */
 293        slot = ffs(tx_mask) - 1;
 294        slot_num = 0;
 295
 296        /* disable vpmon/vbstmon: enable later if set in tx_mask */
 297        snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,
 298                                CS35L34_X_STATE | CS35L34_X_LOC,
 299                                CS35L34_X_STATE | CS35L34_X_LOC);
 300        snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_4_VBSTMON,
 301                                CS35L34_X_STATE | CS35L34_X_LOC,
 302                                CS35L34_X_STATE | CS35L34_X_LOC);
 303
 304        /* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/
 305        while (slot >= 0) {
 306                /* configure VMON_TX_LOC */
 307                if (slot_num == 0)
 308                        snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_1_VMON,
 309                                        CS35L34_X_STATE | CS35L34_X_LOC, slot);
 310
 311                /* configure IMON_TX_LOC */
 312                if (slot_num == 4) {
 313                        snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_2_IMON,
 314                                        CS35L34_X_STATE | CS35L34_X_LOC, slot);
 315                }
 316                /* configure VPMON_TX_LOC */
 317                if (slot_num == 3) {
 318                        snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,
 319                                        CS35L34_X_STATE | CS35L34_X_LOC, slot);
 320                }
 321                /* configure VBSTMON_TX_LOC */
 322                if (slot_num == 7) {
 323                        snd_soc_component_update_bits(component,
 324                                CS35L34_TDM_TX_CTL_4_VBSTMON,
 325                                CS35L34_X_STATE | CS35L34_X_LOC, slot);
 326                }
 327
 328                /* Enable the relevant tx slot */
 329                reg = CS35L34_TDM_TX_SLOT_EN_4 - (slot/8);
 330                bit_pos = slot - ((slot / 8) * (8));
 331                snd_soc_component_update_bits(component, reg,
 332                        1 << bit_pos, 1 << bit_pos);
 333
 334                tx_mask &= ~(1 << slot);
 335                slot = ffs(tx_mask) - 1;
 336                slot_num++;
 337        }
 338
 339        return 0;
 340}
 341
 342static int cs35l34_main_amp_event(struct snd_soc_dapm_widget *w,
 343                struct snd_kcontrol *kcontrol, int event)
 344{
 345        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 346        struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 347
 348        switch (event) {
 349        case SND_SOC_DAPM_POST_PMU:
 350                regmap_update_bits(priv->regmap, CS35L34_BST_CVTR_V_CTL,
 351                                CS35L34_BST_CVTL_MASK, priv->pdata.boost_vtge);
 352                usleep_range(5000, 5100);
 353                regmap_update_bits(priv->regmap, CS35L34_PROTECT_CTL,
 354                                                CS35L34_MUTE, 0);
 355                break;
 356        case SND_SOC_DAPM_POST_PMD:
 357                regmap_update_bits(priv->regmap, CS35L34_BST_CVTR_V_CTL,
 358                        CS35L34_BST_CVTL_MASK, 0);
 359                regmap_update_bits(priv->regmap, CS35L34_PROTECT_CTL,
 360                        CS35L34_MUTE, CS35L34_MUTE);
 361                usleep_range(5000, 5100);
 362                break;
 363        default:
 364                pr_err("Invalid event = 0x%x\n", event);
 365        }
 366        return 0;
 367}
 368
 369static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);
 370
 371static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 300, 100, 0);
 372
 373
 374static const struct snd_kcontrol_new cs35l34_snd_controls[] = {
 375        SOC_SINGLE_SX_TLV("Digital Volume", CS35L34_AMP_DIG_VOL,
 376                      0, 0x34, 0xE4, dig_vol_tlv),
 377        SOC_SINGLE_TLV("Amp Gain Volume", CS35L34_AMP_ANLG_GAIN_CTL,
 378                      0, 0xF, 0, amp_gain_tlv),
 379};
 380
 381
 382static int cs35l34_mclk_event(struct snd_soc_dapm_widget *w,
 383                struct snd_kcontrol *kcontrol, int event)
 384{
 385        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 386        struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 387        int ret, i;
 388        unsigned int reg;
 389
 390        switch (event) {
 391        case SND_SOC_DAPM_PRE_PMD:
 392                ret = regmap_read(priv->regmap, CS35L34_AMP_DIG_VOL_CTL,
 393                        &reg);
 394                if (ret != 0) {
 395                        pr_err("%s regmap read failure %d\n", __func__, ret);
 396                        return ret;
 397                }
 398                if (reg & CS35L34_AMP_DIGSFT)
 399                        msleep(40);
 400                else
 401                        usleep_range(2000, 2100);
 402
 403                for (i = 0; i < PDN_DONE_ATTEMPTS; i++) {
 404                        ret = regmap_read(priv->regmap, CS35L34_INT_STATUS_2,
 405                                &reg);
 406                        if (ret != 0) {
 407                                pr_err("%s regmap read failure %d\n",
 408                                        __func__, ret);
 409                                return ret;
 410                        }
 411                        if (reg & CS35L34_PDN_DONE)
 412                                break;
 413
 414                        usleep_range(5000, 5100);
 415                }
 416                if (i == PDN_DONE_ATTEMPTS)
 417                        pr_err("%s Device did not power down properly\n",
 418                                __func__);
 419                break;
 420        default:
 421                pr_err("Invalid event = 0x%x\n", event);
 422                break;
 423        }
 424        return 0;
 425}
 426
 427static const struct snd_soc_dapm_widget cs35l34_dapm_widgets[] = {
 428        SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L34_PWRCTL3,
 429                                        1, 1, cs35l34_sdin_event,
 430                                        SND_SOC_DAPM_PRE_PMU |
 431                                        SND_SOC_DAPM_POST_PMD),
 432        SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L34_PWRCTL3, 2, 1),
 433
 434        SND_SOC_DAPM_SUPPLY("EXTCLK", CS35L34_PWRCTL3, 7, 1,
 435                cs35l34_mclk_event, SND_SOC_DAPM_PRE_PMD),
 436
 437        SND_SOC_DAPM_OUTPUT("SPK"),
 438
 439        SND_SOC_DAPM_INPUT("VP"),
 440        SND_SOC_DAPM_INPUT("VPST"),
 441        SND_SOC_DAPM_INPUT("ISENSE"),
 442        SND_SOC_DAPM_INPUT("VSENSE"),
 443
 444        SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L34_PWRCTL2, 7, 1),
 445        SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L34_PWRCTL2, 6, 1),
 446        SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L34_PWRCTL3, 3, 1),
 447        SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L34_PWRCTL3, 4, 1),
 448        SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L34_PWRCTL2, 5, 1),
 449        SND_SOC_DAPM_ADC("BOOST", NULL, CS35L34_PWRCTL2, 2, 1),
 450
 451        SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L34_PWRCTL2, 0, 1, NULL, 0,
 452                cs35l34_main_amp_event, SND_SOC_DAPM_POST_PMU |
 453                        SND_SOC_DAPM_POST_PMD),
 454};
 455
 456static const struct snd_soc_dapm_route cs35l34_audio_map[] = {
 457        {"SDIN", NULL, "AMP Playback"},
 458        {"BOOST", NULL, "SDIN"},
 459        {"CLASS H", NULL, "BOOST"},
 460        {"Main AMP", NULL, "CLASS H"},
 461        {"SPK", NULL, "Main AMP"},
 462
 463        {"VPMON ADC", NULL, "CLASS H"},
 464        {"VBSTMON ADC", NULL, "CLASS H"},
 465        {"SPK", NULL, "VPMON ADC"},
 466        {"SPK", NULL, "VBSTMON ADC"},
 467
 468        {"IMON ADC", NULL, "ISENSE"},
 469        {"VMON ADC", NULL, "VSENSE"},
 470        {"SDOUT", NULL, "IMON ADC"},
 471        {"SDOUT", NULL, "VMON ADC"},
 472        {"AMP Capture", NULL, "SDOUT"},
 473
 474        {"SDIN", NULL, "EXTCLK"},
 475        {"SDOUT", NULL, "EXTCLK"},
 476};
 477
 478struct cs35l34_mclk_div {
 479        int mclk;
 480        int srate;
 481        u8 adsp_rate;
 482};
 483
 484static struct cs35l34_mclk_div cs35l34_mclk_coeffs[] = {
 485
 486        /* MCLK, Sample Rate, adsp_rate */
 487
 488        {5644800, 11025, 0x1},
 489        {5644800, 22050, 0x4},
 490        {5644800, 44100, 0x7},
 491
 492        {6000000,  8000, 0x0},
 493        {6000000, 11025, 0x1},
 494        {6000000, 12000, 0x2},
 495        {6000000, 16000, 0x3},
 496        {6000000, 22050, 0x4},
 497        {6000000, 24000, 0x5},
 498        {6000000, 32000, 0x6},
 499        {6000000, 44100, 0x7},
 500        {6000000, 48000, 0x8},
 501
 502        {6144000,  8000, 0x0},
 503        {6144000, 11025, 0x1},
 504        {6144000, 12000, 0x2},
 505        {6144000, 16000, 0x3},
 506        {6144000, 22050, 0x4},
 507        {6144000, 24000, 0x5},
 508        {6144000, 32000, 0x6},
 509        {6144000, 44100, 0x7},
 510        {6144000, 48000, 0x8},
 511};
 512
 513static int cs35l34_get_mclk_coeff(int mclk, int srate)
 514{
 515        int i;
 516
 517        for (i = 0; i < ARRAY_SIZE(cs35l34_mclk_coeffs); i++) {
 518                if (cs35l34_mclk_coeffs[i].mclk == mclk &&
 519                        cs35l34_mclk_coeffs[i].srate == srate)
 520                        return i;
 521        }
 522        return -EINVAL;
 523}
 524
 525static int cs35l34_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 526{
 527        struct snd_soc_component *component = codec_dai->component;
 528        struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 529
 530        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 531        case SND_SOC_DAIFMT_CBM_CFM:
 532                regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,
 533                                    0x80, 0x80);
 534                break;
 535        case SND_SOC_DAIFMT_CBS_CFS:
 536                regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,
 537                                    0x80, 0x00);
 538                break;
 539        default:
 540                return -EINVAL;
 541        }
 542        return 0;
 543}
 544
 545static int cs35l34_pcm_hw_params(struct snd_pcm_substream *substream,
 546                                 struct snd_pcm_hw_params *params,
 547                                 struct snd_soc_dai *dai)
 548{
 549        struct snd_soc_component *component = dai->component;
 550        struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);
 551        int srate = params_rate(params);
 552        int ret;
 553
 554        int coeff = cs35l34_get_mclk_coeff(priv->mclk_int, srate);
 555
 556        if (coeff < 0) {
 557                dev_err(component->dev, "ERROR: Invalid mclk %d and/or srate %d\n",
 558                        priv->mclk_int, srate);
 559                return coeff;
 560        }
 561
 562        ret = regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,
 563                CS35L34_ADSP_RATE, cs35l34_mclk_coeffs[coeff].adsp_rate);
 564        if (ret != 0)
 565                dev_err(component->dev, "Failed to set clock state %d\n", ret);
 566
 567        return ret;
 568}
 569
 570static const unsigned int cs35l34_src_rates[] = {
 571        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
 572};
 573
 574
 575static const struct snd_pcm_hw_constraint_list cs35l34_constraints = {
 576        .count  = ARRAY_SIZE(cs35l34_src_rates),
 577        .list   = cs35l34_src_rates,
 578};
 579
 580static int cs35l34_pcm_startup(struct snd_pcm_substream *substream,
 581                               struct snd_soc_dai *dai)
 582{
 583
 584        snd_pcm_hw_constraint_list(substream->runtime, 0,
 585                                SNDRV_PCM_HW_PARAM_RATE, &cs35l34_constraints);
 586        return 0;
 587}
 588
 589
 590static int cs35l34_set_tristate(struct snd_soc_dai *dai, int tristate)
 591{
 592
 593        struct snd_soc_component *component = dai->component;
 594
 595        if (tristate)
 596                snd_soc_component_update_bits(component, CS35L34_PWRCTL3,
 597                                        CS35L34_PDN_SDOUT, CS35L34_PDN_SDOUT);
 598        else
 599                snd_soc_component_update_bits(component, CS35L34_PWRCTL3,
 600                                        CS35L34_PDN_SDOUT, 0);
 601        return 0;
 602}
 603
 604static int cs35l34_dai_set_sysclk(struct snd_soc_dai *dai,
 605                                int clk_id, unsigned int freq, int dir)
 606{
 607        struct snd_soc_component *component = dai->component;
 608        struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);
 609        unsigned int value;
 610
 611        switch (freq) {
 612        case CS35L34_MCLK_5644:
 613                value = CS35L34_MCLK_RATE_5P6448;
 614                cs35l34->mclk_int = freq;
 615        break;
 616        case CS35L34_MCLK_6:
 617                value = CS35L34_MCLK_RATE_6P0000;
 618                cs35l34->mclk_int = freq;
 619        break;
 620        case CS35L34_MCLK_6144:
 621                value = CS35L34_MCLK_RATE_6P1440;
 622                cs35l34->mclk_int = freq;
 623        break;
 624        case CS35L34_MCLK_11289:
 625                value = CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_5P6448;
 626                cs35l34->mclk_int = freq / 2;
 627        break;
 628        case CS35L34_MCLK_12:
 629                value = CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_6P0000;
 630                cs35l34->mclk_int = freq / 2;
 631        break;
 632        case CS35L34_MCLK_12288:
 633                value = CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_6P1440;
 634                cs35l34->mclk_int = freq / 2;
 635        break;
 636        default:
 637                dev_err(component->dev, "ERROR: Invalid Frequency %d\n", freq);
 638                cs35l34->mclk_int = 0;
 639                return -EINVAL;
 640        }
 641        regmap_update_bits(cs35l34->regmap, CS35L34_MCLK_CTL,
 642                        CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_MASK, value);
 643        return 0;
 644}
 645
 646static const struct snd_soc_dai_ops cs35l34_ops = {
 647        .startup = cs35l34_pcm_startup,
 648        .set_tristate = cs35l34_set_tristate,
 649        .set_fmt = cs35l34_set_dai_fmt,
 650        .hw_params = cs35l34_pcm_hw_params,
 651        .set_sysclk = cs35l34_dai_set_sysclk,
 652        .set_tdm_slot = cs35l34_set_tdm_slot,
 653};
 654
 655static struct snd_soc_dai_driver cs35l34_dai = {
 656                .name = "cs35l34",
 657                .id = 0,
 658                .playback = {
 659                        .stream_name = "AMP Playback",
 660                        .channels_min = 1,
 661                        .channels_max = 8,
 662                        .rates = CS35L34_RATES,
 663                        .formats = CS35L34_FORMATS,
 664                },
 665                .capture = {
 666                        .stream_name = "AMP Capture",
 667                        .channels_min = 1,
 668                        .channels_max = 8,
 669                        .rates = CS35L34_RATES,
 670                        .formats = CS35L34_FORMATS,
 671                },
 672                .ops = &cs35l34_ops,
 673                .symmetric_rates = 1,
 674};
 675
 676static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,
 677        unsigned int inductor)
 678{
 679        struct snd_soc_component *component = cs35l34->component;
 680
 681        switch (inductor) {
 682        case 1000: /* 1 uH */
 683                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x24);
 684                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x24);
 685                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,
 686                        0x4E);
 687                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 0);
 688                break;
 689        case 1200: /* 1.2 uH */
 690                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x20);
 691                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x20);
 692                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,
 693                        0x47);
 694                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 1);
 695                break;
 696        case 1500: /* 1.5uH */
 697                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x20);
 698                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x20);
 699                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,
 700                        0x3C);
 701                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 2);
 702                break;
 703        case 2200: /* 2.2uH */
 704                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x19);
 705                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x25);
 706                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,
 707                        0x23);
 708                regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 3);
 709                break;
 710        default:
 711                dev_err(component->dev, "%s Invalid Inductor Value %d uH\n",
 712                        __func__, inductor);
 713                return -EINVAL;
 714        }
 715        return 0;
 716}
 717
 718static int cs35l34_probe(struct snd_soc_component *component)
 719{
 720        int ret = 0;
 721        struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);
 722
 723        pm_runtime_get_sync(component->dev);
 724
 725        /* Set over temperature warning attenuation to 6 dB */
 726        regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,
 727                 CS35L34_OTW_ATTN_MASK, 0x8);
 728
 729        /* Set Power control registers 2 and 3 to have everything
 730         * powered down at initialization
 731         */
 732        regmap_write(cs35l34->regmap, CS35L34_PWRCTL2, 0xFD);
 733        regmap_write(cs35l34->regmap, CS35L34_PWRCTL3, 0x1F);
 734
 735        /* Set mute bit at startup */
 736        regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,
 737                                CS35L34_MUTE, CS35L34_MUTE);
 738
 739        /* Set Platform Data */
 740        if (cs35l34->pdata.boost_peak)
 741                regmap_update_bits(cs35l34->regmap, CS35L34_BST_PEAK_I,
 742                                CS35L34_BST_PEAK_MASK,
 743                                cs35l34->pdata.boost_peak);
 744
 745        if (cs35l34->pdata.gain_zc_disable)
 746                regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,
 747                        CS35L34_GAIN_ZC_MASK, 0);
 748        else
 749                regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,
 750                        CS35L34_GAIN_ZC_MASK, CS35L34_GAIN_ZC_MASK);
 751
 752        if (cs35l34->pdata.aif_half_drv)
 753                regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_CLK_CTL,
 754                        CS35L34_ADSP_DRIVE, 0);
 755
 756        if (cs35l34->pdata.digsft_disable)
 757                regmap_update_bits(cs35l34->regmap, CS35L34_AMP_DIG_VOL_CTL,
 758                        CS35L34_AMP_DIGSFT, 0);
 759
 760        if (cs35l34->pdata.amp_inv)
 761                regmap_update_bits(cs35l34->regmap, CS35L34_AMP_DIG_VOL_CTL,
 762                        CS35L34_INV, CS35L34_INV);
 763
 764        if (cs35l34->pdata.boost_ind)
 765                ret = cs35l34_boost_inductor(cs35l34, cs35l34->pdata.boost_ind);
 766
 767        if (cs35l34->pdata.i2s_sdinloc)
 768                regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_I2S_CTL,
 769                        CS35L34_I2S_LOC_MASK,
 770                        cs35l34->pdata.i2s_sdinloc << CS35L34_I2S_LOC_SHIFT);
 771
 772        if (cs35l34->pdata.tdm_rising_edge)
 773                regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_TDM_CTL,
 774                        1, 1);
 775
 776        pm_runtime_put_sync(component->dev);
 777
 778        return ret;
 779}
 780
 781
 782static const struct snd_soc_component_driver soc_component_dev_cs35l34 = {
 783        .probe                  = cs35l34_probe,
 784        .dapm_widgets           = cs35l34_dapm_widgets,
 785        .num_dapm_widgets       = ARRAY_SIZE(cs35l34_dapm_widgets),
 786        .dapm_routes            = cs35l34_audio_map,
 787        .num_dapm_routes        = ARRAY_SIZE(cs35l34_audio_map),
 788        .controls               = cs35l34_snd_controls,
 789        .num_controls           = ARRAY_SIZE(cs35l34_snd_controls),
 790        .idle_bias_on           = 1,
 791        .use_pmdown_time        = 1,
 792        .endianness             = 1,
 793        .non_legacy_dai_naming  = 1,
 794};
 795
 796static struct regmap_config cs35l34_regmap = {
 797        .reg_bits = 8,
 798        .val_bits = 8,
 799
 800        .max_register = CS35L34_MAX_REGISTER,
 801        .reg_defaults = cs35l34_reg,
 802        .num_reg_defaults = ARRAY_SIZE(cs35l34_reg),
 803        .volatile_reg = cs35l34_volatile_register,
 804        .readable_reg = cs35l34_readable_register,
 805        .precious_reg = cs35l34_precious_register,
 806        .cache_type = REGCACHE_RBTREE,
 807};
 808
 809static int cs35l34_handle_of_data(struct i2c_client *i2c_client,
 810                                struct cs35l34_platform_data *pdata)
 811{
 812        struct device_node *np = i2c_client->dev.of_node;
 813        unsigned int val;
 814
 815        if (of_property_read_u32(np, "cirrus,boost-vtge-millivolt",
 816                &val) >= 0) {
 817                /* Boost Voltage has a maximum of 8V */
 818                if (val > 8000 || (val < 3300 && val > 0)) {
 819                        dev_err(&i2c_client->dev,
 820                                "Invalid Boost Voltage %d mV\n", val);
 821                        return -EINVAL;
 822                }
 823                if (val == 0)
 824                        pdata->boost_vtge = 0; /* Use VP */
 825                else
 826                        pdata->boost_vtge = ((val - 3300)/100) + 1;
 827        } else {
 828                dev_warn(&i2c_client->dev,
 829                        "Boost Voltage not specified. Using VP\n");
 830        }
 831
 832        if (of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val) >= 0) {
 833                pdata->boost_ind = val;
 834        } else {
 835                dev_err(&i2c_client->dev, "Inductor not specified.\n");
 836                return -EINVAL;
 837        }
 838
 839        if (of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val) >= 0) {
 840                if (val > 3840 || val < 1200) {
 841                        dev_err(&i2c_client->dev,
 842                                "Invalid Boost Peak Current %d mA\n", val);
 843                        return -EINVAL;
 844                }
 845                pdata->boost_peak = ((val - 1200)/80) + 1;
 846        }
 847
 848        pdata->aif_half_drv = of_property_read_bool(np,
 849                "cirrus,aif-half-drv");
 850        pdata->digsft_disable = of_property_read_bool(np,
 851                "cirrus,digsft-disable");
 852
 853        pdata->gain_zc_disable = of_property_read_bool(np,
 854                "cirrus,gain-zc-disable");
 855        pdata->amp_inv = of_property_read_bool(np, "cirrus,amp-inv");
 856
 857        if (of_property_read_u32(np, "cirrus,i2s-sdinloc", &val) >= 0)
 858                pdata->i2s_sdinloc = val;
 859        if (of_property_read_u32(np, "cirrus,tdm-rising-edge", &val) >= 0)
 860                pdata->tdm_rising_edge = val;
 861
 862        return 0;
 863}
 864
 865static irqreturn_t cs35l34_irq_thread(int irq, void *data)
 866{
 867        struct cs35l34_private *cs35l34 = data;
 868        struct snd_soc_component *component = cs35l34->component;
 869        unsigned int sticky1, sticky2, sticky3, sticky4;
 870        unsigned int mask1, mask2, mask3, mask4, current1;
 871
 872
 873        /* ack the irq by reading all status registers */
 874        regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_4, &sticky4);
 875        regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_3, &sticky3);
 876        regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_2, &sticky2);
 877        regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_1, &sticky1);
 878
 879        regmap_read(cs35l34->regmap, CS35L34_INT_MASK_4, &mask4);
 880        regmap_read(cs35l34->regmap, CS35L34_INT_MASK_3, &mask3);
 881        regmap_read(cs35l34->regmap, CS35L34_INT_MASK_2, &mask2);
 882        regmap_read(cs35l34->regmap, CS35L34_INT_MASK_1, &mask1);
 883
 884        if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)
 885                && !(sticky4 & ~mask4))
 886                return IRQ_NONE;
 887
 888        regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_1, &current1);
 889
 890        if (sticky1 & CS35L34_CAL_ERR) {
 891                dev_err(component->dev, "Cal error\n");
 892
 893                /* error is no longer asserted; safe to reset */
 894                if (!(current1 & CS35L34_CAL_ERR)) {
 895                        dev_dbg(component->dev, "Cal error release\n");
 896                        regmap_update_bits(cs35l34->regmap,
 897                                        CS35L34_PROT_RELEASE_CTL,
 898                                        CS35L34_CAL_ERR_RLS, 0);
 899                        regmap_update_bits(cs35l34->regmap,
 900                                        CS35L34_PROT_RELEASE_CTL,
 901                                        CS35L34_CAL_ERR_RLS,
 902                                        CS35L34_CAL_ERR_RLS);
 903                        regmap_update_bits(cs35l34->regmap,
 904                                        CS35L34_PROT_RELEASE_CTL,
 905                                        CS35L34_CAL_ERR_RLS, 0);
 906                        /* note: amp will re-calibrate on next resume */
 907                }
 908        }
 909
 910        if (sticky1 & CS35L34_ALIVE_ERR)
 911                dev_err(component->dev, "Alive error\n");
 912
 913        if (sticky1 & CS35L34_AMP_SHORT) {
 914                dev_crit(component->dev, "Amp short error\n");
 915
 916                /* error is no longer asserted; safe to reset */
 917                if (!(current1 & CS35L34_AMP_SHORT)) {
 918                        dev_dbg(component->dev,
 919                                "Amp short error release\n");
 920                        regmap_update_bits(cs35l34->regmap,
 921                                        CS35L34_PROT_RELEASE_CTL,
 922                                        CS35L34_SHORT_RLS, 0);
 923                        regmap_update_bits(cs35l34->regmap,
 924                                        CS35L34_PROT_RELEASE_CTL,
 925                                        CS35L34_SHORT_RLS,
 926                                        CS35L34_SHORT_RLS);
 927                        regmap_update_bits(cs35l34->regmap,
 928                                        CS35L34_PROT_RELEASE_CTL,
 929                                        CS35L34_SHORT_RLS, 0);
 930                }
 931        }
 932
 933        if (sticky1 & CS35L34_OTW) {
 934                dev_crit(component->dev, "Over temperature warning\n");
 935
 936                /* error is no longer asserted; safe to reset */
 937                if (!(current1 & CS35L34_OTW)) {
 938                        dev_dbg(component->dev,
 939                                "Over temperature warning release\n");
 940                        regmap_update_bits(cs35l34->regmap,
 941                                        CS35L34_PROT_RELEASE_CTL,
 942                                        CS35L34_OTW_RLS, 0);
 943                        regmap_update_bits(cs35l34->regmap,
 944                                        CS35L34_PROT_RELEASE_CTL,
 945                                        CS35L34_OTW_RLS,
 946                                        CS35L34_OTW_RLS);
 947                        regmap_update_bits(cs35l34->regmap,
 948                                        CS35L34_PROT_RELEASE_CTL,
 949                                        CS35L34_OTW_RLS, 0);
 950                }
 951        }
 952
 953        if (sticky1 & CS35L34_OTE) {
 954                dev_crit(component->dev, "Over temperature error\n");
 955
 956                /* error is no longer asserted; safe to reset */
 957                if (!(current1 & CS35L34_OTE)) {
 958                        dev_dbg(component->dev,
 959                                "Over temperature error release\n");
 960                        regmap_update_bits(cs35l34->regmap,
 961                                        CS35L34_PROT_RELEASE_CTL,
 962                                        CS35L34_OTE_RLS, 0);
 963                        regmap_update_bits(cs35l34->regmap,
 964                                        CS35L34_PROT_RELEASE_CTL,
 965                                        CS35L34_OTE_RLS,
 966                                        CS35L34_OTE_RLS);
 967                        regmap_update_bits(cs35l34->regmap,
 968                                        CS35L34_PROT_RELEASE_CTL,
 969                                        CS35L34_OTE_RLS, 0);
 970                }
 971        }
 972
 973        if (sticky3 & CS35L34_BST_HIGH) {
 974                dev_crit(component->dev, "VBST too high error; powering off!\n");
 975                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,
 976                                CS35L34_PDN_AMP, CS35L34_PDN_AMP);
 977                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,
 978                                CS35L34_PDN_ALL, CS35L34_PDN_ALL);
 979        }
 980
 981        if (sticky3 & CS35L34_LBST_SHORT) {
 982                dev_crit(component->dev, "LBST short error; powering off!\n");
 983                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,
 984                                CS35L34_PDN_AMP, CS35L34_PDN_AMP);
 985                regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,
 986                                CS35L34_PDN_ALL, CS35L34_PDN_ALL);
 987        }
 988
 989        return IRQ_HANDLED;
 990}
 991
 992static const char * const cs35l34_core_supplies[] = {
 993        "VA",
 994        "VP",
 995};
 996
 997static int cs35l34_i2c_probe(struct i2c_client *i2c_client,
 998                              const struct i2c_device_id *id)
 999{
1000        struct cs35l34_private *cs35l34;
1001        struct cs35l34_platform_data *pdata =
1002                dev_get_platdata(&i2c_client->dev);
1003        int i;
1004        int ret;
1005        unsigned int devid = 0;
1006        unsigned int reg;
1007
1008        cs35l34 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l34), GFP_KERNEL);
1009        if (!cs35l34)
1010                return -ENOMEM;
1011
1012        i2c_set_clientdata(i2c_client, cs35l34);
1013        cs35l34->regmap = devm_regmap_init_i2c(i2c_client, &cs35l34_regmap);
1014        if (IS_ERR(cs35l34->regmap)) {
1015                ret = PTR_ERR(cs35l34->regmap);
1016                dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1017                return ret;
1018        }
1019
1020        cs35l34->num_core_supplies = ARRAY_SIZE(cs35l34_core_supplies);
1021        for (i = 0; i < ARRAY_SIZE(cs35l34_core_supplies); i++)
1022                cs35l34->core_supplies[i].supply = cs35l34_core_supplies[i];
1023
1024        ret = devm_regulator_bulk_get(&i2c_client->dev,
1025                cs35l34->num_core_supplies,
1026                cs35l34->core_supplies);
1027        if (ret != 0) {
1028                dev_err(&i2c_client->dev,
1029                        "Failed to request core supplies %d\n", ret);
1030                return ret;
1031        }
1032
1033        ret = regulator_bulk_enable(cs35l34->num_core_supplies,
1034                                        cs35l34->core_supplies);
1035        if (ret != 0) {
1036                dev_err(&i2c_client->dev,
1037                        "Failed to enable core supplies: %d\n", ret);
1038                return ret;
1039        }
1040
1041        if (pdata) {
1042                cs35l34->pdata = *pdata;
1043        } else {
1044                pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
1045                                     GFP_KERNEL);
1046                if (!pdata)
1047                        return -ENOMEM;
1048
1049                if (i2c_client->dev.of_node) {
1050                        ret = cs35l34_handle_of_data(i2c_client, pdata);
1051                        if (ret != 0)
1052                                return ret;
1053
1054                }
1055                cs35l34->pdata = *pdata;
1056        }
1057
1058        ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL,
1059                        cs35l34_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,
1060                        "cs35l34", cs35l34);
1061        if (ret != 0)
1062                dev_err(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);
1063
1064        cs35l34->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,
1065                                "reset-gpios", GPIOD_OUT_LOW);
1066        if (IS_ERR(cs35l34->reset_gpio))
1067                return PTR_ERR(cs35l34->reset_gpio);
1068
1069        gpiod_set_value_cansleep(cs35l34->reset_gpio, 1);
1070
1071        msleep(CS35L34_START_DELAY);
1072
1073        ret = regmap_read(cs35l34->regmap, CS35L34_DEVID_AB, &reg);
1074
1075        devid = (reg & 0xFF) << 12;
1076        ret = regmap_read(cs35l34->regmap, CS35L34_DEVID_CD, &reg);
1077        devid |= (reg & 0xFF) << 4;
1078        ret = regmap_read(cs35l34->regmap, CS35L34_DEVID_E, &reg);
1079        devid |= (reg & 0xF0) >> 4;
1080
1081        if (devid != CS35L34_CHIP_ID) {
1082                dev_err(&i2c_client->dev,
1083                        "CS35l34 Device ID (%X). Expected ID %X\n",
1084                        devid, CS35L34_CHIP_ID);
1085                ret = -ENODEV;
1086                goto err_regulator;
1087        }
1088
1089        ret = regmap_read(cs35l34->regmap, CS35L34_REV_ID, &reg);
1090        if (ret < 0) {
1091                dev_err(&i2c_client->dev, "Get Revision ID failed\n");
1092                goto err_regulator;
1093        }
1094
1095        dev_info(&i2c_client->dev,
1096                 "Cirrus Logic CS35l34 (%x), Revision: %02X\n", devid,
1097                reg & 0xFF);
1098
1099        /* Unmask critical interrupts */
1100        regmap_update_bits(cs35l34->regmap, CS35L34_INT_MASK_1,
1101                                CS35L34_M_CAL_ERR | CS35L34_M_ALIVE_ERR |
1102                                CS35L34_M_AMP_SHORT | CS35L34_M_OTW |
1103                                CS35L34_M_OTE, 0);
1104        regmap_update_bits(cs35l34->regmap, CS35L34_INT_MASK_3,
1105                                CS35L34_M_BST_HIGH | CS35L34_M_LBST_SHORT, 0);
1106
1107        pm_runtime_set_autosuspend_delay(&i2c_client->dev, 100);
1108        pm_runtime_use_autosuspend(&i2c_client->dev);
1109        pm_runtime_set_active(&i2c_client->dev);
1110        pm_runtime_enable(&i2c_client->dev);
1111
1112        ret = devm_snd_soc_register_component(&i2c_client->dev,
1113                        &soc_component_dev_cs35l34, &cs35l34_dai, 1);
1114        if (ret < 0) {
1115                dev_err(&i2c_client->dev,
1116                        "%s: Register component failed\n", __func__);
1117                goto err_regulator;
1118        }
1119
1120        return 0;
1121
1122err_regulator:
1123        regulator_bulk_disable(cs35l34->num_core_supplies,
1124                cs35l34->core_supplies);
1125
1126        return ret;
1127}
1128
1129static int cs35l34_i2c_remove(struct i2c_client *client)
1130{
1131        struct cs35l34_private *cs35l34 = i2c_get_clientdata(client);
1132
1133        gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
1134
1135        pm_runtime_disable(&client->dev);
1136        regulator_bulk_disable(cs35l34->num_core_supplies,
1137                cs35l34->core_supplies);
1138
1139        return 0;
1140}
1141
1142static int __maybe_unused cs35l34_runtime_resume(struct device *dev)
1143{
1144        struct cs35l34_private *cs35l34 = dev_get_drvdata(dev);
1145        int ret;
1146
1147        ret = regulator_bulk_enable(cs35l34->num_core_supplies,
1148                cs35l34->core_supplies);
1149
1150        if (ret != 0) {
1151                dev_err(dev, "Failed to enable core supplies: %d\n",
1152                        ret);
1153                return ret;
1154        }
1155
1156        regcache_cache_only(cs35l34->regmap, false);
1157
1158        gpiod_set_value_cansleep(cs35l34->reset_gpio, 1);
1159        msleep(CS35L34_START_DELAY);
1160
1161        ret = regcache_sync(cs35l34->regmap);
1162        if (ret != 0) {
1163                dev_err(dev, "Failed to restore register cache\n");
1164                goto err;
1165        }
1166        return 0;
1167err:
1168        regcache_cache_only(cs35l34->regmap, true);
1169        regulator_bulk_disable(cs35l34->num_core_supplies,
1170                cs35l34->core_supplies);
1171
1172        return ret;
1173}
1174
1175static int __maybe_unused cs35l34_runtime_suspend(struct device *dev)
1176{
1177        struct cs35l34_private *cs35l34 = dev_get_drvdata(dev);
1178
1179        regcache_cache_only(cs35l34->regmap, true);
1180        regcache_mark_dirty(cs35l34->regmap);
1181
1182        gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);
1183
1184        regulator_bulk_disable(cs35l34->num_core_supplies,
1185                        cs35l34->core_supplies);
1186
1187        return 0;
1188}
1189
1190static const struct dev_pm_ops cs35l34_pm_ops = {
1191        SET_RUNTIME_PM_OPS(cs35l34_runtime_suspend,
1192                           cs35l34_runtime_resume,
1193                           NULL)
1194};
1195
1196static const struct of_device_id cs35l34_of_match[] = {
1197        {.compatible = "cirrus,cs35l34"},
1198        {},
1199};
1200MODULE_DEVICE_TABLE(of, cs35l34_of_match);
1201
1202static const struct i2c_device_id cs35l34_id[] = {
1203        {"cs35l34", 0},
1204        {}
1205};
1206MODULE_DEVICE_TABLE(i2c, cs35l34_id);
1207
1208static struct i2c_driver cs35l34_i2c_driver = {
1209        .driver = {
1210                .name = "cs35l34",
1211                .pm = &cs35l34_pm_ops,
1212                .of_match_table = cs35l34_of_match,
1213
1214                },
1215        .id_table = cs35l34_id,
1216        .probe = cs35l34_i2c_probe,
1217        .remove = cs35l34_i2c_remove,
1218
1219};
1220
1221static int __init cs35l34_modinit(void)
1222{
1223        int ret;
1224
1225        ret = i2c_add_driver(&cs35l34_i2c_driver);
1226        if (ret != 0) {
1227                pr_err("Failed to register CS35l34 I2C driver: %d\n", ret);
1228                return ret;
1229        }
1230        return 0;
1231}
1232module_init(cs35l34_modinit);
1233
1234static void __exit cs35l34_exit(void)
1235{
1236        i2c_del_driver(&cs35l34_i2c_driver);
1237}
1238module_exit(cs35l34_exit);
1239
1240MODULE_DESCRIPTION("ASoC CS35l34 driver");
1241MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <Paul.Handrigan@cirrus.com>");
1242MODULE_LICENSE("GPL");
1243