Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: codecs: lpass-wsa-macro: Prepare to accommodate new codec versions

The driver for Qualcomm LPASS WSA macro codec was developed and tested
on codec v2.1, however v2.5 has significant changes in the registers.
The driver correctly works for v2.1 codec, but has issues when running
on SoC with v2.5 codec (so starting with SM8450, even though playback
works properly on that SoC).

Prepare the driver for handling differences in register layouts of newer
version. This does not have functional impact on older codec versions,
but just:
1. Renames few soc_enums and widgets as v2.1,
2. For registers being different in v2.5, moves the defaults and regmap
configuration to new structures,
3. Adds new 'struct wsa_reg_layout' with offsets and masks for few
registers, so most of the code can stay unchaged on v2.5,
4. Chooses proper widgets, regmap config and register layout based on
version of the codec.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Acked-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patch.msgid.link/20240625-qcom-audio-wsa-second-speaker-v1-2-f65ffdfc368c@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Krzysztof Kozlowski and committed by
Mark Brown
5dcf442b 04f4de6f

+218 -122
+218 -122
sound/soc/codecs/lpass-wsa-macro.c
··· 44 44 #define CDC_WSA_TOP_I2S_CLK (0x00A4) 45 45 #define CDC_WSA_TOP_I2S_RESET (0x00A8) 46 46 #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (0x0100) 47 - #define CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK GENMASK(2, 0) 48 - #define CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK GENMASK(5, 3) 49 47 #define CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (0x0104) 50 - #define CDC_WSA_RX_INTX_2_SEL_MASK GENMASK(2, 0) 51 - #define CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK GENMASK(5, 3) 52 48 #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (0x0108) 53 49 #define CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (0x010C) 54 50 #define CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (0x0110) ··· 169 173 #define CDC_WSA_COMPANDER0_CTL5 (0x0594) 170 174 #define CDC_WSA_COMPANDER0_CTL6 (0x0598) 171 175 #define CDC_WSA_COMPANDER0_CTL7 (0x059C) 172 - #define CDC_WSA_COMPANDER1_CTL0 (0x05C0) 173 - #define CDC_WSA_COMPANDER1_CTL1 (0x05C4) 174 - #define CDC_WSA_COMPANDER1_CTL2 (0x05C8) 175 - #define CDC_WSA_COMPANDER1_CTL3 (0x05CC) 176 - #define CDC_WSA_COMPANDER1_CTL4 (0x05D0) 177 - #define CDC_WSA_COMPANDER1_CTL5 (0x05D4) 178 - #define CDC_WSA_COMPANDER1_CTL6 (0x05D8) 179 - #define CDC_WSA_COMPANDER1_CTL7 (0x05DC) 180 - #define CDC_WSA_SOFTCLIP0_CRC (0x0600) 181 - #define CDC_WSA_SOFTCLIP_CLK_EN_MASK BIT(0) 182 - #define CDC_WSA_SOFTCLIP_CLK_ENABLE BIT(0) 183 - #define CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL (0x0604) 184 - #define CDC_WSA_SOFTCLIP_EN_MASK BIT(0) 185 - #define CDC_WSA_SOFTCLIP_ENABLE BIT(0) 186 - #define CDC_WSA_SOFTCLIP1_CRC (0x0640) 187 - #define CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL (0x0644) 176 + /* CDC_WSA_COMPANDER1_CTLx and CDC_WSA_SOFTCLIPx differ per LPASS codec versions */ 188 177 #define CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL (0x0680) 189 178 #define CDC_WSA_EC_HQ_EC_CLK_EN_MASK BIT(0) 190 179 #define CDC_WSA_EC_HQ_EC_CLK_ENABLE BIT(0) ··· 198 217 #define CDC_WSA_SPLINE_ASRC1_STATUS_FIFO (0x0760) 199 218 #define WSA_MAX_OFFSET (0x0760) 200 219 220 + /* LPASS codec version <=2.4 register offsets */ 221 + #define CDC_WSA_COMPANDER1_CTL0 (0x05C0) 222 + #define CDC_WSA_COMPANDER1_CTL1 (0x05C4) 223 + #define CDC_WSA_COMPANDER1_CTL2 (0x05C8) 224 + #define CDC_WSA_COMPANDER1_CTL3 (0x05CC) 225 + #define CDC_WSA_COMPANDER1_CTL4 (0x05D0) 226 + #define CDC_WSA_COMPANDER1_CTL5 (0x05D4) 227 + #define CDC_WSA_COMPANDER1_CTL6 (0x05D8) 228 + #define CDC_WSA_COMPANDER1_CTL7 (0x05DC) 229 + #define CDC_WSA_SOFTCLIP0_CRC (0x0600) 230 + #define CDC_WSA_SOFTCLIP_CLK_EN_MASK BIT(0) 231 + #define CDC_WSA_SOFTCLIP_CLK_ENABLE BIT(0) 232 + #define CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL (0x0604) 233 + #define CDC_WSA_SOFTCLIP_EN_MASK BIT(0) 234 + #define CDC_WSA_SOFTCLIP_ENABLE BIT(0) 235 + #define CDC_WSA_SOFTCLIP1_CRC (0x0640) 236 + #define CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL (0x0644) 237 + 201 238 #define WSA_MACRO_RX_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ 202 239 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\ 203 240 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000) ··· 236 237 #define WSA_MACRO_MCLK_FREQ 19200000 237 238 #define WSA_MACRO_MUX_CFG_OFFSET 0x8 238 239 #define WSA_MACRO_MUX_CFG1_OFFSET 0x4 239 - #define WSA_MACRO_RX_COMP_OFFSET 0x40 240 - #define WSA_MACRO_RX_SOFTCLIP_OFFSET 0x40 241 240 #define WSA_MACRO_RX_PATH_OFFSET 0x80 242 241 #define WSA_MACRO_RX_PATH_CFG3_OFFSET 0x10 243 242 #define WSA_MACRO_RX_PATH_DSMDEM_OFFSET 0x4C ··· 331 334 WSA_MACRO_MAX_DAIS, 332 335 }; 333 336 337 + /** 338 + * struct wsa_reg_layout - Register layout differences 339 + * @rx_intx_1_mix_inp0_sel_mask: register mask for RX_INTX_1_MIX_INP0_SEL_MASK 340 + * @rx_intx_1_mix_inp1_sel_mask: register mask for RX_INTX_1_MIX_INP1_SEL_MASK 341 + * @rx_intx_1_mix_inp2_sel_mask: register mask for RX_INTX_1_MIX_INP2_SEL_MASK 342 + * @rx_intx_2_sel_mask: register mask for RX_INTX_2_SEL_MASK 343 + * @compander1_reg_offset: offset between compander registers (compander1 - compander0) 344 + * @softclip0_reg_base: base address of softclip0 register 345 + * @softclip1_reg_offset: offset between compander registers (softclip1 - softclip0) 346 + */ 347 + struct wsa_reg_layout { 348 + unsigned int rx_intx_1_mix_inp0_sel_mask; 349 + unsigned int rx_intx_1_mix_inp1_sel_mask; 350 + unsigned int rx_intx_1_mix_inp2_sel_mask; 351 + unsigned int rx_intx_2_sel_mask; 352 + unsigned int compander1_reg_offset; 353 + unsigned int softclip0_reg_base; 354 + unsigned int softclip1_reg_offset; 355 + }; 356 + 334 357 struct wsa_macro { 335 358 struct device *dev; 336 359 int comp_enabled[WSA_MACRO_COMP_MAX]; 337 360 int ec_hq[WSA_MACRO_RX1 + 1]; 338 361 u16 prim_int_users[WSA_MACRO_RX1 + 1]; 339 362 u16 wsa_mclk_users; 363 + enum lpass_codec_version codec_version; 364 + const struct wsa_reg_layout *reg_layout; 340 365 unsigned long active_ch_mask[WSA_MACRO_MAX_DAIS]; 341 366 unsigned long active_ch_cnt[WSA_MACRO_MAX_DAIS]; 342 367 int rx_port_value[WSA_MACRO_RX_MAX]; ··· 377 358 }; 378 359 #define to_wsa_macro(_hw) container_of(_hw, struct wsa_macro, hw) 379 360 361 + static const struct wsa_reg_layout wsa_codec_v2_1 = { 362 + .rx_intx_1_mix_inp0_sel_mask = GENMASK(2, 0), 363 + .rx_intx_1_mix_inp1_sel_mask = GENMASK(5, 3), 364 + .rx_intx_1_mix_inp2_sel_mask = GENMASK(5, 3), 365 + .rx_intx_2_sel_mask = GENMASK(2, 0), 366 + .compander1_reg_offset = 0x40, 367 + .softclip0_reg_base = 0x600, 368 + .softclip1_reg_offset = 0x40, 369 + }; 370 + 380 371 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); 381 372 382 - static const char *const rx_text[] = { 373 + static const char *const rx_text_v2_1[] = { 383 374 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1", "DEC0", "DEC1" 384 375 }; 385 376 386 - static const char *const rx_mix_text[] = { 377 + static const char *const rx_mix_text_v2_1[] = { 387 378 "ZERO", "RX0", "RX1", "RX_MIX0", "RX_MIX1" 388 379 }; 389 380 ··· 418 389 wsa_macro_ear_spkr_pa_gain_text); 419 390 420 391 /* RX INT0 */ 421 - static const struct soc_enum rx0_prim_inp0_chain_enum = 392 + static const struct soc_enum rx0_prim_inp0_chain_enum_v2_1 = 422 393 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 423 - 0, 7, rx_text); 394 + 0, 7, rx_text_v2_1); 424 395 425 - static const struct soc_enum rx0_prim_inp1_chain_enum = 396 + static const struct soc_enum rx0_prim_inp1_chain_enum_v2_1 = 426 397 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 427 - 3, 7, rx_text); 398 + 3, 7, rx_text_v2_1); 428 399 429 - static const struct soc_enum rx0_prim_inp2_chain_enum = 400 + static const struct soc_enum rx0_prim_inp2_chain_enum_v2_1 = 430 401 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 431 - 3, 7, rx_text); 402 + 3, 7, rx_text_v2_1); 432 403 433 - static const struct soc_enum rx0_mix_chain_enum = 404 + static const struct soc_enum rx0_mix_chain_enum_v2_1 = 434 405 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 435 - 0, 5, rx_mix_text); 406 + 0, 5, rx_mix_text_v2_1); 436 407 437 408 static const struct soc_enum rx0_sidetone_mix_enum = 438 409 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, 2, rx_sidetone_mix_text); 439 410 440 - static const struct snd_kcontrol_new rx0_prim_inp0_mux = 441 - SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum); 411 + static const struct snd_kcontrol_new rx0_prim_inp0_mux_v2_1 = 412 + SOC_DAPM_ENUM("WSA_RX0 INP0 Mux", rx0_prim_inp0_chain_enum_v2_1); 442 413 443 - static const struct snd_kcontrol_new rx0_prim_inp1_mux = 444 - SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum); 414 + static const struct snd_kcontrol_new rx0_prim_inp1_mux_v2_1 = 415 + SOC_DAPM_ENUM("WSA_RX0 INP1 Mux", rx0_prim_inp1_chain_enum_v2_1); 445 416 446 - static const struct snd_kcontrol_new rx0_prim_inp2_mux = 447 - SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum); 417 + static const struct snd_kcontrol_new rx0_prim_inp2_mux_v2_1 = 418 + SOC_DAPM_ENUM("WSA_RX0 INP2 Mux", rx0_prim_inp2_chain_enum_v2_1); 448 419 449 - static const struct snd_kcontrol_new rx0_mix_mux = 450 - SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum); 420 + static const struct snd_kcontrol_new rx0_mix_mux_v2_1 = 421 + SOC_DAPM_ENUM("WSA_RX0 MIX Mux", rx0_mix_chain_enum_v2_1); 451 422 452 423 static const struct snd_kcontrol_new rx0_sidetone_mix_mux = 453 424 SOC_DAPM_ENUM("WSA_RX0 SIDETONE MIX Mux", rx0_sidetone_mix_enum); 454 425 455 426 /* RX INT1 */ 456 - static const struct soc_enum rx1_prim_inp0_chain_enum = 427 + static const struct soc_enum rx1_prim_inp0_chain_enum_v2_1 = 457 428 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 458 - 0, 7, rx_text); 429 + 0, 7, rx_text_v2_1); 459 430 460 - static const struct soc_enum rx1_prim_inp1_chain_enum = 431 + static const struct soc_enum rx1_prim_inp1_chain_enum_v2_1 = 461 432 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 462 - 3, 7, rx_text); 433 + 3, 7, rx_text_v2_1); 463 434 464 - static const struct soc_enum rx1_prim_inp2_chain_enum = 435 + static const struct soc_enum rx1_prim_inp2_chain_enum_v2_1 = 465 436 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 466 - 3, 7, rx_text); 437 + 3, 7, rx_text_v2_1); 467 438 468 - static const struct soc_enum rx1_mix_chain_enum = 439 + static const struct soc_enum rx1_mix_chain_enum_v2_1 = 469 440 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 470 - 0, 5, rx_mix_text); 441 + 0, 5, rx_mix_text_v2_1); 471 442 472 - static const struct snd_kcontrol_new rx1_prim_inp0_mux = 473 - SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum); 443 + static const struct snd_kcontrol_new rx1_prim_inp0_mux_v2_1 = 444 + SOC_DAPM_ENUM("WSA_RX1 INP0 Mux", rx1_prim_inp0_chain_enum_v2_1); 474 445 475 - static const struct snd_kcontrol_new rx1_prim_inp1_mux = 476 - SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum); 446 + static const struct snd_kcontrol_new rx1_prim_inp1_mux_v2_1 = 447 + SOC_DAPM_ENUM("WSA_RX1 INP1 Mux", rx1_prim_inp1_chain_enum_v2_1); 477 448 478 - static const struct snd_kcontrol_new rx1_prim_inp2_mux = 479 - SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum); 449 + static const struct snd_kcontrol_new rx1_prim_inp2_mux_v2_1 = 450 + SOC_DAPM_ENUM("WSA_RX1 INP2 Mux", rx1_prim_inp2_chain_enum_v2_1); 480 451 481 - static const struct snd_kcontrol_new rx1_mix_mux = 482 - SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum); 452 + static const struct snd_kcontrol_new rx1_mix_mux_v2_1 = 453 + SOC_DAPM_ENUM("WSA_RX1 MIX Mux", rx1_mix_chain_enum_v2_1); 483 454 484 455 static const struct soc_enum rx_mix_ec0_enum = 485 456 SOC_ENUM_SINGLE(CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, ··· 518 489 { CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x00}, 519 490 { CDC_WSA_RX_INP_MUX_RX_EC_CFG0, 0x00}, 520 491 { CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 0x00}, 521 - { CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02}, 522 - { CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00}, 523 - { CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02}, 524 - { CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00}, 525 - { CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02}, 526 - { CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00}, 527 - { CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02}, 528 - { CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00}, 529 492 { CDC_WSA_INTR_CTRL_CFG, 0x00}, 530 493 { CDC_WSA_INTR_CTRL_CLR_COMMIT, 0x00}, 531 494 { CDC_WSA_INTR_CTRL_PIN1_MASK0, 0xFF}, ··· 582 561 { CDC_WSA_COMPANDER0_CTL5, 0x00}, 583 562 { CDC_WSA_COMPANDER0_CTL6, 0x01}, 584 563 { CDC_WSA_COMPANDER0_CTL7, 0x28}, 585 - { CDC_WSA_COMPANDER1_CTL0, 0x60}, 586 - { CDC_WSA_COMPANDER1_CTL1, 0xDB}, 587 - { CDC_WSA_COMPANDER1_CTL2, 0xFF}, 588 - { CDC_WSA_COMPANDER1_CTL3, 0x35}, 589 - { CDC_WSA_COMPANDER1_CTL4, 0xFF}, 590 - { CDC_WSA_COMPANDER1_CTL5, 0x00}, 591 - { CDC_WSA_COMPANDER1_CTL6, 0x01}, 592 - { CDC_WSA_COMPANDER1_CTL7, 0x28}, 593 - { CDC_WSA_SOFTCLIP0_CRC, 0x00}, 594 - { CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38}, 595 - { CDC_WSA_SOFTCLIP1_CRC, 0x00}, 596 - { CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38}, 597 564 { CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL, 0x00}, 598 565 { CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0, 0x01}, 599 566 { CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL, 0x00}, ··· 606 597 { CDC_WSA_SPLINE_ASRC1_STATUS_FIFO, 0x00}, 607 598 }; 608 599 600 + static const struct reg_default wsa_defaults_v2_1[] = { 601 + { CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02}, 602 + { CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00}, 603 + { CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02}, 604 + { CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00}, 605 + { CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02}, 606 + { CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00}, 607 + { CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02}, 608 + { CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00}, 609 + { CDC_WSA_COMPANDER1_CTL0, 0x60}, 610 + { CDC_WSA_COMPANDER1_CTL1, 0xDB}, 611 + { CDC_WSA_COMPANDER1_CTL2, 0xFF}, 612 + { CDC_WSA_COMPANDER1_CTL3, 0x35}, 613 + { CDC_WSA_COMPANDER1_CTL4, 0xFF}, 614 + { CDC_WSA_COMPANDER1_CTL5, 0x00}, 615 + { CDC_WSA_COMPANDER1_CTL6, 0x01}, 616 + { CDC_WSA_COMPANDER1_CTL7, 0x28}, 617 + { CDC_WSA_SOFTCLIP0_CRC, 0x00}, 618 + { CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38}, 619 + { CDC_WSA_SOFTCLIP1_CRC, 0x00}, 620 + { CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38}, 621 + }; 622 + 609 623 static bool wsa_is_wronly_register(struct device *dev, 610 624 unsigned int reg) 611 625 { ··· 636 604 case CDC_WSA_INTR_CTRL_CLR_COMMIT: 637 605 case CDC_WSA_INTR_CTRL_PIN1_CLEAR0: 638 606 case CDC_WSA_INTR_CTRL_PIN2_CLEAR0: 607 + return true; 608 + } 609 + 610 + return false; 611 + } 612 + 613 + static bool wsa_is_rw_register_v2_1(struct device *dev, unsigned int reg) 614 + { 615 + switch (reg) { 616 + case CDC_WSA_COMPANDER1_CTL0: 617 + case CDC_WSA_COMPANDER1_CTL1: 618 + case CDC_WSA_COMPANDER1_CTL2: 619 + case CDC_WSA_COMPANDER1_CTL3: 620 + case CDC_WSA_COMPANDER1_CTL4: 621 + case CDC_WSA_COMPANDER1_CTL5: 622 + case CDC_WSA_COMPANDER1_CTL7: 623 + case CDC_WSA_SOFTCLIP0_CRC: 624 + case CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL: 625 + case CDC_WSA_SOFTCLIP1_CRC: 626 + case CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL: 639 627 return true; 640 628 } 641 629 ··· 753 701 case CDC_WSA_COMPANDER0_CTL4: 754 702 case CDC_WSA_COMPANDER0_CTL5: 755 703 case CDC_WSA_COMPANDER0_CTL7: 756 - case CDC_WSA_COMPANDER1_CTL0: 757 - case CDC_WSA_COMPANDER1_CTL1: 758 - case CDC_WSA_COMPANDER1_CTL2: 759 - case CDC_WSA_COMPANDER1_CTL3: 760 - case CDC_WSA_COMPANDER1_CTL4: 761 - case CDC_WSA_COMPANDER1_CTL5: 762 - case CDC_WSA_COMPANDER1_CTL7: 763 - case CDC_WSA_SOFTCLIP0_CRC: 764 - case CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL: 765 - case CDC_WSA_SOFTCLIP1_CRC: 766 - case CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL: 767 704 case CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL: 768 705 case CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0: 769 706 case CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL: ··· 768 727 return true; 769 728 } 770 729 771 - return false; 730 + return wsa_is_rw_register_v2_1(dev, reg); 772 731 } 773 732 774 733 static bool wsa_is_writeable_register(struct device *dev, unsigned int reg) ··· 782 741 return ret; 783 742 } 784 743 744 + static bool wsa_is_readable_register_v2_1(struct device *dev, unsigned int reg) 745 + { 746 + switch (reg) { 747 + case CDC_WSA_COMPANDER1_CTL6: 748 + return true; 749 + } 750 + 751 + return wsa_is_rw_register(dev, reg); 752 + } 753 + 785 754 static bool wsa_is_readable_register(struct device *dev, unsigned int reg) 786 755 { 787 756 switch (reg) { ··· 801 750 case CDC_WSA_INTR_CTRL_PIN1_STATUS0: 802 751 case CDC_WSA_INTR_CTRL_PIN2_STATUS0: 803 752 case CDC_WSA_COMPANDER0_CTL6: 804 - case CDC_WSA_COMPANDER1_CTL6: 805 753 case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB: 806 754 case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB: 807 755 case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB: ··· 814 764 return true; 815 765 } 816 766 817 - return wsa_is_rw_register(dev, reg); 767 + return wsa_is_readable_register_v2_1(dev, reg); 768 + } 769 + 770 + static bool wsa_is_volatile_register_v2_1(struct device *dev, unsigned int reg) 771 + { 772 + switch (reg) { 773 + case CDC_WSA_COMPANDER1_CTL6: 774 + return true; 775 + } 776 + 777 + return false; 818 778 } 819 779 820 780 static bool wsa_is_volatile_register(struct device *dev, unsigned int reg) ··· 834 774 case CDC_WSA_INTR_CTRL_PIN1_STATUS0: 835 775 case CDC_WSA_INTR_CTRL_PIN2_STATUS0: 836 776 case CDC_WSA_COMPANDER0_CTL6: 837 - case CDC_WSA_COMPANDER1_CTL6: 838 777 case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB: 839 778 case CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB: 840 779 case CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB: ··· 846 787 case CDC_WSA_SPLINE_ASRC1_STATUS_FIFO: 847 788 return true; 848 789 } 849 - return false; 790 + 791 + return wsa_is_volatile_register_v2_1(dev, reg); 850 792 } 851 793 852 794 static const struct regmap_config wsa_regmap_config = { ··· 856 796 .val_bits = 32, /* 8 but with 32 bit read/write */ 857 797 .reg_stride = 4, 858 798 .cache_type = REGCACHE_FLAT, 859 - .reg_defaults = wsa_defaults, 860 - .num_reg_defaults = ARRAY_SIZE(wsa_defaults), 799 + /* .reg_defaults and .num_reg_defaults set in probe() */ 861 800 .max_register = WSA_MAX_OFFSET, 862 801 .writeable_reg = wsa_is_writeable_register, 863 802 .volatile_reg = wsa_is_volatile_register, ··· 930 871 for (j = 0; j < NUM_INTERPOLATORS; j++) { 931 872 int_mux_cfg1 = int_mux_cfg0 + WSA_MACRO_MUX_CFG1_OFFSET; 932 873 inp0_sel = snd_soc_component_read_field(component, int_mux_cfg0, 933 - CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); 934 - inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, 935 - CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); 874 + wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask); 875 + inp1_sel = snd_soc_component_read_field(component, int_mux_cfg0, 876 + wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask); 936 877 inp2_sel = snd_soc_component_read_field(component, int_mux_cfg1, 937 - CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); 878 + wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask); 938 879 939 880 if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || 940 881 (inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) || ··· 975 916 int_mux_cfg1 = CDC_WSA_RX_INP_MUX_RX_INT0_CFG1; 976 917 for (j = 0; j < NUM_INTERPOLATORS; j++) { 977 918 int_mux_cfg1_val = snd_soc_component_read_field(component, int_mux_cfg1, 978 - CDC_WSA_RX_INTX_2_SEL_MASK); 919 + wsa->reg_layout->rx_intx_2_sel_mask); 979 920 980 921 if (int_mux_cfg1_val == int_2_inp + INTn_2_INP_SEL_RX0) { 981 922 int_fs_reg = CDC_WSA_RX0_RX_PATH_MIX_CTL + ··· 1358 1299 return 0; 1359 1300 1360 1301 comp_ctl0_reg = CDC_WSA_COMPANDER0_CTL0 + 1361 - (comp * WSA_MACRO_RX_COMP_OFFSET); 1302 + (comp * wsa->reg_layout->compander1_reg_offset); 1362 1303 rx_path_cfg0_reg = CDC_WSA_RX0_RX_PATH_CFG0 + 1363 1304 (comp * WSA_MACRO_RX_PATH_OFFSET); 1364 1305 ··· 1404 1345 int path, 1405 1346 bool enable) 1406 1347 { 1407 - u16 softclip_clk_reg = CDC_WSA_SOFTCLIP0_CRC + 1408 - (path * WSA_MACRO_RX_SOFTCLIP_OFFSET); 1348 + u16 softclip_clk_reg = wsa->reg_layout->softclip0_reg_base + 1349 + (path * wsa->reg_layout->softclip1_reg_offset); 1409 1350 u8 softclip_mux_mask = (1 << path); 1410 1351 u8 softclip_mux_value = (1 << path); 1411 1352 ··· 1450 1391 return 0; 1451 1392 1452 1393 softclip_ctrl_reg = CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL + 1453 - (softclip_path * WSA_MACRO_RX_SOFTCLIP_OFFSET); 1394 + (softclip_path * wsa->reg_layout->softclip1_reg_offset); 1454 1395 1455 1396 if (SND_SOC_DAPM_EVENT_ON(event)) { 1456 1397 /* Enable Softclip clock and mux */ ··· 1475 1416 static bool wsa_macro_adie_lb(struct snd_soc_component *component, 1476 1417 int interp_idx) 1477 1418 { 1419 + struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); 1478 1420 u16 int_mux_cfg0, int_mux_cfg1; 1479 1421 u8 int_n_inp0, int_n_inp1, int_n_inp2; 1480 1422 ··· 1483 1423 int_mux_cfg1 = int_mux_cfg0 + 4; 1484 1424 1485 1425 int_n_inp0 = snd_soc_component_read_field(component, int_mux_cfg0, 1486 - CDC_WSA_RX_INTX_1_MIX_INP0_SEL_MASK); 1426 + wsa->reg_layout->rx_intx_1_mix_inp0_sel_mask); 1487 1427 if (int_n_inp0 == INTn_1_INP_SEL_DEC0 || 1488 1428 int_n_inp0 == INTn_1_INP_SEL_DEC1) 1489 1429 return true; 1490 1430 1491 1431 int_n_inp1 = snd_soc_component_read_field(component, int_mux_cfg0, 1492 - CDC_WSA_RX_INTX_1_MIX_INP1_SEL_MASK); 1432 + wsa->reg_layout->rx_intx_1_mix_inp1_sel_mask); 1493 1433 if (int_n_inp1 == INTn_1_INP_SEL_DEC0 || 1494 1434 int_n_inp1 == INTn_1_INP_SEL_DEC1) 1495 1435 return true; 1496 1436 1497 1437 int_n_inp2 = snd_soc_component_read_field(component, int_mux_cfg1, 1498 - CDC_WSA_RX_INTX_1_MIX_INP2_SEL_MASK); 1438 + wsa->reg_layout->rx_intx_1_mix_inp2_sel_mask); 1499 1439 if (int_n_inp2 == INTn_1_INP_SEL_DEC0 || 1500 1440 int_n_inp2 == INTn_1_INP_SEL_DEC1) 1501 1441 return true; ··· 2133 2073 SND_SOC_DAPM_MIXER("WSA RX_MIX0", SND_SOC_NOPM, 0, 0, NULL, 0), 2134 2074 SND_SOC_DAPM_MIXER("WSA RX_MIX1", SND_SOC_NOPM, 0, 0, NULL, 0), 2135 2075 2136 - SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux), 2137 - SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux), 2138 - SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux), 2139 - SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 2140 - 0, &rx0_mix_mux, wsa_macro_enable_mix_path, 2141 - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2142 - SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux), 2143 - SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux), 2144 - SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux), 2145 - SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 2146 - 0, &rx1_mix_mux, wsa_macro_enable_mix_path, 2147 - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2148 - 2149 2076 SND_SOC_DAPM_MIXER_E("WSA_RX INT0 MIX", SND_SOC_NOPM, 0, 0, NULL, 0, 2150 2077 wsa_macro_enable_main_path, SND_SOC_DAPM_PRE_PMU), 2151 2078 SND_SOC_DAPM_MIXER_E("WSA_RX INT1 MIX", SND_SOC_NOPM, 1, 0, NULL, 0, ··· 2181 2134 SND_SOC_DAPM_SUPPLY_S("WSA_MCLK", 0, SND_SOC_NOPM, 0, 0, 2182 2135 wsa_macro_mclk_event, 2183 2136 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2137 + }; 2138 + 2139 + static const struct snd_soc_dapm_widget wsa_macro_dapm_widgets_v2_1[] = { 2140 + SND_SOC_DAPM_MUX("WSA_RX0 INP0", SND_SOC_NOPM, 0, 0, &rx0_prim_inp0_mux_v2_1), 2141 + SND_SOC_DAPM_MUX("WSA_RX0 INP1", SND_SOC_NOPM, 0, 0, &rx0_prim_inp1_mux_v2_1), 2142 + SND_SOC_DAPM_MUX("WSA_RX0 INP2", SND_SOC_NOPM, 0, 0, &rx0_prim_inp2_mux_v2_1), 2143 + SND_SOC_DAPM_MUX_E("WSA_RX0 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX0, 2144 + 0, &rx0_mix_mux_v2_1, wsa_macro_enable_mix_path, 2145 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2146 + SND_SOC_DAPM_MUX("WSA_RX1 INP0", SND_SOC_NOPM, 0, 0, &rx1_prim_inp0_mux_v2_1), 2147 + SND_SOC_DAPM_MUX("WSA_RX1 INP1", SND_SOC_NOPM, 0, 0, &rx1_prim_inp1_mux_v2_1), 2148 + SND_SOC_DAPM_MUX("WSA_RX1 INP2", SND_SOC_NOPM, 0, 0, &rx1_prim_inp2_mux_v2_1), 2149 + SND_SOC_DAPM_MUX_E("WSA_RX1 MIX INP", SND_SOC_NOPM, WSA_MACRO_RX_MIX1, 2150 + 0, &rx1_mix_mux_v2_1, wsa_macro_enable_mix_path, 2151 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 2184 2152 }; 2185 2153 2186 2154 static const struct snd_soc_dapm_route wsa_audio_map[] = { ··· 2343 2281 2344 2282 static int wsa_macro_component_probe(struct snd_soc_component *comp) 2345 2283 { 2284 + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(comp); 2346 2285 struct wsa_macro *wsa = snd_soc_component_get_drvdata(comp); 2286 + const struct snd_soc_dapm_widget *widgets; 2287 + unsigned int num_widgets; 2347 2288 2348 2289 snd_soc_component_init_regmap(comp, wsa->regmap); 2349 2290 ··· 2363 2298 2364 2299 wsa_macro_set_spkr_mode(comp, WSA_MACRO_SPKR_MODE_1); 2365 2300 2366 - return 0; 2301 + widgets = wsa_macro_dapm_widgets_v2_1; 2302 + num_widgets = ARRAY_SIZE(wsa_macro_dapm_widgets_v2_1); 2303 + 2304 + return snd_soc_dapm_new_controls(dapm, widgets, num_widgets); 2367 2305 } 2368 2306 2369 2307 static int swclk_gate_enable(struct clk_hw *hw) ··· 2446 2378 static int wsa_macro_probe(struct platform_device *pdev) 2447 2379 { 2448 2380 struct device *dev = &pdev->dev; 2381 + struct reg_default *reg_defaults; 2382 + struct regmap_config *reg_config; 2449 2383 struct wsa_macro *wsa; 2450 2384 kernel_ulong_t flags; 2451 2385 void __iomem *base; 2452 - int ret; 2386 + int ret, def_count; 2453 2387 2454 2388 flags = (kernel_ulong_t)device_get_match_data(dev); 2455 2389 ··· 2485 2415 if (IS_ERR(base)) 2486 2416 return PTR_ERR(base); 2487 2417 2488 - wsa->regmap = devm_regmap_init_mmio(dev, base, &wsa_regmap_config); 2418 + wsa->codec_version = lpass_macro_get_codec_version(); 2419 + switch (wsa->codec_version) { 2420 + default: 2421 + wsa->reg_layout = &wsa_codec_v2_1; 2422 + def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_1); 2423 + reg_defaults = devm_kmalloc_array(dev, def_count, 2424 + sizeof(*reg_defaults), 2425 + GFP_KERNEL); 2426 + if (!reg_defaults) 2427 + return -ENOMEM; 2428 + memcpy(&reg_defaults[0], wsa_defaults, sizeof(wsa_defaults)); 2429 + memcpy(&reg_defaults[ARRAY_SIZE(wsa_defaults)], 2430 + wsa_defaults_v2_1, sizeof(wsa_defaults_v2_1)); 2431 + break; 2432 + } 2433 + 2434 + reg_config = devm_kmemdup(dev, &wsa_regmap_config, 2435 + sizeof(*reg_config), GFP_KERNEL); 2436 + if (!reg_config) 2437 + return -ENOMEM; 2438 + 2439 + reg_config->reg_defaults = reg_defaults; 2440 + reg_config->num_reg_defaults = def_count; 2441 + 2442 + wsa->regmap = devm_regmap_init_mmio(dev, base, reg_config); 2489 2443 if (IS_ERR(wsa->regmap)) 2490 2444 return PTR_ERR(wsa->regmap); 2491 2445 2446 + devm_kfree(dev, reg_config); 2447 + devm_kfree(dev, reg_defaults); 2492 2448 dev_set_drvdata(dev, wsa); 2493 2449 2494 2450 wsa->dev = dev;