Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // cs35l41.c -- CS35l41 ALSA SoC audio driver
0004 //
0005 // Copyright 2017-2021 Cirrus Logic, Inc.
0006 //
0007 // Author: David Rhodes <david.rhodes@cirrus.com>
0008 
0009 #include <linux/acpi.h>
0010 #include <linux/delay.h>
0011 #include <linux/err.h>
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/moduleparam.h>
0016 #include <linux/of_device.h>
0017 #include <linux/pm_runtime.h>
0018 #include <linux/property.h>
0019 #include <sound/initval.h>
0020 #include <sound/pcm.h>
0021 #include <sound/pcm_params.h>
0022 #include <sound/soc.h>
0023 #include <sound/soc-dapm.h>
0024 #include <sound/tlv.h>
0025 
0026 #include "cs35l41.h"
0027 
0028 static const char * const cs35l41_supplies[CS35L41_NUM_SUPPLIES] = {
0029     "VA",
0030     "VP",
0031 };
0032 
0033 struct cs35l41_pll_sysclk_config {
0034     int freq;
0035     int clk_cfg;
0036 };
0037 
0038 static const struct cs35l41_pll_sysclk_config cs35l41_pll_sysclk[] = {
0039     { 32768,    0x00 },
0040     { 8000,     0x01 },
0041     { 11025,    0x02 },
0042     { 12000,    0x03 },
0043     { 16000,    0x04 },
0044     { 22050,    0x05 },
0045     { 24000,    0x06 },
0046     { 32000,    0x07 },
0047     { 44100,    0x08 },
0048     { 48000,    0x09 },
0049     { 88200,    0x0A },
0050     { 96000,    0x0B },
0051     { 128000,   0x0C },
0052     { 176400,   0x0D },
0053     { 192000,   0x0E },
0054     { 256000,   0x0F },
0055     { 352800,   0x10 },
0056     { 384000,   0x11 },
0057     { 512000,   0x12 },
0058     { 705600,   0x13 },
0059     { 750000,   0x14 },
0060     { 768000,   0x15 },
0061     { 1000000,  0x16 },
0062     { 1024000,  0x17 },
0063     { 1200000,  0x18 },
0064     { 1411200,  0x19 },
0065     { 1500000,  0x1A },
0066     { 1536000,  0x1B },
0067     { 2000000,  0x1C },
0068     { 2048000,  0x1D },
0069     { 2400000,  0x1E },
0070     { 2822400,  0x1F },
0071     { 3000000,  0x20 },
0072     { 3072000,  0x21 },
0073     { 3200000,  0x22 },
0074     { 4000000,  0x23 },
0075     { 4096000,  0x24 },
0076     { 4800000,  0x25 },
0077     { 5644800,  0x26 },
0078     { 6000000,  0x27 },
0079     { 6144000,  0x28 },
0080     { 6250000,  0x29 },
0081     { 6400000,  0x2A },
0082     { 6500000,  0x2B },
0083     { 6750000,  0x2C },
0084     { 7526400,  0x2D },
0085     { 8000000,  0x2E },
0086     { 8192000,  0x2F },
0087     { 9600000,  0x30 },
0088     { 11289600, 0x31 },
0089     { 12000000, 0x32 },
0090     { 12288000, 0x33 },
0091     { 12500000, 0x34 },
0092     { 12800000, 0x35 },
0093     { 13000000, 0x36 },
0094     { 13500000, 0x37 },
0095     { 19200000, 0x38 },
0096     { 22579200, 0x39 },
0097     { 24000000, 0x3A },
0098     { 24576000, 0x3B },
0099     { 25000000, 0x3C },
0100     { 25600000, 0x3D },
0101     { 26000000, 0x3E },
0102     { 27000000, 0x3F },
0103 };
0104 
0105 struct cs35l41_fs_mon_config {
0106     int freq;
0107     unsigned int fs1;
0108     unsigned int fs2;
0109 };
0110 
0111 static const struct cs35l41_fs_mon_config cs35l41_fs_mon[] = {
0112     { 32768,    2254,   3754 },
0113     { 8000,     9220,   15364 },
0114     { 11025,    6148,   10244 },
0115     { 12000,    6148,   10244 },
0116     { 16000,    4612,   7684 },
0117     { 22050,    3076,   5124 },
0118     { 24000,    3076,   5124 },
0119     { 32000,    2308,   3844 },
0120     { 44100,    1540,   2564 },
0121     { 48000,    1540,   2564 },
0122     { 88200,    772,    1284 },
0123     { 96000,    772,    1284 },
0124     { 128000,   580,    964 },
0125     { 176400,   388,    644 },
0126     { 192000,   388,    644 },
0127     { 256000,   292,    484 },
0128     { 352800,   196,    324 },
0129     { 384000,   196,    324 },
0130     { 512000,   148,    244 },
0131     { 705600,   100,    164 },
0132     { 750000,   100,    164 },
0133     { 768000,   100,    164 },
0134     { 1000000,  76, 124 },
0135     { 1024000,  76, 124 },
0136     { 1200000,  64, 104 },
0137     { 1411200,  52, 84 },
0138     { 1500000,  52, 84 },
0139     { 1536000,  52, 84 },
0140     { 2000000,  40, 64 },
0141     { 2048000,  40, 64 },
0142     { 2400000,  34, 54 },
0143     { 2822400,  28, 44 },
0144     { 3000000,  28, 44 },
0145     { 3072000,  28, 44 },
0146     { 3200000,  27, 42 },
0147     { 4000000,  22, 34 },
0148     { 4096000,  22, 34 },
0149     { 4800000,  19, 29 },
0150     { 5644800,  16, 24 },
0151     { 6000000,  16, 24 },
0152     { 6144000,  16, 24 },
0153 };
0154 
0155 static int cs35l41_get_fs_mon_config_index(int freq)
0156 {
0157     int i;
0158 
0159     for (i = 0; i < ARRAY_SIZE(cs35l41_fs_mon); i++) {
0160         if (cs35l41_fs_mon[i].freq == freq)
0161             return i;
0162     }
0163 
0164     return -EINVAL;
0165 }
0166 
0167 static const DECLARE_TLV_DB_RANGE(dig_vol_tlv,
0168         0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
0169         1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200));
0170 static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
0171 
0172 static const struct snd_kcontrol_new dre_ctrl =
0173     SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0);
0174 
0175 static const char * const cs35l41_pcm_sftramp_text[] =  {
0176     "Off", ".5ms", "1ms", "2ms", "4ms", "8ms", "15ms", "30ms"
0177 };
0178 
0179 static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
0180                 CS35L41_AMP_DIG_VOL_CTRL, 0,
0181                 cs35l41_pcm_sftramp_text);
0182 
0183 static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w,
0184                   struct snd_kcontrol *kcontrol, int event)
0185 {
0186     struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0187     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
0188     int ret;
0189 
0190     switch (event) {
0191     case SND_SOC_DAPM_PRE_PMU:
0192         if (cs35l41->dsp.cs_dsp.booted)
0193             return 0;
0194 
0195         return wm_adsp_early_event(w, kcontrol, event);
0196     case SND_SOC_DAPM_PRE_PMD:
0197         if (cs35l41->dsp.preloaded)
0198             return 0;
0199 
0200         if (cs35l41->dsp.cs_dsp.running) {
0201             ret = wm_adsp_event(w, kcontrol, event);
0202             if (ret)
0203                 return ret;
0204         }
0205 
0206         return wm_adsp_early_event(w, kcontrol, event);
0207     default:
0208         return 0;
0209     }
0210 }
0211 
0212 static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w,
0213                 struct snd_kcontrol *kcontrol, int event)
0214 {
0215     struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0216     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
0217     unsigned int fw_status;
0218     int ret;
0219 
0220     switch (event) {
0221     case SND_SOC_DAPM_POST_PMU:
0222         if (!cs35l41->dsp.cs_dsp.running)
0223             return wm_adsp_event(w, kcontrol, event);
0224 
0225         ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &fw_status);
0226         if (ret < 0) {
0227             dev_err(cs35l41->dev,
0228                 "Failed to read firmware status: %d\n", ret);
0229             return ret;
0230         }
0231 
0232         switch (fw_status) {
0233         case CSPL_MBOX_STS_RUNNING:
0234         case CSPL_MBOX_STS_PAUSED:
0235             break;
0236         default:
0237             dev_err(cs35l41->dev, "Firmware status is invalid: %u\n",
0238                 fw_status);
0239             return -EINVAL;
0240         }
0241 
0242         return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
0243                          CSPL_MBOX_CMD_RESUME);
0244     case SND_SOC_DAPM_PRE_PMD:
0245         return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap,
0246                          CSPL_MBOX_CMD_PAUSE);
0247     default:
0248         return 0;
0249     }
0250 }
0251 
0252 static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
0253 static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
0254 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum,
0255                   CS35L41_DAC_PCM1_SRC,
0256                   0, CS35L41_ASP_SOURCE_MASK,
0257                   cs35l41_pcm_source_texts,
0258                   cs35l41_pcm_source_values);
0259 
0260 static const struct snd_kcontrol_new pcm_source_mux =
0261     SOC_DAPM_ENUM("PCM Source", cs35l41_pcm_source_enum);
0262 
0263 static const char * const cs35l41_tx_input_texts[] = {
0264     "Zero", "ASPRX1", "ASPRX2", "VMON", "IMON",
0265     "VPMON", "VBSTMON", "DSPTX1", "DSPTX2"
0266 };
0267 
0268 static const unsigned int cs35l41_tx_input_values[] = {
0269     0x00, CS35L41_INPUT_SRC_ASPRX1, CS35L41_INPUT_SRC_ASPRX2,
0270     CS35L41_INPUT_SRC_VMON, CS35L41_INPUT_SRC_IMON, CS35L41_INPUT_SRC_VPMON,
0271     CS35L41_INPUT_SRC_VBSTMON, CS35L41_INPUT_DSP_TX1, CS35L41_INPUT_DSP_TX2
0272 };
0273 
0274 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx1_enum,
0275                   CS35L41_ASP_TX1_SRC,
0276                   0, CS35L41_ASP_SOURCE_MASK,
0277                   cs35l41_tx_input_texts,
0278                   cs35l41_tx_input_values);
0279 
0280 static const struct snd_kcontrol_new asp_tx1_mux =
0281     SOC_DAPM_ENUM("ASPTX1 SRC", cs35l41_asptx1_enum);
0282 
0283 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx2_enum,
0284                   CS35L41_ASP_TX2_SRC,
0285                   0, CS35L41_ASP_SOURCE_MASK,
0286                   cs35l41_tx_input_texts,
0287                   cs35l41_tx_input_values);
0288 
0289 static const struct snd_kcontrol_new asp_tx2_mux =
0290     SOC_DAPM_ENUM("ASPTX2 SRC", cs35l41_asptx2_enum);
0291 
0292 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx3_enum,
0293                   CS35L41_ASP_TX3_SRC,
0294                   0, CS35L41_ASP_SOURCE_MASK,
0295                   cs35l41_tx_input_texts,
0296                   cs35l41_tx_input_values);
0297 
0298 static const struct snd_kcontrol_new asp_tx3_mux =
0299     SOC_DAPM_ENUM("ASPTX3 SRC", cs35l41_asptx3_enum);
0300 
0301 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_asptx4_enum,
0302                   CS35L41_ASP_TX4_SRC,
0303                   0, CS35L41_ASP_SOURCE_MASK,
0304                   cs35l41_tx_input_texts,
0305                   cs35l41_tx_input_values);
0306 
0307 static const struct snd_kcontrol_new asp_tx4_mux =
0308     SOC_DAPM_ENUM("ASPTX4 SRC", cs35l41_asptx4_enum);
0309 
0310 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx1_enum,
0311                   CS35L41_DSP1_RX1_SRC,
0312                   0, CS35L41_ASP_SOURCE_MASK,
0313                   cs35l41_tx_input_texts,
0314                   cs35l41_tx_input_values);
0315 
0316 static const struct snd_kcontrol_new dsp_rx1_mux =
0317     SOC_DAPM_ENUM("DSPRX1 SRC", cs35l41_dsprx1_enum);
0318 
0319 static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_dsprx2_enum,
0320                   CS35L41_DSP1_RX2_SRC,
0321                   0, CS35L41_ASP_SOURCE_MASK,
0322                   cs35l41_tx_input_texts,
0323                   cs35l41_tx_input_values);
0324 
0325 static const struct snd_kcontrol_new dsp_rx2_mux =
0326     SOC_DAPM_ENUM("DSPRX2 SRC", cs35l41_dsprx2_enum);
0327 
0328 static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
0329     SOC_SINGLE_SX_TLV("Digital PCM Volume", CS35L41_AMP_DIG_VOL_CTRL,
0330               3, 0x4CF, 0x391, dig_vol_tlv),
0331     SOC_SINGLE_TLV("Analog PCM Volume", CS35L41_AMP_GAIN_CTRL, 5, 0x14, 0,
0332                amp_gain_tlv),
0333     SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
0334     SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0),
0335     SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0),
0336     SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0),
0337     SOC_SINGLE("Aux Noise Gate CH1 Switch",
0338            CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0),
0339     SOC_SINGLE("Aux Noise Gate CH1 Entry Delay",
0340            CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0),
0341     SOC_SINGLE("Aux Noise Gate CH1 Threshold",
0342            CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0),
0343     SOC_SINGLE("Aux Noise Gate CH2 Entry Delay",
0344            CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0),
0345     SOC_SINGLE("Aux Noise Gate CH2 Switch",
0346            CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0),
0347     SOC_SINGLE("Aux Noise Gate CH2 Threshold",
0348            CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0),
0349     SOC_SINGLE("SCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0),
0350     SOC_SINGLE("LRCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0),
0351     SOC_SINGLE("Invert Class D Switch", CS35L41_AMP_DIG_VOL_CTRL,
0352            CS35L41_AMP_INV_PCM_SHIFT, 1, 0),
0353     SOC_SINGLE("Amp Gain ZC Switch", CS35L41_AMP_GAIN_CTRL,
0354            CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0),
0355     WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
0356     WM_ADSP_FW_CONTROL("DSP1", 0),
0357 };
0358 
0359 static irqreturn_t cs35l41_irq(int irq, void *data)
0360 {
0361     struct cs35l41_private *cs35l41 = data;
0362     unsigned int status[4] = { 0, 0, 0, 0 };
0363     unsigned int masks[4] = { 0, 0, 0, 0 };
0364     int ret = IRQ_NONE;
0365     unsigned int i;
0366 
0367     pm_runtime_get_sync(cs35l41->dev);
0368 
0369     for (i = 0; i < ARRAY_SIZE(status); i++) {
0370         regmap_read(cs35l41->regmap,
0371                 CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE),
0372                 &status[i]);
0373         regmap_read(cs35l41->regmap,
0374                 CS35L41_IRQ1_MASK1 + (i * CS35L41_REGSTRIDE),
0375                 &masks[i]);
0376     }
0377 
0378     /* Check to see if unmasked bits are active */
0379     if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) &&
0380         !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
0381         goto done;
0382 
0383     if (status[3] & CS35L41_OTP_BOOT_DONE) {
0384         regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4,
0385                    CS35L41_OTP_BOOT_DONE, CS35L41_OTP_BOOT_DONE);
0386     }
0387 
0388     /*
0389      * The following interrupts require a
0390      * protection release cycle to get the
0391      * speaker out of Safe-Mode.
0392      */
0393     if (status[0] & CS35L41_AMP_SHORT_ERR) {
0394         dev_crit_ratelimited(cs35l41->dev, "Amp short error\n");
0395         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0396                  CS35L41_AMP_SHORT_ERR);
0397         regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
0398         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0399                    CS35L41_AMP_SHORT_ERR_RLS,
0400                    CS35L41_AMP_SHORT_ERR_RLS);
0401         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0402                    CS35L41_AMP_SHORT_ERR_RLS, 0);
0403         ret = IRQ_HANDLED;
0404     }
0405 
0406     if (status[0] & CS35L41_TEMP_WARN) {
0407         dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n");
0408         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0409                  CS35L41_TEMP_WARN);
0410         regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
0411         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0412                    CS35L41_TEMP_WARN_ERR_RLS,
0413                    CS35L41_TEMP_WARN_ERR_RLS);
0414         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0415                    CS35L41_TEMP_WARN_ERR_RLS, 0);
0416         ret = IRQ_HANDLED;
0417     }
0418 
0419     if (status[0] & CS35L41_TEMP_ERR) {
0420         dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n");
0421         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0422                  CS35L41_TEMP_ERR);
0423         regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
0424         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0425                    CS35L41_TEMP_ERR_RLS,
0426                    CS35L41_TEMP_ERR_RLS);
0427         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0428                    CS35L41_TEMP_ERR_RLS, 0);
0429         ret = IRQ_HANDLED;
0430     }
0431 
0432     if (status[0] & CS35L41_BST_OVP_ERR) {
0433         dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n");
0434         regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
0435                    CS35L41_BST_EN_MASK, 0);
0436         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0437                  CS35L41_BST_OVP_ERR);
0438         regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
0439         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0440                    CS35L41_BST_OVP_ERR_RLS,
0441                    CS35L41_BST_OVP_ERR_RLS);
0442         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0443                    CS35L41_BST_OVP_ERR_RLS, 0);
0444         regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
0445                    CS35L41_BST_EN_MASK,
0446                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
0447         ret = IRQ_HANDLED;
0448     }
0449 
0450     if (status[0] & CS35L41_BST_DCM_UVP_ERR) {
0451         dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n");
0452         regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
0453                    CS35L41_BST_EN_MASK, 0);
0454         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0455                  CS35L41_BST_DCM_UVP_ERR);
0456         regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
0457         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0458                    CS35L41_BST_UVP_ERR_RLS,
0459                    CS35L41_BST_UVP_ERR_RLS);
0460         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0461                    CS35L41_BST_UVP_ERR_RLS, 0);
0462         regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
0463                    CS35L41_BST_EN_MASK,
0464                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
0465         ret = IRQ_HANDLED;
0466     }
0467 
0468     if (status[0] & CS35L41_BST_SHORT_ERR) {
0469         dev_crit_ratelimited(cs35l41->dev, "LBST error: powering off!\n");
0470         regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
0471                    CS35L41_BST_EN_MASK, 0);
0472         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0473                  CS35L41_BST_SHORT_ERR);
0474         regmap_write(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN, 0);
0475         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0476                    CS35L41_BST_SHORT_ERR_RLS,
0477                    CS35L41_BST_SHORT_ERR_RLS);
0478         regmap_update_bits(cs35l41->regmap, CS35L41_PROTECT_REL_ERR_IGN,
0479                    CS35L41_BST_SHORT_ERR_RLS, 0);
0480         regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2,
0481                    CS35L41_BST_EN_MASK,
0482                    CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
0483         ret = IRQ_HANDLED;
0484     }
0485 
0486 done:
0487     pm_runtime_mark_last_busy(cs35l41->dev);
0488     pm_runtime_put_autosuspend(cs35l41->dev);
0489 
0490     return ret;
0491 }
0492 
0493 static const struct reg_sequence cs35l41_pup_patch[] = {
0494     { CS35L41_TEST_KEY_CTL, 0x00000055 },
0495     { CS35L41_TEST_KEY_CTL, 0x000000AA },
0496     { 0x00002084, 0x002F1AA0 },
0497     { CS35L41_TEST_KEY_CTL, 0x000000CC },
0498     { CS35L41_TEST_KEY_CTL, 0x00000033 },
0499 };
0500 
0501 static const struct reg_sequence cs35l41_pdn_patch[] = {
0502     { CS35L41_TEST_KEY_CTL, 0x00000055 },
0503     { CS35L41_TEST_KEY_CTL, 0x000000AA },
0504     { 0x00002084, 0x002F1AA3 },
0505     { CS35L41_TEST_KEY_CTL, 0x000000CC },
0506     { CS35L41_TEST_KEY_CTL, 0x00000033 },
0507 };
0508 
0509 static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
0510                   struct snd_kcontrol *kcontrol, int event)
0511 {
0512     struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0513     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
0514     unsigned int val;
0515     int ret = 0;
0516 
0517     switch (event) {
0518     case SND_SOC_DAPM_PRE_PMU:
0519         regmap_multi_reg_write_bypassed(cs35l41->regmap,
0520                         cs35l41_pup_patch,
0521                         ARRAY_SIZE(cs35l41_pup_patch));
0522 
0523         cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1);
0524         break;
0525     case SND_SOC_DAPM_POST_PMD:
0526         cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
0527 
0528         ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0529                            val, val &  CS35L41_PDN_DONE_MASK,
0530                            1000, 100000);
0531         if (ret)
0532             dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
0533 
0534         regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
0535                  CS35L41_PDN_DONE_MASK);
0536 
0537         regmap_multi_reg_write_bypassed(cs35l41->regmap,
0538                         cs35l41_pdn_patch,
0539                         ARRAY_SIZE(cs35l41_pdn_patch));
0540         break;
0541     default:
0542         dev_err(cs35l41->dev, "Invalid event = 0x%x\n", event);
0543         ret = -EINVAL;
0544     }
0545 
0546     return ret;
0547 }
0548 
0549 static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
0550     SND_SOC_DAPM_SPK("DSP1 Preload", NULL),
0551     SND_SOC_DAPM_SUPPLY_S("DSP1 Preloader", 100, SND_SOC_NOPM, 0, 0,
0552                   cs35l41_dsp_preload_ev,
0553                   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
0554     SND_SOC_DAPM_OUT_DRV_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0,
0555                    cs35l41_dsp_audio_ev,
0556                    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
0557 
0558     SND_SOC_DAPM_OUTPUT("SPK"),
0559 
0560     SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0, CS35L41_SP_ENABLES, 16, 0),
0561     SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 0, CS35L41_SP_ENABLES, 17, 0),
0562     SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0, CS35L41_SP_ENABLES, 0, 0),
0563     SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 0, CS35L41_SP_ENABLES, 1, 0),
0564     SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 0, CS35L41_SP_ENABLES, 2, 0),
0565     SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 0, CS35L41_SP_ENABLES, 3, 0),
0566 
0567     SND_SOC_DAPM_SIGGEN("VSENSE"),
0568     SND_SOC_DAPM_SIGGEN("ISENSE"),
0569     SND_SOC_DAPM_SIGGEN("VP"),
0570     SND_SOC_DAPM_SIGGEN("VBST"),
0571     SND_SOC_DAPM_SIGGEN("TEMP"),
0572 
0573     SND_SOC_DAPM_SUPPLY("VMON", CS35L41_PWR_CTRL2, 12, 0, NULL, 0),
0574     SND_SOC_DAPM_SUPPLY("IMON", CS35L41_PWR_CTRL2, 13, 0, NULL, 0),
0575     SND_SOC_DAPM_SUPPLY("VPMON", CS35L41_PWR_CTRL2, 8, 0, NULL, 0),
0576     SND_SOC_DAPM_SUPPLY("VBSTMON", CS35L41_PWR_CTRL2, 9, 0, NULL, 0),
0577     SND_SOC_DAPM_SUPPLY("TEMPMON", CS35L41_PWR_CTRL2, 10, 0, NULL, 0),
0578 
0579     SND_SOC_DAPM_ADC("VMON ADC", NULL, SND_SOC_NOPM, 0, 0),
0580     SND_SOC_DAPM_ADC("IMON ADC", NULL, SND_SOC_NOPM, 0, 0),
0581     SND_SOC_DAPM_ADC("VPMON ADC", NULL, SND_SOC_NOPM, 0, 0),
0582     SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, SND_SOC_NOPM, 0, 0),
0583     SND_SOC_DAPM_ADC("TEMPMON ADC", NULL, SND_SOC_NOPM, 0, 0),
0584 
0585     SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L41_PWR_CTRL3, 4, 0),
0586 
0587     SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
0588                    cs35l41_main_amp_event,
0589                    SND_SOC_DAPM_POST_PMD |  SND_SOC_DAPM_PRE_PMU),
0590 
0591     SND_SOC_DAPM_MUX("ASP TX1 Source", SND_SOC_NOPM, 0, 0, &asp_tx1_mux),
0592     SND_SOC_DAPM_MUX("ASP TX2 Source", SND_SOC_NOPM, 0, 0, &asp_tx2_mux),
0593     SND_SOC_DAPM_MUX("ASP TX3 Source", SND_SOC_NOPM, 0, 0, &asp_tx3_mux),
0594     SND_SOC_DAPM_MUX("ASP TX4 Source", SND_SOC_NOPM, 0, 0, &asp_tx4_mux),
0595     SND_SOC_DAPM_MUX("DSP RX1 Source", SND_SOC_NOPM, 0, 0, &dsp_rx1_mux),
0596     SND_SOC_DAPM_MUX("DSP RX2 Source", SND_SOC_NOPM, 0, 0, &dsp_rx2_mux),
0597     SND_SOC_DAPM_MUX("PCM Source", SND_SOC_NOPM, 0, 0, &pcm_source_mux),
0598     SND_SOC_DAPM_SWITCH("DRE", SND_SOC_NOPM, 0, 0, &dre_ctrl),
0599 };
0600 
0601 static const struct snd_soc_dapm_route cs35l41_audio_map[] = {
0602     {"DSP RX1 Source", "ASPRX1", "ASPRX1"},
0603     {"DSP RX1 Source", "ASPRX2", "ASPRX2"},
0604     {"DSP RX2 Source", "ASPRX1", "ASPRX1"},
0605     {"DSP RX2 Source", "ASPRX2", "ASPRX2"},
0606 
0607     {"DSP1", NULL, "DSP RX1 Source"},
0608     {"DSP1", NULL, "DSP RX2 Source"},
0609 
0610     {"ASP TX1 Source", "VMON", "VMON ADC"},
0611     {"ASP TX1 Source", "IMON", "IMON ADC"},
0612     {"ASP TX1 Source", "VPMON", "VPMON ADC"},
0613     {"ASP TX1 Source", "VBSTMON", "VBSTMON ADC"},
0614     {"ASP TX1 Source", "DSPTX1", "DSP1"},
0615     {"ASP TX1 Source", "DSPTX2", "DSP1"},
0616     {"ASP TX1 Source", "ASPRX1", "ASPRX1" },
0617     {"ASP TX1 Source", "ASPRX2", "ASPRX2" },
0618     {"ASP TX2 Source", "VMON", "VMON ADC"},
0619     {"ASP TX2 Source", "IMON", "IMON ADC"},
0620     {"ASP TX2 Source", "VPMON", "VPMON ADC"},
0621     {"ASP TX2 Source", "VBSTMON", "VBSTMON ADC"},
0622     {"ASP TX2 Source", "DSPTX1", "DSP1"},
0623     {"ASP TX2 Source", "DSPTX2", "DSP1"},
0624     {"ASP TX2 Source", "ASPRX1", "ASPRX1" },
0625     {"ASP TX2 Source", "ASPRX2", "ASPRX2" },
0626     {"ASP TX3 Source", "VMON", "VMON ADC"},
0627     {"ASP TX3 Source", "IMON", "IMON ADC"},
0628     {"ASP TX3 Source", "VPMON", "VPMON ADC"},
0629     {"ASP TX3 Source", "VBSTMON", "VBSTMON ADC"},
0630     {"ASP TX3 Source", "DSPTX1", "DSP1"},
0631     {"ASP TX3 Source", "DSPTX2", "DSP1"},
0632     {"ASP TX3 Source", "ASPRX1", "ASPRX1" },
0633     {"ASP TX3 Source", "ASPRX2", "ASPRX2" },
0634     {"ASP TX4 Source", "VMON", "VMON ADC"},
0635     {"ASP TX4 Source", "IMON", "IMON ADC"},
0636     {"ASP TX4 Source", "VPMON", "VPMON ADC"},
0637     {"ASP TX4 Source", "VBSTMON", "VBSTMON ADC"},
0638     {"ASP TX4 Source", "DSPTX1", "DSP1"},
0639     {"ASP TX4 Source", "DSPTX2", "DSP1"},
0640     {"ASP TX4 Source", "ASPRX1", "ASPRX1" },
0641     {"ASP TX4 Source", "ASPRX2", "ASPRX2" },
0642     {"ASPTX1", NULL, "ASP TX1 Source"},
0643     {"ASPTX2", NULL, "ASP TX2 Source"},
0644     {"ASPTX3", NULL, "ASP TX3 Source"},
0645     {"ASPTX4", NULL, "ASP TX4 Source"},
0646     {"AMP Capture", NULL, "ASPTX1"},
0647     {"AMP Capture", NULL, "ASPTX2"},
0648     {"AMP Capture", NULL, "ASPTX3"},
0649     {"AMP Capture", NULL, "ASPTX4"},
0650 
0651     {"DSP1", NULL, "VMON"},
0652     {"DSP1", NULL, "IMON"},
0653     {"DSP1", NULL, "VPMON"},
0654     {"DSP1", NULL, "VBSTMON"},
0655     {"DSP1", NULL, "TEMPMON"},
0656 
0657     {"VMON ADC", NULL, "VMON"},
0658     {"IMON ADC", NULL, "IMON"},
0659     {"VPMON ADC", NULL, "VPMON"},
0660     {"VBSTMON ADC", NULL, "VBSTMON"},
0661     {"TEMPMON ADC", NULL, "TEMPMON"},
0662 
0663     {"VMON ADC", NULL, "VSENSE"},
0664     {"IMON ADC", NULL, "ISENSE"},
0665     {"VPMON ADC", NULL, "VP"},
0666     {"VBSTMON ADC", NULL, "VBST"},
0667     {"TEMPMON ADC", NULL, "TEMP"},
0668 
0669     {"DSP1 Preload", NULL, "DSP1 Preloader"},
0670     {"DSP1", NULL, "DSP1 Preloader"},
0671 
0672     {"ASPRX1", NULL, "AMP Playback"},
0673     {"ASPRX2", NULL, "AMP Playback"},
0674     {"DRE", "Switch", "CLASS H"},
0675     {"Main AMP", NULL, "CLASS H"},
0676     {"Main AMP", NULL, "DRE"},
0677     {"SPK", NULL, "Main AMP"},
0678 
0679     {"PCM Source", "ASP", "ASPRX1"},
0680     {"PCM Source", "DSP", "DSP1"},
0681     {"CLASS H", NULL, "PCM Source"},
0682 };
0683 
0684 static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_n,
0685                    unsigned int *tx_slot, unsigned int rx_n, unsigned int *rx_slot)
0686 {
0687     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
0688 
0689     return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_n, tx_slot, rx_n, rx_slot);
0690 }
0691 
0692 static int cs35l41_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
0693 {
0694     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
0695     unsigned int daifmt = 0;
0696 
0697     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0698     case SND_SOC_DAIFMT_CBP_CFP:
0699         daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
0700         break;
0701     case SND_SOC_DAIFMT_CBC_CFC:
0702         break;
0703     default:
0704         dev_warn(cs35l41->dev, "Mixed provider/consumer mode unsupported\n");
0705         return -EINVAL;
0706     }
0707 
0708     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0709     case SND_SOC_DAIFMT_DSP_A:
0710         break;
0711     case SND_SOC_DAIFMT_I2S:
0712         daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
0713         break;
0714     default:
0715         dev_warn(cs35l41->dev, "Invalid or unsupported DAI format\n");
0716         return -EINVAL;
0717     }
0718 
0719     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0720     case SND_SOC_DAIFMT_NB_IF:
0721         daifmt |= CS35L41_LRCLK_INV_MASK;
0722         break;
0723     case SND_SOC_DAIFMT_IB_NF:
0724         daifmt |= CS35L41_SCLK_INV_MASK;
0725         break;
0726     case SND_SOC_DAIFMT_IB_IF:
0727         daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
0728         break;
0729     case SND_SOC_DAIFMT_NB_NF:
0730         break;
0731     default:
0732         dev_warn(cs35l41->dev, "Invalid DAI clock INV\n");
0733         return -EINVAL;
0734     }
0735 
0736     return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
0737                   CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
0738                   CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
0739                   CS35L41_SCLK_INV_MASK, daifmt);
0740 }
0741 
0742 struct cs35l41_global_fs_config {
0743     int rate;
0744     int fs_cfg;
0745 };
0746 
0747 static const struct cs35l41_global_fs_config cs35l41_fs_rates[] = {
0748     { 12000,    0x01 },
0749     { 24000,    0x02 },
0750     { 48000,    0x03 },
0751     { 96000,    0x04 },
0752     { 192000,   0x05 },
0753     { 11025,    0x09 },
0754     { 22050,    0x0A },
0755     { 44100,    0x0B },
0756     { 88200,    0x0C },
0757     { 176400,   0x0D },
0758     { 8000,     0x11 },
0759     { 16000,    0x12 },
0760     { 32000,    0x13 },
0761 };
0762 
0763 static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
0764                  struct snd_pcm_hw_params *params,
0765                  struct snd_soc_dai *dai)
0766 {
0767     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
0768     unsigned int rate = params_rate(params);
0769     u8 asp_wl;
0770     int i;
0771 
0772     for (i = 0; i < ARRAY_SIZE(cs35l41_fs_rates); i++) {
0773         if (rate == cs35l41_fs_rates[i].rate)
0774             break;
0775     }
0776 
0777     if (i >= ARRAY_SIZE(cs35l41_fs_rates)) {
0778         dev_err(cs35l41->dev, "Unsupported rate: %u\n", rate);
0779         return -EINVAL;
0780     }
0781 
0782     asp_wl = params_width(params);
0783 
0784     if (i < ARRAY_SIZE(cs35l41_fs_rates))
0785         regmap_update_bits(cs35l41->regmap, CS35L41_GLOBAL_CLK_CTRL,
0786                    CS35L41_GLOBAL_FS_MASK,
0787                    cs35l41_fs_rates[i].fs_cfg << CS35L41_GLOBAL_FS_SHIFT);
0788 
0789     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0790         regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
0791                    CS35L41_ASP_WIDTH_RX_MASK,
0792                    asp_wl << CS35L41_ASP_WIDTH_RX_SHIFT);
0793         regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
0794                    CS35L41_ASP_RX_WL_MASK,
0795                    asp_wl << CS35L41_ASP_RX_WL_SHIFT);
0796     } else {
0797         regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
0798                    CS35L41_ASP_WIDTH_TX_MASK,
0799                    asp_wl << CS35L41_ASP_WIDTH_TX_SHIFT);
0800         regmap_update_bits(cs35l41->regmap, CS35L41_SP_TX_WL,
0801                    CS35L41_ASP_TX_WL_MASK,
0802                    asp_wl << CS35L41_ASP_TX_WL_SHIFT);
0803     }
0804 
0805     return 0;
0806 }
0807 
0808 static int cs35l41_get_clk_config(int freq)
0809 {
0810     int i;
0811 
0812     for (i = 0; i < ARRAY_SIZE(cs35l41_pll_sysclk); i++) {
0813         if (cs35l41_pll_sysclk[i].freq == freq)
0814             return cs35l41_pll_sysclk[i].clk_cfg;
0815     }
0816 
0817     return -EINVAL;
0818 }
0819 
0820 static const unsigned int cs35l41_src_rates[] = {
0821     8000, 12000, 11025, 16000, 22050, 24000, 32000,
0822     44100, 48000, 88200, 96000, 176400, 192000
0823 };
0824 
0825 static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
0826     .count = ARRAY_SIZE(cs35l41_src_rates),
0827     .list = cs35l41_src_rates,
0828 };
0829 
0830 static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
0831                    struct snd_soc_dai *dai)
0832 {
0833     if (substream->runtime)
0834         return snd_pcm_hw_constraint_list(substream->runtime, 0,
0835                           SNDRV_PCM_HW_PARAM_RATE,
0836                           &cs35l41_constraints);
0837     return 0;
0838 }
0839 
0840 static int cs35l41_component_set_sysclk(struct snd_soc_component *component,
0841                     int clk_id, int source,
0842                     unsigned int freq, int dir)
0843 {
0844     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
0845     int extclk_cfg, clksrc;
0846 
0847     switch (clk_id) {
0848     case CS35L41_CLKID_SCLK:
0849         clksrc = CS35L41_PLLSRC_SCLK;
0850         break;
0851     case CS35L41_CLKID_LRCLK:
0852         clksrc = CS35L41_PLLSRC_LRCLK;
0853         break;
0854     case CS35L41_CLKID_MCLK:
0855         clksrc = CS35L41_PLLSRC_MCLK;
0856         break;
0857     default:
0858         dev_err(cs35l41->dev, "Invalid CLK Config\n");
0859         return -EINVAL;
0860     }
0861 
0862     extclk_cfg = cs35l41_get_clk_config(freq);
0863 
0864     if (extclk_cfg < 0) {
0865         dev_err(cs35l41->dev, "Invalid CLK Config: %d, freq: %u\n",
0866             extclk_cfg, freq);
0867         return -EINVAL;
0868     }
0869 
0870     regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
0871                CS35L41_PLL_OPENLOOP_MASK,
0872                1 << CS35L41_PLL_OPENLOOP_SHIFT);
0873     regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
0874                CS35L41_REFCLK_FREQ_MASK,
0875                extclk_cfg << CS35L41_REFCLK_FREQ_SHIFT);
0876     regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
0877                CS35L41_PLL_CLK_EN_MASK,
0878                0 << CS35L41_PLL_CLK_EN_SHIFT);
0879     regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
0880                CS35L41_PLL_CLK_SEL_MASK, clksrc);
0881     regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
0882                CS35L41_PLL_OPENLOOP_MASK,
0883                0 << CS35L41_PLL_OPENLOOP_SHIFT);
0884     regmap_update_bits(cs35l41->regmap, CS35L41_PLL_CLK_CTRL,
0885                CS35L41_PLL_CLK_EN_MASK,
0886                1 << CS35L41_PLL_CLK_EN_SHIFT);
0887 
0888     return 0;
0889 }
0890 
0891 static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,
0892                   int clk_id, unsigned int freq, int dir)
0893 {
0894     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
0895     unsigned int fs1_val;
0896     unsigned int fs2_val;
0897     unsigned int val;
0898     int fsindex;
0899 
0900     fsindex = cs35l41_get_fs_mon_config_index(freq);
0901     if (fsindex < 0) {
0902         dev_err(cs35l41->dev, "Invalid CLK Config freq: %u\n", freq);
0903         return -EINVAL;
0904     }
0905 
0906     dev_dbg(cs35l41->dev, "Set DAI sysclk %d\n", freq);
0907 
0908     if (freq <= 6144000) {
0909         /* Use the lookup table */
0910         fs1_val = cs35l41_fs_mon[fsindex].fs1;
0911         fs2_val = cs35l41_fs_mon[fsindex].fs2;
0912     } else {
0913         /* Use hard-coded values */
0914         fs1_val = 0x10;
0915         fs2_val = 0x24;
0916     }
0917 
0918     val = fs1_val;
0919     val |= (fs2_val << CS35L41_FS2_WINDOW_SHIFT) & CS35L41_FS2_WINDOW_MASK;
0920     regmap_write(cs35l41->regmap, CS35L41_TST_FS_MON0, val);
0921 
0922     return 0;
0923 }
0924 
0925 static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
0926 {
0927     struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
0928     int ret;
0929 
0930     if (!hw_cfg->valid)
0931         return -EINVAL;
0932 
0933     if (hw_cfg->bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH)
0934         return -EINVAL;
0935 
0936     /* Required */
0937     ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg);
0938     if (ret)
0939         return ret;
0940 
0941     /* Optional */
0942     if (hw_cfg->dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && hw_cfg->dout_hiz >= 0)
0943         regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, CS35L41_ASP_DOUT_HIZ_MASK,
0944                    hw_cfg->dout_hiz);
0945 
0946     return 0;
0947 }
0948 
0949 static const struct snd_soc_dapm_route cs35l41_ext_bst_routes[] = {
0950     {"Main AMP", NULL, "VSPK"},
0951 };
0952 
0953 static const struct snd_soc_dapm_widget cs35l41_ext_bst_widget[] = {
0954     SND_SOC_DAPM_SUPPLY("VSPK", CS35L41_GPIO1_CTRL1, CS35L41_GPIO_LVL_SHIFT, 0, NULL, 0),
0955 };
0956 
0957 static int cs35l41_component_probe(struct snd_soc_component *component)
0958 {
0959     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
0960     struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0961     int ret;
0962 
0963     if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) {
0964         ret = snd_soc_dapm_new_controls(dapm, cs35l41_ext_bst_widget,
0965                         ARRAY_SIZE(cs35l41_ext_bst_widget));
0966         if (ret)
0967             return ret;
0968 
0969         ret = snd_soc_dapm_add_routes(dapm, cs35l41_ext_bst_routes,
0970                           ARRAY_SIZE(cs35l41_ext_bst_routes));
0971         if (ret)
0972             return ret;
0973     }
0974 
0975     return wm_adsp2_component_probe(&cs35l41->dsp, component);
0976 }
0977 
0978 static void cs35l41_component_remove(struct snd_soc_component *component)
0979 {
0980     struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
0981 
0982     wm_adsp2_component_remove(&cs35l41->dsp, component);
0983 }
0984 
0985 static const struct snd_soc_dai_ops cs35l41_ops = {
0986     .startup = cs35l41_pcm_startup,
0987     .set_fmt = cs35l41_set_dai_fmt,
0988     .hw_params = cs35l41_pcm_hw_params,
0989     .set_sysclk = cs35l41_dai_set_sysclk,
0990     .set_channel_map = cs35l41_set_channel_map,
0991 };
0992 
0993 static struct snd_soc_dai_driver cs35l41_dai[] = {
0994     {
0995         .name = "cs35l41-pcm",
0996         .id = 0,
0997         .playback = {
0998             .stream_name = "AMP Playback",
0999             .channels_min = 1,
1000             .channels_max = 2,
1001             .rates = SNDRV_PCM_RATE_KNOT,
1002             .formats = CS35L41_RX_FORMATS,
1003         },
1004         .capture = {
1005             .stream_name = "AMP Capture",
1006             .channels_min = 1,
1007             .channels_max = 4,
1008             .rates = SNDRV_PCM_RATE_KNOT,
1009             .formats = CS35L41_TX_FORMATS,
1010         },
1011         .ops = &cs35l41_ops,
1012         .symmetric_rate = 1,
1013     },
1014 };
1015 
1016 static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
1017     .name = "cs35l41-codec",
1018     .probe = cs35l41_component_probe,
1019     .remove = cs35l41_component_remove,
1020 
1021     .dapm_widgets = cs35l41_dapm_widgets,
1022     .num_dapm_widgets = ARRAY_SIZE(cs35l41_dapm_widgets),
1023     .dapm_routes = cs35l41_audio_map,
1024     .num_dapm_routes = ARRAY_SIZE(cs35l41_audio_map),
1025 
1026     .controls = cs35l41_aud_controls,
1027     .num_controls = ARRAY_SIZE(cs35l41_aud_controls),
1028     .set_sysclk = cs35l41_component_set_sysclk,
1029 
1030     .endianness = 1,
1031 };
1032 
1033 static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cfg)
1034 {
1035     struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1;
1036     struct cs35l41_gpio_cfg *gpio2 = &hw_cfg->gpio2;
1037     unsigned int val;
1038     int ret;
1039 
1040     ret = device_property_read_u32(dev, "cirrus,boost-type", &val);
1041     if (ret >= 0)
1042         hw_cfg->bst_type = val;
1043 
1044     ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
1045     if (ret >= 0)
1046         hw_cfg->bst_ipk = val;
1047     else
1048         hw_cfg->bst_ipk = -1;
1049 
1050     ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
1051     if (ret >= 0)
1052         hw_cfg->bst_ind = val;
1053     else
1054         hw_cfg->bst_ind = -1;
1055 
1056     ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
1057     if (ret >= 0)
1058         hw_cfg->bst_cap = val;
1059     else
1060         hw_cfg->bst_cap = -1;
1061 
1062     ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
1063     if (ret >= 0)
1064         hw_cfg->dout_hiz = val;
1065     else
1066         hw_cfg->dout_hiz = -1;
1067 
1068     /* GPIO1 Pin Config */
1069     gpio1->pol_inv = device_property_read_bool(dev, "cirrus,gpio1-polarity-invert");
1070     gpio1->out_en = device_property_read_bool(dev, "cirrus,gpio1-output-enable");
1071     ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", &val);
1072     if (ret >= 0) {
1073         gpio1->func = val;
1074         gpio1->valid = true;
1075     }
1076 
1077     /* GPIO2 Pin Config */
1078     gpio2->pol_inv = device_property_read_bool(dev, "cirrus,gpio2-polarity-invert");
1079     gpio2->out_en = device_property_read_bool(dev, "cirrus,gpio2-output-enable");
1080     ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", &val);
1081     if (ret >= 0) {
1082         gpio2->func = val;
1083         gpio2->valid = true;
1084     }
1085 
1086     hw_cfg->valid = true;
1087 
1088     return 0;
1089 }
1090 
1091 static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
1092 {
1093     struct wm_adsp *dsp;
1094     int ret;
1095 
1096     dsp = &cs35l41->dsp;
1097     dsp->part = "cs35l41";
1098     dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */
1099     dsp->toggle_preload = true;
1100 
1101     cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, &dsp->cs_dsp);
1102 
1103     ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap);
1104     if (ret < 0)
1105         return ret;
1106 
1107     ret = wm_halo_init(dsp);
1108     if (ret) {
1109         dev_err(cs35l41->dev, "wm_halo_init failed: %d\n", ret);
1110         return ret;
1111     }
1112 
1113     ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX5_SRC,
1114                CS35L41_INPUT_SRC_VPMON);
1115     if (ret < 0) {
1116         dev_err(cs35l41->dev, "Write INPUT_SRC_VPMON failed: %d\n", ret);
1117         goto err_dsp;
1118     }
1119     ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX6_SRC,
1120                CS35L41_INPUT_SRC_CLASSH);
1121     if (ret < 0) {
1122         dev_err(cs35l41->dev, "Write INPUT_SRC_CLASSH failed: %d\n", ret);
1123         goto err_dsp;
1124     }
1125     ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX7_SRC,
1126                CS35L41_INPUT_SRC_TEMPMON);
1127     if (ret < 0) {
1128         dev_err(cs35l41->dev, "Write INPUT_SRC_TEMPMON failed: %d\n", ret);
1129         goto err_dsp;
1130     }
1131     ret = regmap_write(cs35l41->regmap, CS35L41_DSP1_RX8_SRC,
1132                CS35L41_INPUT_SRC_RSVD);
1133     if (ret < 0) {
1134         dev_err(cs35l41->dev, "Write INPUT_SRC_RSVD failed: %d\n", ret);
1135         goto err_dsp;
1136     }
1137 
1138     return 0;
1139 
1140 err_dsp:
1141     wm_adsp2_remove(dsp);
1142 
1143     return ret;
1144 }
1145 
1146 static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41)
1147 {
1148     acpi_handle handle = ACPI_HANDLE(cs35l41->dev);
1149     const char *sub;
1150 
1151     /* If there is no ACPI_HANDLE, there is no ACPI for this system, return 0 */
1152     if (!handle)
1153         return 0;
1154 
1155     sub = acpi_get_subsystem_id(handle);
1156     if (IS_ERR(sub)) {
1157         /* If bad ACPI, return 0 and fallback to legacy firmware path, otherwise fail */
1158         if (PTR_ERR(sub) == -ENODATA)
1159             return 0;
1160         else
1161             return PTR_ERR(sub);
1162     }
1163 
1164     cs35l41->dsp.system_name = sub;
1165     dev_dbg(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name);
1166 
1167     return 0;
1168 }
1169 
1170 int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg)
1171 {
1172     u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
1173     int irq_pol = 0;
1174     int ret;
1175 
1176     if (hw_cfg) {
1177         cs35l41->hw_cfg = *hw_cfg;
1178     } else {
1179         ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->hw_cfg);
1180         if (ret != 0)
1181             return ret;
1182     }
1183 
1184     for (i = 0; i < CS35L41_NUM_SUPPLIES; i++)
1185         cs35l41->supplies[i].supply = cs35l41_supplies[i];
1186 
1187     ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
1188                       cs35l41->supplies);
1189     if (ret != 0) {
1190         dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
1191         return ret;
1192     }
1193 
1194     ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1195     if (ret != 0) {
1196         dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
1197         return ret;
1198     }
1199 
1200     /* returning NULL can be an option if in stereo mode */
1201     cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
1202                               GPIOD_OUT_LOW);
1203     if (IS_ERR(cs35l41->reset_gpio)) {
1204         ret = PTR_ERR(cs35l41->reset_gpio);
1205         cs35l41->reset_gpio = NULL;
1206         if (ret == -EBUSY) {
1207             dev_info(cs35l41->dev,
1208                  "Reset line busy, assuming shared reset\n");
1209         } else {
1210             dev_err(cs35l41->dev,
1211                 "Failed to get reset GPIO: %d\n", ret);
1212             goto err;
1213         }
1214     }
1215     if (cs35l41->reset_gpio) {
1216         /* satisfy minimum reset pulse width spec */
1217         usleep_range(2000, 2100);
1218         gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
1219     }
1220 
1221     usleep_range(2000, 2100);
1222 
1223     ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4,
1224                        int_status, int_status & CS35L41_OTP_BOOT_DONE,
1225                        1000, 100000);
1226     if (ret) {
1227         dev_err(cs35l41->dev,
1228             "Failed waiting for OTP_BOOT_DONE: %d\n", ret);
1229         goto err;
1230     }
1231 
1232     regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_status);
1233     if (int_status & CS35L41_OTP_BOOT_ERR) {
1234         dev_err(cs35l41->dev, "OTP Boot error\n");
1235         ret = -EINVAL;
1236         goto err;
1237     }
1238 
1239     ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
1240     if (ret < 0) {
1241         dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
1242         goto err;
1243     }
1244 
1245     ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
1246     if (ret < 0) {
1247         dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
1248         goto err;
1249     }
1250 
1251     mtl_revid = reg_revid & CS35L41_MTLREVID_MASK;
1252 
1253     /* CS35L41 will have even MTLREVID
1254      * CS35L41R will have odd MTLREVID
1255      */
1256     chipid_match = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID;
1257     if (regid != chipid_match) {
1258         dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n",
1259             regid, chipid_match);
1260         ret = -ENODEV;
1261         goto err;
1262     }
1263 
1264     cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
1265 
1266     ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid);
1267     if (ret)
1268         goto err;
1269 
1270     ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap);
1271     if (ret < 0) {
1272         dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
1273         goto err;
1274     }
1275 
1276     cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
1277 
1278     irq_pol = cs35l41_gpio_config(cs35l41->regmap, &cs35l41->hw_cfg);
1279 
1280     /* Set interrupt masks for critical errors */
1281     regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
1282              CS35L41_INT1_MASK_DEFAULT);
1283 
1284     ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq,
1285                     IRQF_ONESHOT | IRQF_SHARED | irq_pol,
1286                     "cs35l41", cs35l41);
1287     if (ret != 0) {
1288         dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
1289         goto err;
1290     }
1291 
1292     ret = cs35l41_set_pdata(cs35l41);
1293     if (ret < 0) {
1294         dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
1295         goto err;
1296     }
1297 
1298     ret = cs35l41_acpi_get_name(cs35l41);
1299     if (ret < 0)
1300         goto err;
1301 
1302     ret = cs35l41_dsp_init(cs35l41);
1303     if (ret < 0)
1304         goto err;
1305 
1306     pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);
1307     pm_runtime_use_autosuspend(cs35l41->dev);
1308     pm_runtime_mark_last_busy(cs35l41->dev);
1309     pm_runtime_set_active(cs35l41->dev);
1310     pm_runtime_get_noresume(cs35l41->dev);
1311     pm_runtime_enable(cs35l41->dev);
1312 
1313     ret = devm_snd_soc_register_component(cs35l41->dev,
1314                           &soc_component_dev_cs35l41,
1315                           cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
1316     if (ret < 0) {
1317         dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
1318         goto err_pm;
1319     }
1320 
1321     pm_runtime_put_autosuspend(cs35l41->dev);
1322 
1323     dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n",
1324          regid, reg_revid);
1325 
1326     return 0;
1327 
1328 err_pm:
1329     pm_runtime_disable(cs35l41->dev);
1330     pm_runtime_put_noidle(cs35l41->dev);
1331 
1332     wm_adsp2_remove(&cs35l41->dsp);
1333 err:
1334     cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
1335     regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1336     gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1337 
1338     return ret;
1339 }
1340 EXPORT_SYMBOL_GPL(cs35l41_probe);
1341 
1342 void cs35l41_remove(struct cs35l41_private *cs35l41)
1343 {
1344     pm_runtime_get_sync(cs35l41->dev);
1345     pm_runtime_disable(cs35l41->dev);
1346 
1347     regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
1348     kfree(cs35l41->dsp.system_name);
1349     wm_adsp2_remove(&cs35l41->dsp);
1350     cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
1351 
1352     pm_runtime_put_noidle(cs35l41->dev);
1353 
1354     regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
1355     gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
1356 }
1357 EXPORT_SYMBOL_GPL(cs35l41_remove);
1358 
1359 static int __maybe_unused cs35l41_runtime_suspend(struct device *dev)
1360 {
1361     struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1362 
1363     dev_dbg(cs35l41->dev, "Runtime suspend\n");
1364 
1365     if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running)
1366         return 0;
1367 
1368     cs35l41_enter_hibernate(dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type);
1369 
1370     regcache_cache_only(cs35l41->regmap, true);
1371     regcache_mark_dirty(cs35l41->regmap);
1372 
1373     return 0;
1374 }
1375 
1376 static int __maybe_unused cs35l41_runtime_resume(struct device *dev)
1377 {
1378     struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1379     int ret;
1380 
1381     dev_dbg(cs35l41->dev, "Runtime resume\n");
1382 
1383     if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running)
1384         return 0;
1385 
1386     regcache_cache_only(cs35l41->regmap, false);
1387 
1388     ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap);
1389     if (ret)
1390         return ret;
1391 
1392     /* Test key needs to be unlocked to allow the OTP settings to re-apply */
1393     cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap);
1394     ret = regcache_sync(cs35l41->regmap);
1395     cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
1396     if (ret) {
1397         dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret);
1398         return ret;
1399     }
1400     cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg);
1401 
1402     return 0;
1403 }
1404 
1405 static int __maybe_unused cs35l41_sys_suspend(struct device *dev)
1406 {
1407     struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1408 
1409     dev_dbg(cs35l41->dev, "System suspend, disabling IRQ\n");
1410     disable_irq(cs35l41->irq);
1411 
1412     return 0;
1413 }
1414 
1415 static int __maybe_unused cs35l41_sys_suspend_noirq(struct device *dev)
1416 {
1417     struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1418 
1419     dev_dbg(cs35l41->dev, "Late system suspend, reenabling IRQ\n");
1420     enable_irq(cs35l41->irq);
1421 
1422     return 0;
1423 }
1424 
1425 static int __maybe_unused cs35l41_sys_resume_noirq(struct device *dev)
1426 {
1427     struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1428 
1429     dev_dbg(cs35l41->dev, "Early system resume, disabling IRQ\n");
1430     disable_irq(cs35l41->irq);
1431 
1432     return 0;
1433 }
1434 
1435 static int __maybe_unused cs35l41_sys_resume(struct device *dev)
1436 {
1437     struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
1438 
1439     dev_dbg(cs35l41->dev, "System resume, reenabling IRQ\n");
1440     enable_irq(cs35l41->irq);
1441 
1442     return 0;
1443 }
1444 
1445 const struct dev_pm_ops cs35l41_pm_ops = {
1446     SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL)
1447 
1448     SET_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend, cs35l41_sys_resume)
1449     SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend_noirq, cs35l41_sys_resume_noirq)
1450 };
1451 EXPORT_SYMBOL_GPL(cs35l41_pm_ops);
1452 
1453 MODULE_DESCRIPTION("ASoC CS35L41 driver");
1454 MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
1455 MODULE_LICENSE("GPL");