linux/sound/soc/codecs/cs35l41.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// cs35l41.c -- CS35l41 ALSA SoC audio driver
   4//
   5// Copyright 2017-2021 Cirrus Logic, Inc.
   6//
   7// Author: David Rhodes <david.rhodes@cirrus.com>
   8
   9#include <linux/delay.h>
  10#include <linux/err.h>
  11#include <linux/init.h>
  12#include <linux/kernel.h>
  13#include <linux/module.h>
  14#include <linux/moduleparam.h>
  15#include <linux/of_device.h>
  16#include <linux/property.h>
  17#include <linux/slab.h>
  18#include <sound/initval.h>
  19#include <sound/pcm.h>
  20#include <sound/pcm_params.h>
  21#include <sound/soc.h>
  22#include <sound/soc-dapm.h>
  23#include <sound/tlv.h>
  24
  25#include "cs35l41.h"
  26
  27static const char * const cs35l41_supplies[CS35L41_NUM_SUPPLIES] = {
  28        "VA",
  29        "VP",
  30};
  31
  32struct cs35l41_pll_sysclk_config {
  33        int freq;
  34        int clk_cfg;
  35};
  36
  37static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = {
  38        { 32768,        0x00 },
  39        { 8000,         0x01 },
  40        { 11025,        0x02 },
  41        { 12000,        0x03 },
  42        { 16000,        0x04 },
  43        { 22050,        0x05 },
  44        { 24000,        0x06 },
  45        { 32000,        0x07 },
  46        { 44100,        0x08 },
  47        { 48000,        0x09 },
  48        { 88200,        0x0A },
  49        { 96000,        0x0B },
  50        { 128000,       0x0C },
  51        { 176400,       0x0D },
  52        { 192000,       0x0E },
  53        { 256000,       0x0F },
  54        { 352800,       0x10 },
  55        { 384000,       0x11 },
  56        { 512000,       0x12 },
  57        { 705600,       0x13 },
  58        { 750000,       0x14 },
  59        { 768000,       0x15 },
  60        { 1000000,      0x16 },
  61        { 1024000,      0x17 },
  62        { 1200000,      0x18 },
  63        { 1411200,      0x19 },
  64        { 1500000,      0x1A },
  65        { 1536000,      0x1B },
  66        { 2000000,      0x1C },
  67        { 2048000,      0x1D },
  68        { 2400000,      0x1E },
  69        { 2822400,      0x1F },
  70        { 3000000,      0x20 },
  71        { 3072000,      0x21 },
  72        { 3200000,      0x22 },
  73        { 4000000,      0x23 },
  74        { 4096000,      0x24 },
  75        { 4800000,      0x25 },
  76        { 5644800,      0x26 },
  77        { 6000000,      0x27 },
  78        { 6144000,      0x28 },
  79        { 6250000,      0x29 },
  80        { 6400000,      0x2A },
  81        { 6500000,      0x2B },
  82        { 6750000,      0x2C },
  83        { 7526400,      0x2D },
  84        { 8000000,      0x2E },
  85        { 8192000,      0x2F },
  86        { 9600000,      0x30 },
  87        { 11289600,     0x31 },
  88        { 12000000,     0x32 },
  89        { 12288000,     0x33 },
  90        { 12500000,     0x34 },
  91        { 12800000,     0x35 },
  92        { 13000000,     0x36 },
  93        { 13500000,     0x37 },
  94        { 19200000,     0x38 },
  95        { 22579200,     0x39 },
  96        { 24000000,     0x3A },
  97        { 24576000,     0x3B },
  98        { 25000000,     0x3C },
  99        { 25600000,     0x3D },
 100        { 26000000,     0x3E },
 101        { 27000000,     0x3F },
 102};
 103
 104struct cs35l41_fs_mon_config {
 105        int freq;
 106        unsigned int fs1;
 107        unsigned int fs2;
 108};
 109
 110static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = {
 111        { 32768,        2254,   3754 },
 112        { 8000,         9220,   15364 },
 113        { 11025,        6148,   10244 },
 114        { 12000,        6148,   10244 },
 115        { 16000,        4612,   7684 },
 116        { 22050,        3076,   5124 },
 117        { 24000,        3076,   5124 },
 118        { 32000,        2308,   3844 },
 119        { 44100,        1540,   2564 },
 120        { 48000,        1540,   2564 },
 121        { 88200,        772,    1284 },
 122        { 96000,        772,    1284 },
 123        { 128000,       580,    964 },
 124        { 176400,       388,    644 },
 125        { 192000,       388,    644 },
 126        { 256000,       292,    484 },
 127        { 352800,       196,    324 },
 128        { 384000,       196,    324 },
 129        { 512000,       148,    244 },
 130        { 705600,       100,    164 },
 131        { 750000,       100,    164 },
 132        { 768000,       100,    164 },
 133        { 1000000,      76,     124 },
 134        { 1024000,      76,     124 },
 135        { 1200000,      64,     104 },
 136        { 1411200,      52,     84 },
 137        { 1500000,      52,     84 },
 138        { 1536000,      52,     84 },
 139        { 2000000,      40,     64 },
 140        { 2048000,      40,     64 },
 141        { 2400000,      34,     54 },
 142        { 2822400,      28,     44 },
 143        { 3000000,      28,     44 },
 144        { 3072000,      28,     44 },
 145        { 3200000,      27,     42 },
 146        { 4000000,      22,     34 },
 147        { 4096000,      22,     34 },
 148        { 4800000,      19,     29 },
 149        { 5644800,      16,     24 },
 150        { 6000000,      16,     24 },
 151        { 6144000,      16,     24 },
 152};
 153
 154static const unsigned char cs35l41_bst_k1_table[4][5] = {
 155        { 0x24, 0x32, 0x32, 0x4F, 0x57 },
 156        { 0x24, 0x32, 0x32, 0x4F, 0x57 },
 157        { 0x40, 0x32, 0x32, 0x4F, 0x57 },
 158        { 0x40, 0x32, 0x32, 0x4F, 0x57 }
 159};
 160
 161static const unsigned char cs35l41_bst_k2_table[4][5] = {
 162        { 0x24, 0x49, 0x66, 0xA3, 0xEA },
 163        { 0x24, 0x49, 0x66, 0xA3, 0xEA },
 164        { 0x48, 0x49, 0x66, 0xA3, 0xEA },
 165        { 0x48, 0x49, 0x66, 0xA3, 0xEA }
 166};
 167
 168static const unsigned char cs35l41_bst_slope_table[4] = {
 169        0x75, 0x6B, 0x3B, 0x28
 170};
 171
 172static int cs35l41_get_fs_mon_config_index(int freq)
 173{
 174        int i;
 175
 176        for (i = 0; i < ARRAY_SIZE(cs35l41_fs_mon); i++) {
 177                if (cs35l41_fs_mon[i].freq == freq)
 178                        return i;
 179        }
 180
 181        return -EINVAL;
 182}
 183
 184static const DECLARE_TLV_DB_RANGE(dig_vol_tlv,
 185                0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
 186                1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200));
 187static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
 188
 189static const struct snd_kcontrol_new dre_ctrl =
 190        SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0);
 191
 192static const char * const cs35l41_pcm_sftramp_text[] =  {
 193        "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"
 194};
 195
 196static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
 197                            CS35L41_AMP_DIG_VOL_CTRL, 0,
 198                            cs35l41_pcm_sftramp_text);
 199
 200static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
 201static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
 202static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum,
 203                                  CS35L41_DAC_PCM1_SRC,
 204                                  0, CS35L41_ASP_SOURCE_MASK,
 205                                  cs35l41_pcm_source_texts,
 206                                  cs35l41_pcm_source_values);
 207
 208static const struct snd_kcontrol_new pcm_source_mux =
 209        SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum);
 210
 211static const char * const cs35l41_tx_input_texts[] = {
 212        "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON",
 213        "VPMON", "VBSTMON", "DSPTX1", "DSPTX2"
 214};
 215
 216static const unsigned int cs35l41_tx_input_values[] = {
 217        0x00, CS35L41_INPUT_SRC_ASPRX1, CS35L41_INPUT_SRC_ASPRX2,
 218        CS35L41_INPUT_SRC_VMON, CS35L41_INPUT_SRC_IMON, CS35L41_INPUT_SRC_VPMON,
 219        CS35L41_INPUT_SRC_VBSTMON, CS35L41_INPUT_DSP_TX1, CS35L41_INPUT_DSP_TX2
 220};
 221
 222static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum,
 223                                  CS35L41_ASP_TX1_SRC,
 224                                  0, CS35L41_ASP_SOURCE_MASK,
 225                                  cs35l41_tx_input_texts,
 226                                  cs35l41_tx_input_values);
 227
 228static const struct snd_kcontrol_new asp_tx1_mux =
 229        SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum);
 230
 231static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum,
 232                                  CS35L41_ASP_TX2_SRC,
 233                                  0, CS35L41_ASP_SOURCE_MASK,
 234                                  cs35l41_tx_input_texts,
 235                                  cs35l41_tx_input_values);
 236
 237static const struct snd_kcontrol_new asp_tx2_mux =
 238        SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum);
 239
 240static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum,
 241                                  CS35L41_ASP_TX3_SRC,
 242                                  0, CS35L41_ASP_SOURCE_MASK,
 243                                  cs35l41_tx_input_texts,
 244                                  cs35l41_tx_input_values);
 245
 246static const struct snd_kcontrol_new asp_tx3_mux =
 247        SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum);
 248
 249static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum,
 250                                  CS35L41_ASP_TX4_SRC,
 251                                  0, CS35L41_ASP_SOURCE_MASK,
 252                                  cs35l41_tx_input_texts,
 253                                  cs35l41_tx_input_values);
 254
 255static const struct snd_kcontrol_new asp_tx4_mux =
 256        SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum);
 257
 258static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
 259        SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL,
 260                          3, 0x4CF, 0x391, dig_vol_tlv),
 261        SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0,
 262                       amp_gain_tlv),
 263        SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
 264        SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0),
 265        SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0),
 266        SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0),
 267        SOC_SINGLE("Aux Noise Gate CH1 Enable",
 268                   CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0),
 269        SOC_SINGLE("Aux Noise Gate CH1 Entry Delay",
 270                   CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0),
 271        SOC_SINGLE("Aux Noise Gate CH1 Threshold",
 272                   CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0),
 273        SOC_SINGLE("Aux Noise Gate CH2 Entry Delay",
 274                   CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0),
 275        SOC_SINGLE("Aux Noise Gate CH2 Enable",
 276                   CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0),
 277        SOC_SINGLE("Aux Noise Gate CH2 Threshold",
 278                   CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0),
 279        SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0),
 280        SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0),
 281        SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL,
 282                   CS35L41_AMP_INV_PCM_SHIFT, 1, 0),
 283        SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL,
 284                   CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0),
 285};
 286
 287static const struct cs35l41_otp_map_element_t *cs35l41_find_otp_map(u32 otp_id)
 288{
 289        int i;
 290
 291        for (i = 0; i < ARRAY_SIZE(cs35l41_otp_map_map); i++) {
 292                if (cs35l41_otp_map_map[i].id == otp_id)
 293                        return &cs35l41_otp_map_map[i];
 294        }
 295
 296        return NULL;
 297}
 298
 299static int cs35l41_otp_unpack(void *data)
 300{
 301        const struct cs35l41_otp_map_element_t *otp_map_match;
 302        const struct cs35l41_otp_packed_element_t *otp_map;
 303        struct cs35l41_private *cs35l41 = data;
 304        int bit_offset, word_offset, ret, i;
 305        unsigned int bit_sum = 8;
 306        u32 otp_val, otp_id_reg;
 307        u32 *otp_mem;
 308
 309        otp_mem = kmalloc_array(CS35L41_OTP_SIZE_WORDS, sizeof(*otp_mem), GFP_KERNEL);
 310        if (!otp_mem)
 311                return -ENOMEM;
 312
 313        ret = regmap_read(cs35l41->regmap, CS35L41_OTPID, &otp_id_reg);
 314        if (ret < 0) {
 315                dev_err(cs35l41->dev, "Read OTP ID failed: %d\n", ret);
 316                goto err_otp_unpack;
 317        }
 318
 319        otp_map_match = cs35l41_find_otp_map(otp_id_reg);
 320
 321        if (!otp_map_match) {
 322                dev_err(cs35l41->dev, "OTP Map matching ID %d not found\n",
 323                        otp_id_reg);
 324                ret = -EINVAL;
 325                goto err_otp_unpack;
 326        }
 327
 328        ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem,
 329                               CS35L41_OTP_SIZE_WORDS);
 330        if (ret < 0) {
 331                dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret);
 332                goto err_otp_unpack;
 333        }
 334
 335        otp_map = otp_map_match->map;
 336
 337        bit_offset = otp_map_match->bit_offset;
 338        word_offset = otp_map_match->word_offset;
 339
 340        ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000055);
 341        if (ret < 0) {
 342                dev_err(cs35l41->dev, "Write Unlock key failed 1/2: %d\n", ret);
 343                goto err_otp_unpack;
 344        }
 345        ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000AA);
 346        if (ret < 0) {
 347                dev_err(cs35l41->dev, "Write Unlock key failed 2/2: %d\n", ret);
 348                goto err_otp_unpack;
 349        }
 350
 351        for (i = 0; i < otp_map_match->num_elements; i++) {
 352                dev_dbg(cs35l41->dev,
 353                        "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n",
 354                        bit_offset, word_offset, bit_sum % 32);
 355                if (bit_offset + otp_map[i].size - 1 >= 32) {
 356                        otp_val = (otp_mem[word_offset] &
 357                                        GENMASK(31, bit_offset)) >>
 358                                        bit_offset;
 359                        otp_val |= (otp_mem[++word_offset] &
 360                                        GENMASK(bit_offset +
 361                                                otp_map[i].size - 33, 0)) <<
 362                                        (32 - bit_offset);
 363                        bit_offset += otp_map[i].size - 32;
 364                } else {
 365                        otp_val = (otp_mem[word_offset] &
 366                                GENMASK(bit_offset + otp_map[i].size - 1,
 367                                        bit_offset)) >> bit_offset;
 368                        bit_offset += otp_map[i].size;
 369                }
 370                bit_sum += otp_map[i].size;
 371
 372                if (bit_offset == 32) {
 373                        bit_offset = 0;
 374                        word_offset++;
 375                }
 376
 377                if (otp_map[i].reg != 0) {
 378                        ret = regmap_update_bits(cs35l41->regmap,
 379                                                 otp_map[i].reg,
 380                                                 GENMASK(otp_map[i].shift +
 381                                                         otp_map[i].size - 1,
 382                                                 otp_map[i].shift),
 383                                                 otp_val << otp_map[i].shift);
 384                        if (ret < 0) {
 385                                dev_err(cs35l41->dev, "Write OTP val failed: %d\n",
 386                                        ret);
 387                                goto err_otp_unpack;
 388                        }
 389                }
 390        }
 391
 392        ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x000000CC);
 393        if (ret < 0) {
 394                dev_err(cs35l41->dev, "Write Lock key failed 1/2: %d\n", ret);
 395                goto err_otp_unpack;
 396        }
 397        ret = regmap_write(cs35l41->regmap, CS35L41_TEST_KEY_CTL, 0x00000033);
 398        if (ret < 0) {
 399                dev_err(cs35l41->dev, "Write Lock key failed 2/2: %d\n", ret);
 400                goto err_otp_unpack;
 401        }
 402        ret = 0;
 403
 404err_otp_unpack:
 405        kfree(otp_mem);
 406        return ret;
 407}
 408
 409static irqreturn_t cs35l41_irq(int irq, void *data)
 410{
 411        struct cs35l41_private *cs35l41 = data;
 412        unsigned int status[4] = { 0, 0, 0, 0 };
 413        unsigned int masks[4] = { 0, 0, 0, 0 };
 414        int ret = IRQ_NONE;
 415        unsigned int i;
 416
 417        for (i = 0; i < ARRAY_SIZE(status); i++) {
 418                regmap_read(cs35l41->regmap,
 419                            CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE),
 420                            &status[i]);
 421                regmap_read(cs35l41->regmap,
 422                            CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE),
 423                            &masks[i]);
 424        }
 425
 426        /* Check to see if unmasked bits are active */
 427        if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&
 428            !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
 429                return IRQ_NONE;
 430
 431        if (status[3] & CS35L41_OTP_BOOT_DONE) {
 432                regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4,
 433                                   CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE);
 434        }
 435
 436        /*
 437         * The following interrupts require a
 438         * protection release cycle to get the
 439         * speaker out of Safe-Mode.
 440         */
 441        if (status[0] & CS35L41_AMP_SHORT_ERR) {
 442                dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
 443                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 444                             CS35L41_AMP_SHORT_ERR);
 445                regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
 446                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 447                                   CS35L41_AMP_SHORT_ERR_RLS,
 448                                   CS35L41_AMP_SHORT_ERR_RLS);
 449                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 450                                   CS35L41_AMP_SHORT_ERR_RLS, 0);
 451                ret = IRQ_HANDLED;
 452        }
 453
 454        if (status[0] & CS35L41_TEMP_WARN) {
 455                dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
 456                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 457                             CS35L41_TEMP_WARN);
 458                regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
 459                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 460                                   CS35L41_TEMP_WARN_ERR_RLS,
 461                                   CS35L41_TEMP_WARN_ERR_RLS);
 462                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 463                                   CS35L41_TEMP_WARN_ERR_RLS, 0);
 464                ret = IRQ_HANDLED;
 465        }
 466
 467        if (status[0] & CS35L41_TEMP_ERR) {
 468                dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
 469                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 470                             CS35L41_TEMP_ERR);
 471                regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
 472                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 473                                   CS35L41_TEMP_ERR_RLS,
 474                                   CS35L41_TEMP_ERR_RLS);
 475                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 476                                   CS35L41_TEMP_ERR_RLS, 0);
 477                ret = IRQ_HANDLED;
 478        }
 479
 480        if (status[0] & CS35L41_BST_OVP_ERR) {
 481                dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
 482                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 483                                   CS35L41_BST_EN_MASK, 0);
 484                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 485                             CS35L41_BST_OVP_ERR);
 486                regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
 487                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 488                                   CS35L41_BST_OVP_ERR_RLS,
 489                                   CS35L41_BST_OVP_ERR_RLS);
 490                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 491                                   CS35L41_BST_OVP_ERR_RLS, 0);
 492                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 493                                   CS35L41_BST_EN_MASK,
 494                                   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
 495                ret = IRQ_HANDLED;
 496        }
 497
 498        if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
 499                dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
 500                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 501                                   CS35L41_BST_EN_MASK, 0);
 502                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 503                             CS35L41_BST_DCM_UVP_ERR);
 504                regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
 505                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 506                                   CS35L41_BST_UVP_ERR_RLS,
 507                                   CS35L41_BST_UVP_ERR_RLS);
 508                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 509                                   CS35L41_BST_UVP_ERR_RLS, 0);
 510                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 511                                   CS35L41_BST_EN_MASK,
 512                                   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
 513                ret = IRQ_HANDLED;
 514        }
 515
 516        if (status[0] & CS35L41_BST_SHORT_ERR) {
 517                dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
 518                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 519                                   CS35L41_BST_EN_MASK, 0);
 520                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 521                             CS35L41_BST_SHORT_ERR);
 522                regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
 523                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 524                                   CS35L41_BST_SHORT_ERR_RLS,
 525                                   CS35L41_BST_SHORT_ERR_RLS);
 526                regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
 527                                   CS35L41_BST_SHORT_ERR_RLS, 0);
 528                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
 529                                   CS35L41_BST_EN_MASK,
 530                                   CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
 531                ret = IRQ_HANDLED;
 532        }
 533
 534        return ret;
 535}
 536
 537static const struct reg_sequence cs35l41_pup_patch[] = {
 538        { 0x00000040, 0x00000055 },
 539        { 0x00000040, 0x000000AA },
 540        { 0x00002084, 0x002F1AA0 },
 541        { 0x00000040, 0x000000CC },
 542        { 0x00000040, 0x00000033 },
 543};
 544
 545static const struct reg_sequence cs35l41_pdn_patch[] = {
 546        { 0x00000040, 0x00000055 },
 547        { 0x00000040, 0x000000AA },
 548        { 0x00002084, 0x002F1AA3 },
 549        { 0x00000040, 0x000000CC },
 550        { 0x00000040, 0x00000033 },
 551};
 552
 553static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
 554                                  struct snd_kcontrol *kcontrol, int event)
 555{
 556        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 557        struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
 558        unsigned int val;
 559        int ret = 0;
 560
 561        switch (event) {
 562        case SND_SOC_DAPM_POST_PMU:
 563                regmap_multi_reg_write_bypassed(cs35l41->regmap,
 564                                                cs35l41_pup_patch,
 565                                                ARRAY_SIZE(cs35l41_pup_patch));
 566
 567                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
 568                                   CS35L41_GLOBAL_EN_MASK,
 569                                   1 << CS35L41_GLOBAL_EN_SHIFT);
 570
 571                usleep_range(1000, 1100);
 572                break;
 573        case SND_SOC_DAPM_POST_PMD:
 574                regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
 575                                   CS35L41_GLOBAL_EN_MASK, 0);
 576
 577                ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 578                                               val, val &  CS35L41_PDN_DONE_MASK,
 579                                               1000, 100000);
 580                if (ret)
 581                        dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
 582
 583                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
 584                             CS35L41_PDN_DONE_MASK);
 585
 586                regmap_multi_reg_write_bypassed(cs35l41->regmap,
 587                                                cs35l41_pdn_patch,
 588                                                ARRAY_SIZE(cs35l41_pdn_patch));
 589                break;
 590        default:
 591                dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event);
 592                ret = -EINVAL;
 593        }
 594
 595        return ret;
 596}
 597
 598static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
 599        SND_SOC_DAPM_OUTPUT("SPK"),
 600
 601        SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0),
 602        SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0),
 603        SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0),
 604        SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0),
 605        SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
 606        SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
 607
 608        SND_SOC_DAPM_SIGGEN("VSENSE"),
 609        SND_SOC_DAPM_SIGGEN("ISENSE"),
 610        SND_SOC_DAPM_SIGGEN("VP"),
 611        SND_SOC_DAPM_SIGGEN("VBST"),
 612        SND_SOC_DAPM_SIGGEN("TEMP"),
 613
 614        SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L41_PWR_CTRL2, 12, 0),
 615        SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L41_PWR_CTRL2, 13, 0),
 616        SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L41_PWR_CTRL2, 8, 0),
 617        SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L41_PWR_CTRL2, 9, 0),
 618        SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, CS35L41_PWR_CTRL2, 10, 0),
 619        SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0),
 620
 621        SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
 622                               cs35l41_main_amp_event,
 623                               SND_SOC_DAPM_POST_PMD |  SND_SOC_DAPM_POST_PMU),
 624
 625        SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
 626        SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
 627        SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
 628        SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux),
 629        SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux),
 630        SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl),
 631};
 632
 633static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
 634        {"ASP TX1 Source", "VMON", "VMON ADC"},
 635        {"ASP TX1 Source", "IMON", "IMON ADC"},
 636        {"ASP TX1 Source", "VPMON", "VPMON ADC"},
 637        {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"},
 638        {"ASP TX1 Source", "ASPRX1", "ASPRX1" },
 639        {"ASP TX1 Source", "ASPRX2", "ASPRX2" },
 640        {"ASP TX2 Source", "VMON", "VMON ADC"},
 641        {"ASP TX2 Source", "IMON", "IMON ADC"},
 642        {"ASP TX2 Source", "VPMON", "VPMON ADC"},
 643        {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"},
 644        {"ASP TX2 Source", "ASPRX1", "ASPRX1" },
 645        {"ASP TX2 Source", "ASPRX2", "ASPRX2" },
 646        {"ASP TX3 Source", "VMON", "VMON ADC"},
 647        {"ASP TX3 Source", "IMON", "IMON ADC"},
 648        {"ASP TX3 Source", "VPMON", "VPMON ADC"},
 649        {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"},
 650        {"ASP TX3 Source", "ASPRX1", "ASPRX1" },
 651        {"ASP TX3 Source", "ASPRX2", "ASPRX2" },
 652        {"ASP TX4 Source", "VMON", "VMON ADC"},
 653        {"ASP TX4 Source", "IMON", "IMON ADC"},
 654        {"ASP TX4 Source", "VPMON", "VPMON ADC"},
 655        {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"},
 656        {"ASP TX4 Source", "ASPRX1", "ASPRX1" },
 657        {"ASP TX4 Source", "ASPRX2", "ASPRX2" },
 658        {"ASPTX1", NULL, "ASP TX1 Source"},
 659        {"ASPTX2", NULL, "ASP TX2 Source"},
 660        {"ASPTX3", NULL, "ASP TX3 Source"},
 661        {"ASPTX4", NULL, "ASP TX4 Source"},
 662        {"AMP Capture", NULL, "ASPTX1"},
 663        {"AMP Capture", NULL, "ASPTX2"},
 664        {"AMP Capture", NULL, "ASPTX3"},
 665        {"AMP Capture", NULL, "ASPTX4"},
 666
 667        {"VMON ADC", NULL, "VSENSE"},
 668        {"IMON ADC", NULL, "ISENSE"},
 669        {"VPMON ADC", NULL, "VP"},
 670        {"VBSTMON ADC", NULL, "VBST"},
 671        {"TEMPMON ADC", NULL, "TEMP"},
 672
 673        {"ASPRX1", NULL, "AMP Playback"},
 674        {"ASPRX2", NULL, "AMP Playback"},
 675        {"DRE", "Switch", "CLASS H"},
 676        {"Main AMP", NULL, "CLASS H"},
 677        {"Main AMP", NULL, "DRE"},
 678        {"SPK", NULL, "Main AMP"},
 679
 680        {"PCM Source", "ASP", "ASPRX1"},
 681        {"CLASS H", NULL, "PCM Source"},
 682};
 683
 684static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num,
 685                                   unsigned int *tx_slot, unsigned int rx_num,
 686                                   unsigned int *rx_slot)
 687{
 688        struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
 689        unsigned int val, mask;
 690        int i;
 691
 692        if (tx_num > 4 || rx_num > 2)
 693                return -EINVAL;
 694
 695        val = 0;
 696        mask = 0;
 697        for (i = 0; i < rx_num; i++) {
 698                dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]);
 699                val |= rx_slot[i] << (i * 8);
 700                mask |= 0x3F << (i * 8);
 701        }
 702        regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val);
 703
 704        val = 0;
 705        mask = 0;
 706        for (i = 0; i < tx_num; i++) {
 707                dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]);
 708                val |= tx_slot[i] << (i * 8);
 709                mask |= 0x3F << (i * 8);
 710        }
 711        regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val);
 712
 713        return 0;
 714}
 715
 716static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 717{
 718        struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
 719        unsigned int daifmt = 0;
 720
 721        switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 722        case SND_SOC_DAIFMT_CBP_CFP:
 723                daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
 724                break;
 725        case SND_SOC_DAIFMT_CBC_CFC:
 726                break;
 727        default:
 728                dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n");
 729                return -EINVAL;
 730        }
 731
 732        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 733        case SND_SOC_DAIFMT_DSP_A:
 734                break;
 735        case SND_SOC_DAIFMT_I2S:
 736                daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
 737                break;
 738        default:
 739                dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n");
 740                return -EINVAL;
 741        }
 742
 743        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 744        case SND_SOC_DAIFMT_NB_IF:
 745                daifmt |= CS35L41_LRCLK_INV_MASK;
 746                break;
 747        case SND_SOC_DAIFMT_IB_NF:
 748                daifmt |= CS35L41_SCLK_INV_MASK;
 749                break;
 750        case SND_SOC_DAIFMT_IB_IF:
 751                daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
 752                break;
 753        case SND_SOC_DAIFMT_NB_NF:
 754                break;
 755        default:
 756                dev_warn(cs35l41->dev, "Invalid DAI clock INV\n");
 757                return -EINVAL;
 758        }
 759
 760        return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
 761                                  CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
 762                                  CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
 763                                  CS35L41_SCLK_INV_MASK, daifmt);
 764}
 765
 766struct cs35l41_global_fs_config {
 767        int rate;
 768        int fs_cfg;
 769};
 770
 771static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = {
 772        { 12000,        0x01 },
 773        { 24000,        0x02 },
 774        { 48000,        0x03 },
 775        { 96000,        0x04 },
 776        { 192000,       0x05 },
 777        { 11025,        0x09 },
 778        { 22050,        0x0A },
 779        { 44100,        0x0B },
 780        { 88200,        0x0C },
 781        { 176400,       0x0D },
 782        { 8000,         0x11 },
 783        { 16000,        0x12 },
 784        { 32000,        0x13 },
 785};
 786
 787static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
 788                                 struct snd_pcm_hw_params *params,
 789                                 struct snd_soc_dai *dai)
 790{
 791        struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
 792        unsigned int rate = params_rate(params);
 793        u8 asp_wl;
 794        int i;
 795
 796        for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) {
 797                if (rate == cs35l41_fs_rates[i].rate)
 798                        break;
 799        }
 800
 801        if (i >= ARRAY_SIZE(cs35l41_fs_rates)) {
 802                dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate);
 803                return -EINVAL;
 804        }
 805
 806        asp_wl = params_width(params);
 807
 808        if (i < ARRAY_SIZE(cs35l41_fs_rates))
 809                regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL,
 810                                   CS35L41_GLOBAL_FS_MASK,
 811                                   cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT);
 812
 813        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 814                regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
 815                                   CS35L41_ASP_WIDTH_RX_MASK,
 816                                   asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT);
 817                regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
 818                                   CS35L41_ASP_RX_WL_MASK,
 819                                   asp_wl << CS35L41_ASP_RX_WL_SHIFT);
 820        } else {
 821                regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
 822                                   CS35L41_ASP_WIDTH_TX_MASK,
 823                                   asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT);
 824                regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL,
 825                                   CS35L41_ASP_TX_WL_MASK,
 826                                   asp_wl << CS35L41_ASP_TX_WL_SHIFT);
 827        }
 828
 829        return 0;
 830}
 831
 832static int cs35l41_get_clk_config(int freq)
 833{
 834        int i;
 835
 836        for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) {
 837                if (cs35l41_pll_sysclk[i].freq == freq)
 838                        return cs35l41_pll_sysclk[i].clk_cfg;
 839        }
 840
 841        return -EINVAL;
 842}
 843
 844static const unsigned int cs35l41_src_rates[] = {
 845        8000, 12000, 11025, 16000, 22050, 24000, 32000,
 846        44100, 48000, 88200, 96000, 176400, 192000
 847};
 848
 849static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
 850        .count = ARRAY_SIZE(cs35l41_src_rates),
 851        .list = cs35l41_src_rates,
 852};
 853
 854static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
 855                               struct snd_soc_dai *dai)
 856{
 857        if (substream->runtime)
 858                return snd_pcm_hw_constraint_list(substream->runtime, 0,
 859                                                  SNDRV_PCM_HW_PARAM_RATE,
 860                                                  &cs35l41_constraints);
 861        return 0;
 862}
 863
 864static int cs35l41_component_set_sysclk(struct snd_soc_component *component,
 865                                        int clk_id, int source,
 866                                        unsigned int freq, int dir)
 867{
 868        struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
 869        int extclk_cfg, clksrc;
 870
 871        switch (clk_id) {
 872        case CS35L41_CLKID_SCLK:
 873                clksrc = CS35L41_PLLSRC_SCLK;
 874                break;
 875        case CS35L41_CLKID_LRCLK:
 876                clksrc = CS35L41_PLLSRC_LRCLK;
 877                break;
 878        case CS35L41_CLKID_MCLK:
 879                clksrc = CS35L41_PLLSRC_MCLK;
 880                break;
 881        default:
 882                dev_err(cs35l41->dev, "Invalid CLK Config\n");
 883                return -EINVAL;
 884        }
 885
 886        extclk_cfg = cs35l41_get_clk_config(freq);
 887
 888        if (extclk_cfg < 0) {
 889                dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n",
 890                        extclk_cfg, freq);
 891                return -EINVAL;
 892        }
 893
 894        regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
 895                           CS35L41_PLL_OPENLOOP_MASK,
 896                           1 << CS35L41_PLL_OPENLOOP_SHIFT);
 897        regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
 898                           CS35L41_REFCLK_FREQ_MASK,
 899                           extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT);
 900        regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
 901                           CS35L41_PLL_CLK_EN_MASK,
 902                           0 << CS35L41_PLL_CLK_EN_SHIFT);
 903        regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
 904                           CS35L41_PLL_CLK_SEL_MASK, clksrc);
 905        regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
 906                           CS35L41_PLL_OPENLOOP_MASK,
 907                           0 << CS35L41_PLL_OPENLOOP_SHIFT);
 908        regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
 909                           CS35L41_PLL_CLK_EN_MASK,
 910                           1 << CS35L41_PLL_CLK_EN_SHIFT);
 911
 912        return 0;
 913}
 914
 915static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,
 916                                  int clk_id, unsigned int freq, int dir)
 917{
 918        struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
 919        unsigned int fs1_val;
 920        unsigned int fs2_val;
 921        unsigned int val;
 922        int fsindex;
 923
 924        fsindex = cs35l41_get_fs_mon_config_index(freq);
 925        if (fsindex < 0) {
 926                dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq);
 927                return -EINVAL;
 928        }
 929
 930        dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq);
 931
 932        if (freq <= 6144000) {
 933                /* Use the lookup table */
 934                fs1_val = cs35l41_fs_mon[fsindex].fs1;
 935                fs2_val = cs35l41_fs_mon[fsindex].fs2;
 936        } else {
 937                /* Use hard-coded values */
 938                fs1_val = 0x10;
 939                fs2_val = 0x24;
 940        }
 941
 942        val = fs1_val;
 943        val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK;
 944        regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val);
 945
 946        return 0;
 947}
 948
 949static int cs35l41_boost_config(struct cs35l41_private *cs35l41,
 950                                int boost_ind, int boost_cap, int boost_ipk)
 951{
 952        unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled;
 953        struct regmap *regmap = cs35l41->regmap;
 954        struct device *dev = cs35l41->dev;
 955        int ret;
 956
 957        switch (boost_ind) {
 958        case 1000:      /* 1.0 uH */
 959                bst_lbst_val = 0;
 960                break;
 961        case 1200:      /* 1.2 uH */
 962                bst_lbst_val = 1;
 963                break;
 964        case 1500:      /* 1.5 uH */
 965                bst_lbst_val = 2;
 966                break;
 967        case 2200:      /* 2.2 uH */
 968                bst_lbst_val = 3;
 969                break;
 970        default:
 971                dev_err(dev, "Invalid boost inductor value: %d nH\n", boost_ind);
 972                return -EINVAL;
 973        }
 974
 975        switch (boost_cap) {
 976        case 0 ... 19:
 977                bst_cbst_range = 0;
 978                break;
 979        case 20 ... 50:
 980                bst_cbst_range = 1;
 981                break;
 982        case 51 ... 100:
 983                bst_cbst_range = 2;
 984                break;
 985        case 101 ... 200:
 986                bst_cbst_range = 3;
 987                break;
 988        default:        /* 201 uF and greater */
 989                bst_cbst_range = 4;
 990        }
 991
 992        ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
 993                                 CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK,
 994                                 cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
 995                                        << CS35L41_BST_K1_SHIFT |
 996                                 cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range]
 997                                        << CS35L41_BST_K2_SHIFT);
 998        if (ret) {
 999                dev_err(dev, "Failed to write boost coefficients: %d\n", ret);
1000                return ret;
1001        }
1002
1003        ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST,
1004                                 CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK,
1005                                 cs35l41_bst_slope_table[bst_lbst_val]
1006                                        << CS35L41_BST_SLOPE_SHIFT |
1007                                 bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT);
1008        if (ret) {
1009                dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret);
1010                return ret;
1011        }
1012
1013        if (boost_ipk < 1600 || boost_ipk > 4500) {
1014                dev_err(dev, "Invalid boost inductor peak current: %d mA\n",
1015                        boost_ipk);
1016                return -EINVAL;
1017        }
1018        bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10;
1019
1020        ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR,
1021                                 CS35L41_BST_IPK_MASK,
1022                                 bst_ipk_scaled << CS35L41_BST_IPK_SHIFT);
1023        if (ret) {
1024                dev_err(dev, "Failed to write boost inductor peak current: %d\n", ret);
1025                return ret;
1026        }
1027
1028        return 0;
1029}
1030
1031static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
1032{
1033        int ret;
1034
1035        /* Set Platform Data */
1036        /* Required */
1037        if (cs35l41->pdata.bst_ipk &&
1038            cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) {
1039                ret = cs35l41_boost_config(cs35l41, cs35l41->pdata.bst_ind,
1040                                           cs35l41->pdata.bst_cap,
1041                                           cs35l41->pdata.bst_ipk);
1042                if (ret) {
1043                        dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
1044                        return ret;
1045                }
1046        } else {
1047                dev_err(cs35l41->dev, "Incomplete Boost component DT config\n");
1048                return -EINVAL;
1049        }
1050
1051        /* Optional */
1052        if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK &&
1053            cs35l41->pdata.dout_hiz >= 0)
1054                regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL,
1055                                   CS35L41_ASP_DOUT_HIZ_MASK,
1056                                   cs35l41->pdata.dout_hiz);
1057
1058        return 0;
1059}
1060
1061static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41)
1062{
1063        struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1;
1064        struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2;
1065        int irq_pol = IRQF_TRIGGER_NONE;
1066
1067        regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1,
1068                           CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1069                           irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1070                           !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1071
1072        regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1,
1073                           CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
1074                           irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
1075                           !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
1076
1077        regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
1078                           CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
1079                           irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT |
1080                           irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT);
1081
1082        if ((irq_gpio_cfg2->irq_src_sel ==
1083                        (CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) ||
1084                (irq_gpio_cfg2->irq_src_sel ==
1085                        (CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA)))
1086                irq_pol = IRQF_TRIGGER_LOW;
1087        else if (irq_gpio_cfg2->irq_src_sel ==
1088                        (CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA))
1089                irq_pol = IRQF_TRIGGER_HIGH;
1090
1091        return irq_pol;
1092}
1093
1094static const struct snd_soc_dai_ops cs35l41_ops = {
1095        .startup = cs35l41_pcm_startup,
1096        .set_fmt = cs35l41_set_dai_fmt,
1097        .hw_params = cs35l41_pcm_hw_params,
1098        .set_sysclk = cs35l41_dai_set_sysclk,
1099        .set_channel_map = cs35l41_set_channel_map,
1100};
1101
1102static struct snd_soc_dai_driver cs35l41_dai[] = {
1103        {
1104                .name = "cs35l41-pcm",
1105                .id = 0,
1106                .playback = {
1107                        .stream_name = "AMP Playback",
1108                        .channels_min = 1,
1109                        .channels_max = 2,
1110                        .rates = SNDRV_PCM_RATE_KNOT,
1111                        .formats = CS35L41_RX_FORMATS,
1112                },
1113                .capture = {
1114                        .stream_name = "AMP Capture",
1115                        .channels_min = 1,
1116                        .channels_max = 8,
1117                        .rates = SNDRV_PCM_RATE_KNOT,
1118                        .formats = CS35L41_TX_FORMATS,
1119                },
1120                .ops = &cs35l41_ops,
1121                .symmetric_rate = 1,
1122        },
1123};
1124
1125static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
1126        .name = "cs35l41-codec",
1127
1128        .dapm_widgets = cs35l41_dapm_widgets,
1129        .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets),
1130        .dapm_routes = cs35l41_audio_map,
1131        .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map),
1132
1133        .controls = cs35l41_aud_controls,
1134        .num_controls = ARRAY_SIZE(cs35l41_aud_controls),
1135        .set_sysclk = cs35l41_component_set_sysclk,
1136};
1137
1138static int cs35l41_handle_pdata(struct device *dev,
1139                                struct cs35l41_platform_data *pdata,
1140                                struct cs35l41_private *cs35l41)
1141{
1142        struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1;
1143        struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2;
1144        unsigned int val;
1145        int ret;
1146
1147        ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1148        if (ret >= 0)
1149                pdata->bst_ipk = val;
1150
1151        ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
1152        if (ret >= 0)
1153                pdata->bst_ind = val;
1154
1155        ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
1156        if (ret >= 0)
1157                pdata->bst_cap = val;
1158
1159        ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
1160        if (ret >= 0)
1161                pdata->dout_hiz = val;
1162        else
1163                pdata->dout_hiz = -1;
1164
1165        /* GPIO1 Pin Config */
1166        irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev,
1167                                        "cirrus,gpio1-polarity-invert");
1168        irq_gpio1_config->irq_out_en = device_property_read_bool(dev,
1169                                        "cirrus,gpio1-output-enable");
1170        ret = device_property_read_u32(dev, "cirrus,gpio1-src-select",
1171                                       &val);
1172        if (ret >= 0)
1173                irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1174
1175        /* GPIO2 Pin Config */
1176        irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev,
1177                                        "cirrus,gpio2-polarity-invert");
1178        irq_gpio2_config->irq_out_en = device_property_read_bool(dev,
1179                                        "cirrus,gpio2-output-enable");
1180        ret = device_property_read_u32(dev, "cirrus,gpio2-src-select",
1181                                       &val);
1182        if (ret >= 0)
1183                irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA;
1184
1185        return 0;
1186}
1187
1188static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
1189        { 0x00000040,                    0x00005555 },
1190        { 0x00000040,                    0x0000AAAA },
1191        { 0x00003854,                    0x05180240 },
1192        { CS35L41_VIMON_SPKMON_RESYNC,   0x00000000 },
1193        { 0x00004310,                    0x00000000 },
1194        { CS35L41_VPVBST_FS_SEL,         0x00000000 },
1195        { CS35L41_OTP_TRIM_30,           0x9091A1C8 },
1196        { 0x00003014,                    0x0200EE0E },
1197        { CS35L41_BSTCVRT_DCM_CTRL,      0x00000051 },
1198        { 0x00000054,                    0x00000004 },
1199        { CS35L41_IRQ1_DB3,              0x00000000 },
1200        { CS35L41_IRQ2_DB3,              0x00000000 },
1201        { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1202        { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1203        { 0x00000040,                    0x0000CCCC },
1204        { 0x00000040,                    0x00003333 },
1205};
1206
1207static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
1208        { 0x00000040,                    0x00005555 },
1209        { 0x00000040,                    0x0000AAAA },
1210        { CS35L41_VIMON_SPKMON_RESYNC,   0x00000000 },
1211        { 0x00004310,                    0x00000000 },
1212        { CS35L41_VPVBST_FS_SEL,         0x00000000 },
1213        { CS35L41_BSTCVRT_DCM_CTRL,      0x00000051 },
1214        { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1215        { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1216        { 0x00000040,                    0x0000CCCC },
1217        { 0x00000040,                    0x00003333 },
1218};
1219
1220static const struct reg_sequence cs35l41_revb2_errata_patch[] = {
1221        { 0x00000040,                    0x00005555 },
1222        { 0x00000040,                    0x0000AAAA },
1223        { CS35L41_VIMON_SPKMON_RESYNC,   0x00000000 },
1224        { 0x00004310,                    0x00000000 },
1225        { CS35L41_VPVBST_FS_SEL,         0x00000000 },
1226        { CS35L41_BSTCVRT_DCM_CTRL,      0x00000051 },
1227        { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 },
1228        { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 },
1229        { 0x00000040,                    0x0000CCCC },
1230        { 0x00000040,                    0x00003333 },
1231};
1232
1233int cs35l41_probe(struct cs35l41_private *cs35l41,
1234                  struct cs35l41_platform_data *pdata)
1235{
1236        u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
1237        int irq_pol = 0;
1238        int ret;
1239
1240        if (pdata) {
1241                cs35l41->pdata = *pdata;
1242        } else {
1243                ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata, cs35l41);
1244                if (ret != 0)
1245                        return ret;
1246        }
1247
1248        for (i = 0; i < CS35L41_NUM_SUPPLIES; i++)
1249                cs35l41->supplies[i].supply = cs35l41_supplies[i];
1250
1251        ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
1252                                      cs35l41->supplies);
1253        if (ret != 0) {
1254                dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
1255                return ret;
1256        }
1257
1258        ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1259        if (ret != 0) {
1260                dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
1261                return ret;
1262        }
1263
1264        /* returning NULL can be an option if in stereo mode */
1265        cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
1266                                                      GPIOD_OUT_LOW);
1267        if (IS_ERR(cs35l41->reset_gpio)) {
1268                ret = PTR_ERR(cs35l41->reset_gpio);
1269                cs35l41->reset_gpio = NULL;
1270                if (ret == -EBUSY) {
1271                        dev_info(cs35l41->dev,
1272                                 "Reset line busy, assuming shared reset\n");
1273                } else {
1274                        dev_err(cs35l41->dev,
1275                                "Failed to get reset GPIO: %d\n", ret);
1276                        goto err;
1277                }
1278        }
1279        if (cs35l41->reset_gpio) {
1280                /* satisfy minimum reset pulse width spec */
1281                usleep_range(2000, 2100);
1282                gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
1283        }
1284
1285        usleep_range(2000, 2100);
1286
1287        ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4,
1288                                       int_status, int_status & CS35L41_OTP_BOOT_DONE,
1289                                       1000, 100000);
1290        if (ret) {
1291                dev_err(cs35l41->dev,
1292                        "Failed waiting for OTP_BOOT_DONE: %d\n", ret);
1293                goto err;
1294        }
1295
1296        regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status);
1297        if (int_status & CS35L41_OTP_BOOT_ERR) {
1298                dev_err(cs35l41->dev, "OTP Boot error\n");
1299                ret = -EINVAL;
1300                goto err;
1301        }
1302
1303        ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
1304        if (ret < 0) {
1305                dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
1306                goto err;
1307        }
1308
1309        ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
1310        if (ret < 0) {
1311                dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
1312                goto err;
1313        }
1314
1315        mtl_revid = reg_revid & CS35L41_MTLREVID_MASK;
1316
1317        /* CS35L41 will have even MTLREVID
1318         * CS35L41R will have odd MTLREVID
1319         */
1320        chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID;
1321        if (regid != chipid_match) {
1322                dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n",
1323                        regid, chipid_match);
1324                ret = -ENODEV;
1325                goto err;
1326        }
1327
1328        switch (reg_revid) {
1329        case CS35L41_REVID_A0:
1330                ret = regmap_register_patch(cs35l41->regmap,
1331                                            cs35l41_reva0_errata_patch,
1332                                            ARRAY_SIZE(cs35l41_reva0_errata_patch));
1333                if (ret < 0) {
1334                        dev_err(cs35l41->dev,
1335                                "Failed to apply A0 errata patch: %d\n", ret);
1336                        goto err;
1337                }
1338                break;
1339        case CS35L41_REVID_B0:
1340                ret = regmap_register_patch(cs35l41->regmap,
1341                                            cs35l41_revb0_errata_patch,
1342                                            ARRAY_SIZE(cs35l41_revb0_errata_patch));
1343                if (ret < 0) {
1344                        dev_err(cs35l41->dev,
1345                                "Failed to apply B0 errata patch: %d\n", ret);
1346                        goto err;
1347                }
1348                break;
1349        case CS35L41_REVID_B2:
1350                ret = regmap_register_patch(cs35l41->regmap,
1351                                            cs35l41_revb2_errata_patch,
1352                                            ARRAY_SIZE(cs35l41_revb2_errata_patch));
1353                if (ret < 0) {
1354                        dev_err(cs35l41->dev,
1355                                "Failed to apply B2 errata patch: %d\n", ret);
1356                        goto err;
1357                }
1358                break;
1359        }
1360
1361        irq_pol = cs35l41_irq_gpio_config(cs35l41);
1362
1363        /* Set interrupt masks for critical errors */
1364        regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1365                     CS35L41_INT1_MASK_DEFAULT);
1366
1367        ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1368                                        IRQF_ONESHOT | IRQF_SHARED | irq_pol,
1369                                        "cs35l41", cs35l41);
1370
1371        /* CS35L41 needs INT for PDN_DONE */
1372        if (ret != 0) {
1373                dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
1374                goto err;
1375        }
1376
1377        ret = cs35l41_otp_unpack(cs35l41);
1378        if (ret < 0) {
1379                dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
1380                goto err;
1381        }
1382
1383        ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_CCM_CORE_CTRL, 0);
1384        if (ret < 0) {
1385                dev_err(cs35l41->dev, "Write CCM_CORE_CTRL failed: %d\n", ret);
1386                goto err;
1387        }
1388
1389        ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
1390                                 CS35L41_AMP_EN_MASK, 0);
1391        if (ret < 0) {
1392                dev_err(cs35l41->dev, "Write CS35L41_PWR_CTRL2 failed: %d\n", ret);
1393                goto err;
1394        }
1395
1396        ret = regmap_update_bits(cs35l41->regmap, CS35L41_AMP_GAIN_CTRL,
1397                                 CS35L41_AMP_GAIN_PCM_MASK, 0);
1398        if (ret < 0) {
1399                dev_err(cs35l41->dev, "Write CS35L41_AMP_GAIN_CTRL failed: %d\n", ret);
1400                goto err;
1401        }
1402
1403        ret = cs35l41_set_pdata(cs35l41);
1404        if (ret < 0) {
1405                dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
1406                goto err;
1407        }
1408
1409        ret = devm_snd_soc_register_component(cs35l41->dev,
1410                                              &soc_component_dev_cs35l41,
1411                                              cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
1412        if (ret < 0) {
1413                dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
1414                goto err;
1415        }
1416
1417        dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n",
1418                 regid, reg_revid);
1419
1420        return 0;
1421
1422err:
1423        regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1424        gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1425
1426        return ret;
1427}
1428
1429void cs35l41_remove(struct cs35l41_private *cs35l41)
1430{
1431        regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1432        regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1433        gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1434}
1435
1436MODULE_DESCRIPTION("ASoC CS35L41 driver");
1437MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
1438MODULE_LICENSE("GPL");
1439