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