0001
0002
0003
0004
0005
0006
0007
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
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
0390
0391
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
0910 fs1_val = cs35l41_fs_mon[fsindex].fs1;
0911 fs2_val = cs35l41_fs_mon[fsindex].fs2;
0912 } else {
0913
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
0937 ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg);
0938 if (ret)
0939 return ret;
0940
0941
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
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
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;
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
1152 if (!handle)
1153 return 0;
1154
1155 sub = acpi_get_subsystem_id(handle);
1156 if (IS_ERR(sub)) {
1157
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
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
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, ®id);
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, ®_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
1254
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
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
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");