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

Merge tag 'asoc-v5.17-2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v5.17

A few more updates for v5.17, nothing hugely stand out in the few days
since the initial pull request was sent.

+584 -179
+10 -4
drivers/firmware/cirrus/cs_dsp.c
··· 2744 2744 2745 2745 static int cs_dsp_halo_start_core(struct cs_dsp *dsp) 2746 2746 { 2747 - return regmap_update_bits(dsp->regmap, 2748 - dsp->base + HALO_CCM_CORE_CONTROL, 2749 - HALO_CORE_RESET | HALO_CORE_EN, 2750 - HALO_CORE_RESET | HALO_CORE_EN); 2747 + int ret; 2748 + 2749 + ret = regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, 2750 + HALO_CORE_RESET | HALO_CORE_EN, 2751 + HALO_CORE_RESET | HALO_CORE_EN); 2752 + if (ret) 2753 + return ret; 2754 + 2755 + return regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, 2756 + HALO_CORE_RESET, 0); 2751 2757 } 2752 2758 2753 2759 static void cs_dsp_halo_stop_core(struct cs_dsp *dsp)
+7
include/sound/cs35l41.h
··· 40 40 #define CS35L41_PROTECT_REL_ERR_IGN 0x00002034 41 41 #define CS35L41_GPIO_PAD_CONTROL 0x0000242C 42 42 #define CS35L41_JTAG_CONTROL 0x00002438 43 + #define CS35L41_PWRMGT_CTL 0x00002900 44 + #define CS35L41_WAKESRC_CTL 0x00002904 45 + #define CS35L41_PWRMGT_STS 0x00002908 43 46 #define CS35L41_PLL_CLK_CTRL 0x00002C04 44 47 #define CS35L41_DSP_CLK_CTRL 0x00002C08 45 48 #define CS35L41_GLOBAL_CLK_CTRL 0x00002C0C ··· 638 635 #define CS35L41_INPUT_DSP_TX1 0x32 639 636 #define CS35L41_INPUT_DSP_TX2 0x33 640 637 638 + #define CS35L41_WR_PEND_STS_MASK 0x2 639 + 641 640 #define CS35L41_PLL_CLK_SEL_MASK 0x07 642 641 #define CS35L41_PLL_CLK_SEL_SHIFT 0 643 642 #define CS35L41_PLL_CLK_EN_MASK 0x10 ··· 767 762 extern struct regmap_config cs35l41_regmap_i2c; 768 763 extern struct regmap_config cs35l41_regmap_spi; 769 764 765 + int cs35l41_test_key_unlock(struct device *dev, struct regmap *regmap); 766 + int cs35l41_test_key_lock(struct device *dev, struct regmap *regmap); 770 767 int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap); 771 768 int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid); 772 769 int cs35l41_set_channels(struct device *dev, struct regmap *reg,
+4 -4
sound/soc/amd/acp/acp-mach-common.c
··· 293 293 294 294 /* Declare RT1019 codec components */ 295 295 SND_SOC_DAILINK_DEF(rt1019, 296 - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"), 297 - COMP_CODEC("i2c-10EC1019:02", "rt1019-aif"))); 296 + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"), 297 + COMP_CODEC("i2c-10EC1019:01", "rt1019-aif"))); 298 298 299 299 static const struct snd_soc_dapm_route rt1019_map_lr[] = { 300 300 { "Left Spk", NULL, "Left SPO" }, ··· 303 303 304 304 static struct snd_soc_codec_conf rt1019_conf[] = { 305 305 { 306 - .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"), 306 + .dlc = COMP_CODEC_CONF("i2c-10EC1019:00"), 307 307 .name_prefix = "Left", 308 308 }, 309 309 { 310 - .dlc = COMP_CODEC_CONF("i2c-10EC1019:02"), 310 + .dlc = COMP_CODEC_CONF("i2c-10EC1019:01"), 311 311 .name_prefix = "Right", 312 312 }, 313 313 };
-2
sound/soc/codecs/ak4375.c
··· 438 438 return 0; 439 439 } 440 440 441 - #ifdef CONFIG_PM 442 441 static int __maybe_unused ak4375_runtime_suspend(struct device *dev) 443 442 { 444 443 struct ak4375_priv *ak4375 = dev_get_drvdata(dev); ··· 462 463 463 464 return regcache_sync(ak4375->regmap); 464 465 } 465 - #endif /* CONFIG_PM */ 466 466 467 467 static const struct snd_soc_component_driver soc_codec_dev_ak4375 = { 468 468 .controls = ak4375_snd_controls,
+3
sound/soc/codecs/cs35l41-i2c.c
··· 22 22 static const struct i2c_device_id cs35l41_id_i2c[] = { 23 23 { "cs35l40", 0 }, 24 24 { "cs35l41", 0 }, 25 + { "cs35l51", 0 }, 26 + { "cs35l53", 0 }, 25 27 {} 26 28 }; 27 29 ··· 86 84 static struct i2c_driver cs35l41_i2c_driver = { 87 85 .driver = { 88 86 .name = "cs35l41", 87 + .pm = &cs35l41_pm_ops, 89 88 .of_match_table = of_match_ptr(cs35l41_of_match), 90 89 .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), 91 90 },
+62 -92
sound/soc/codecs/cs35l41-lib.c
··· 20 20 { CS35L41_PWR_CTRL2, 0x00000000 }, 21 21 { CS35L41_PWR_CTRL3, 0x01000010 }, 22 22 { CS35L41_GPIO_PAD_CONTROL, 0x00000000 }, 23 + { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, 24 + { CS35L41_TST_FS_MON0, 0x00020016 }, 25 + { CS35L41_BSTCVRT_COEFF, 0x00002424 }, 26 + { CS35L41_BSTCVRT_SLOPE_LBST, 0x00007500 }, 27 + { CS35L41_BSTCVRT_PEAK_CUR, 0x0000004A }, 23 28 { CS35L41_SP_ENABLES, 0x00000000 }, 24 29 { CS35L41_SP_RATE_CTRL, 0x00000028 }, 25 30 { CS35L41_SP_FORMAT, 0x18180200 }, ··· 53 48 { CS35L41_WKFET_CFG, 0x00000111 }, 54 49 { CS35L41_NG_CFG, 0x00000033 }, 55 50 { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, 51 + { CS35L41_IRQ1_MASK1, 0xFFFFFFFF }, 52 + { CS35L41_IRQ1_MASK2, 0xFFFFFFFF }, 53 + { CS35L41_IRQ1_MASK3, 0xFFFF87FF }, 54 + { CS35L41_IRQ1_MASK4, 0xFEFFFFFF }, 56 55 { CS35L41_GPIO1_CTRL1, 0xE1000001 }, 57 56 { CS35L41_GPIO2_CTRL1, 0xE1000001 }, 58 57 { CS35L41_MIXER_NGATE_CFG, 0x00000000 }, 59 58 { CS35L41_MIXER_NGATE_CH1_CFG, 0x00000303 }, 60 59 { CS35L41_MIXER_NGATE_CH2_CFG, 0x00000303 }, 60 + { CS35L41_DSP1_CCM_CORE_CTRL, 0x00000101 }, 61 61 }; 62 62 63 63 static bool cs35l41_readable_reg(struct device *dev, unsigned int reg) ··· 90 80 case CS35L41_PROTECT_REL_ERR_IGN: 91 81 case CS35L41_GPIO_PAD_CONTROL: 92 82 case CS35L41_JTAG_CONTROL: 83 + case CS35L41_PWRMGT_CTL: 84 + case CS35L41_WAKESRC_CTL: 85 + case CS35L41_PWRMGT_STS: 93 86 case CS35L41_PLL_CLK_CTRL: 94 87 case CS35L41_DSP_CLK_CTRL: 95 88 case CS35L41_GLOBAL_CLK_CTRL: 96 89 case CS35L41_DATA_FS_SEL: 90 + case CS35L41_TST_FS_MON0: 97 91 case CS35L41_MDSYNC_EN: 98 92 case CS35L41_MDSYNC_TX_ID: 99 93 case CS35L41_MDSYNC_PWR_CTRL: ··· 356 342 static bool cs35l41_precious_reg(struct device *dev, unsigned int reg) 357 343 { 358 344 switch (reg) { 345 + case CS35L41_TEST_KEY_CTL: 346 + case CS35L41_USER_KEY_CTL: 359 347 case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: 348 + case CS35L41_TST_FS_MON0: 360 349 case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: 361 350 case CS35L41_DSP1_YMEM_PACK_0 ... CS35L41_DSP1_YMEM_PACK_1532: 362 351 case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: ··· 376 359 case CS35L41_SFT_RESET: 377 360 case CS35L41_FABID: 378 361 case CS35L41_REVID: 362 + case CS35L41_OTPID: 363 + case CS35L41_TEST_KEY_CTL: 364 + case CS35L41_USER_KEY_CTL: 365 + case CS35L41_PWRMGT_CTL: 366 + case CS35L41_WAKESRC_CTL: 367 + case CS35L41_PWRMGT_STS: 379 368 case CS35L41_DTEMP_EN: 380 369 case CS35L41_IRQ1_STATUS: 381 370 case CS35L41_IRQ1_STATUS1: ··· 392 369 case CS35L41_IRQ1_RAW_STATUS2: 393 370 case CS35L41_IRQ1_RAW_STATUS3: 394 371 case CS35L41_IRQ1_RAW_STATUS4: 395 - case CS35L41_IRQ1_FRC1: 396 - case CS35L41_IRQ1_FRC2: 397 - case CS35L41_IRQ1_FRC3: 398 - case CS35L41_IRQ1_FRC4: 399 - case CS35L41_IRQ1_EDGE1: 400 - case CS35L41_IRQ1_EDGE4: 401 - case CS35L41_IRQ1_POL1: 402 - case CS35L41_IRQ1_POL2: 403 - case CS35L41_IRQ1_POL3: 404 - case CS35L41_IRQ1_POL4: 405 - case CS35L41_IRQ1_DB3: 406 372 case CS35L41_IRQ2_STATUS: 407 373 case CS35L41_IRQ2_STATUS1: 408 374 case CS35L41_IRQ2_STATUS2: ··· 401 389 case CS35L41_IRQ2_RAW_STATUS2: 402 390 case CS35L41_IRQ2_RAW_STATUS3: 403 391 case CS35L41_IRQ2_RAW_STATUS4: 404 - case CS35L41_IRQ2_FRC1: 405 - case CS35L41_IRQ2_FRC2: 406 - case CS35L41_IRQ2_FRC3: 407 - case CS35L41_IRQ2_FRC4: 408 - case CS35L41_IRQ2_EDGE1: 409 - case CS35L41_IRQ2_EDGE4: 410 - case CS35L41_IRQ2_POL1: 411 - case CS35L41_IRQ2_POL2: 412 - case CS35L41_IRQ2_POL3: 413 - case CS35L41_IRQ2_POL4: 414 - case CS35L41_IRQ2_DB3: 415 392 case CS35L41_GPIO_STATUS1: 416 - case CS35L41_OTP_TRIM_1: 417 - case CS35L41_OTP_TRIM_2: 418 - case CS35L41_OTP_TRIM_3: 419 - case CS35L41_OTP_TRIM_4: 420 - case CS35L41_OTP_TRIM_5: 421 - case CS35L41_OTP_TRIM_6: 422 - case CS35L41_OTP_TRIM_7: 423 - case CS35L41_OTP_TRIM_8: 424 - case CS35L41_OTP_TRIM_9: 425 - case CS35L41_OTP_TRIM_10: 426 - case CS35L41_OTP_TRIM_11: 427 - case CS35L41_OTP_TRIM_12: 428 - case CS35L41_OTP_TRIM_13: 429 - case CS35L41_OTP_TRIM_14: 430 - case CS35L41_OTP_TRIM_15: 431 - case CS35L41_OTP_TRIM_16: 432 - case CS35L41_OTP_TRIM_17: 433 - case CS35L41_OTP_TRIM_18: 434 - case CS35L41_OTP_TRIM_19: 435 - case CS35L41_OTP_TRIM_20: 436 - case CS35L41_OTP_TRIM_21: 437 - case CS35L41_OTP_TRIM_22: 438 - case CS35L41_OTP_TRIM_23: 439 - case CS35L41_OTP_TRIM_24: 440 - case CS35L41_OTP_TRIM_25: 441 - case CS35L41_OTP_TRIM_26: 442 - case CS35L41_OTP_TRIM_27: 443 - case CS35L41_OTP_TRIM_28: 444 - case CS35L41_OTP_TRIM_29: 445 - case CS35L41_OTP_TRIM_30: 446 - case CS35L41_OTP_TRIM_31: 447 - case CS35L41_OTP_TRIM_32: 448 - case CS35L41_OTP_TRIM_33: 449 - case CS35L41_OTP_TRIM_34: 450 - case CS35L41_OTP_TRIM_35: 451 - case CS35L41_OTP_TRIM_36: 452 393 case CS35L41_DSP_MBOX_1 ... CS35L41_DSP_VIRT2_MBOX_8: 453 394 case CS35L41_DSP1_XMEM_PACK_0 ... CS35L41_DSP1_XMEM_PACK_3068: 454 395 case CS35L41_DSP1_XMEM_UNPACK32_0 ... CS35L41_DSP1_XMEM_UNPACK32_2046: ··· 410 445 case CS35L41_DSP1_YMEM_UNPACK32_0 ... CS35L41_DSP1_YMEM_UNPACK32_1022: 411 446 case CS35L41_DSP1_YMEM_UNPACK24_0 ... CS35L41_DSP1_YMEM_UNPACK24_2045: 412 447 case CS35L41_DSP1_PMEM_0 ... CS35L41_DSP1_PMEM_5114: 413 - case CS35L41_DSP1_CCM_CORE_CTRL ... CS35L41_DSP1_WDT_STATUS: 448 + case CS35L41_DSP1_SCRATCH1: 449 + case CS35L41_DSP1_SCRATCH2: 450 + case CS35L41_DSP1_SCRATCH3: 451 + case CS35L41_DSP1_SCRATCH4: 452 + case CS35L41_DSP1_CCM_CLK_OVERRIDE ... CS35L41_DSP1_WDT_STATUS: 414 453 case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31: 415 454 return true; 416 455 default: ··· 629 660 }; 630 661 631 662 static const struct reg_sequence cs35l41_reva0_errata_patch[] = { 632 - { 0x00000040, 0x00005555 }, 633 - { 0x00000040, 0x0000AAAA }, 634 663 { 0x00003854, 0x05180240 }, 635 664 { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, 636 665 { 0x00004310, 0x00000000 }, ··· 641 674 { CS35L41_IRQ2_DB3, 0x00000000 }, 642 675 { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, 643 676 { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, 644 - { 0x00000040, 0x0000CCCC }, 645 - { 0x00000040, 0x00003333 }, 646 677 { CS35L41_PWR_CTRL2, 0x00000000 }, 647 678 { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, 648 679 }; 649 680 650 681 static const struct reg_sequence cs35l41_revb0_errata_patch[] = { 651 - { 0x00000040, 0x00005555 }, 652 - { 0x00000040, 0x0000AAAA }, 653 682 { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, 654 683 { 0x00004310, 0x00000000 }, 655 684 { CS35L41_VPVBST_FS_SEL, 0x00000000 }, 656 685 { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, 657 686 { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, 658 687 { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, 659 - { 0x00000040, 0x0000CCCC }, 660 - { 0x00000040, 0x00003333 }, 661 688 { CS35L41_PWR_CTRL2, 0x00000000 }, 662 689 { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, 663 690 }; 664 691 665 692 static const struct reg_sequence cs35l41_revb2_errata_patch[] = { 666 - { 0x00000040, 0x00005555 }, 667 - { 0x00000040, 0x0000AAAA }, 668 693 { CS35L41_VIMON_SPKMON_RESYNC, 0x00000000 }, 669 694 { 0x00004310, 0x00000000 }, 670 695 { CS35L41_VPVBST_FS_SEL, 0x00000000 }, 671 696 { CS35L41_BSTCVRT_DCM_CTRL, 0x00000051 }, 672 697 { CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000 }, 673 698 { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, 674 - { 0x00000040, 0x0000CCCC }, 675 - { 0x00000040, 0x00003333 }, 676 699 { CS35L41_PWR_CTRL2, 0x00000000 }, 677 700 { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, 678 701 }; ··· 750 793 return NULL; 751 794 } 752 795 796 + int cs35l41_test_key_unlock(struct device *dev, struct regmap *regmap) 797 + { 798 + static const struct reg_sequence unlock[] = { 799 + { CS35L41_TEST_KEY_CTL, 0x00000055 }, 800 + { CS35L41_TEST_KEY_CTL, 0x000000AA }, 801 + }; 802 + int ret; 803 + 804 + ret = regmap_multi_reg_write(regmap, unlock, ARRAY_SIZE(unlock)); 805 + if (ret) 806 + dev_err(dev, "Failed to unlock test key: %d\n", ret); 807 + 808 + return ret; 809 + } 810 + EXPORT_SYMBOL_GPL(cs35l41_test_key_unlock); 811 + 812 + int cs35l41_test_key_lock(struct device *dev, struct regmap *regmap) 813 + { 814 + static const struct reg_sequence unlock[] = { 815 + { CS35L41_TEST_KEY_CTL, 0x000000CC }, 816 + { CS35L41_TEST_KEY_CTL, 0x00000033 }, 817 + }; 818 + int ret; 819 + 820 + ret = regmap_multi_reg_write(regmap, unlock, ARRAY_SIZE(unlock)); 821 + if (ret) 822 + dev_err(dev, "Failed to lock test key: %d\n", ret); 823 + 824 + return ret; 825 + } 826 + EXPORT_SYMBOL_GPL(cs35l41_test_key_lock); 827 + 828 + /* Must be called with the TEST_KEY unlocked */ 753 829 int cs35l41_otp_unpack(struct device *dev, struct regmap *regmap) 754 830 { 755 831 const struct cs35l41_otp_map_element_t *otp_map_match; ··· 821 831 bit_offset = otp_map_match->bit_offset; 822 832 word_offset = otp_map_match->word_offset; 823 833 824 - ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000055); 825 - if (ret) { 826 - dev_err(dev, "Write Unlock key failed 1/2: %d\n", ret); 827 - goto err_otp_unpack; 828 - } 829 - ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000AA); 830 - if (ret) { 831 - dev_err(dev, "Write Unlock key failed 2/2: %d\n", ret); 832 - goto err_otp_unpack; 833 - } 834 - 835 834 for (i = 0; i < otp_map_match->num_elements; i++) { 836 835 dev_dbg(dev, "bitoffset= %d, word_offset=%d, bit_sum mod 32=%d\n", 837 836 bit_offset, word_offset, bit_sum % 32); ··· 856 877 } 857 878 } 858 879 859 - ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x000000CC); 860 - if (ret) { 861 - dev_err(dev, "Write Lock key failed 1/2: %d\n", ret); 862 - goto err_otp_unpack; 863 - } 864 - ret = regmap_write(regmap, CS35L41_TEST_KEY_CTL, 0x00000033); 865 - if (ret) { 866 - dev_err(dev, "Write Lock key failed 2/2: %d\n", ret); 867 - goto err_otp_unpack; 868 - } 869 880 ret = 0; 870 881 871 882 err_otp_unpack: ··· 865 896 } 866 897 EXPORT_SYMBOL_GPL(cs35l41_otp_unpack); 867 898 899 + /* Must be called with the TEST_KEY unlocked */ 868 900 int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid) 869 901 { 870 902 char *rev;
+3
sound/soc/codecs/cs35l41-spi.c
··· 20 20 static const struct spi_device_id cs35l41_id_spi[] = { 21 21 { "cs35l40", 0 }, 22 22 { "cs35l41", 0 }, 23 + { "cs35l51", 0 }, 24 + { "cs35l53", 0 }, 23 25 {} 24 26 }; 25 27 ··· 84 82 static struct spi_driver cs35l41_spi_driver = { 85 83 .driver = { 86 84 .name = "cs35l41", 85 + .pm = &cs35l41_pm_ops, 87 86 .of_match_table = of_match_ptr(cs35l41_of_match), 88 87 .acpi_match_table = ACPI_PTR(cs35l41_acpi_match), 89 88 },
+223 -24
sound/soc/codecs/cs35l41.c
··· 13 13 #include <linux/module.h> 14 14 #include <linux/moduleparam.h> 15 15 #include <linux/of_device.h> 16 + #include <linux/pm_runtime.h> 16 17 #include <linux/property.h> 17 18 #include <sound/initval.h> 18 19 #include <sound/pcm.h> ··· 182 181 static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w, 183 182 struct snd_kcontrol *kcontrol, int event) 184 183 { 184 + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 185 + struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component); 185 186 int ret; 186 187 187 188 switch (event) { 188 189 case SND_SOC_DAPM_PRE_PMU: 190 + if (cs35l41->dsp.cs_dsp.booted) 191 + return 0; 192 + 189 193 return wm_adsp_early_event(w, kcontrol, event); 190 194 case SND_SOC_DAPM_PRE_PMD: 191 - ret = wm_adsp_early_event(w, kcontrol, event); 192 - if (ret) 193 - return ret; 195 + if (cs35l41->dsp.preloaded) 196 + return 0; 194 197 195 - return wm_adsp_event(w, kcontrol, event); 198 + if (cs35l41->dsp.cs_dsp.running) { 199 + ret = wm_adsp_event(w, kcontrol, event); 200 + if (ret) 201 + return ret; 202 + } 203 + 204 + return wm_adsp_early_event(w, kcontrol, event); 196 205 default: 197 206 return 0; 198 207 } ··· 216 205 case CSPL_MBOX_CMD_UNKNOWN_CMD: 217 206 return true; 218 207 case CSPL_MBOX_CMD_PAUSE: 208 + case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: 219 209 return (sts == CSPL_MBOX_STS_PAUSED); 220 210 case CSPL_MBOX_CMD_RESUME: 221 211 return (sts == CSPL_MBOX_STS_RUNNING); ··· 238 226 // Set mailbox cmd 239 227 ret = regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); 240 228 if (ret < 0) { 241 - dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); 229 + if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) 230 + dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); 242 231 return ret; 243 232 } 244 233 ··· 422 409 int ret = IRQ_NONE; 423 410 unsigned int i; 424 411 412 + pm_runtime_get_sync(cs35l41->dev); 413 + 425 414 for (i = 0; i < ARRAY_SIZE(status); i++) { 426 415 regmap_read(cs35l41->regmap, 427 416 CS35L41_IRQ1_STATUS1 + (i * CS35L41_REGSTRIDE), ··· 436 421 /* Check to see if unmasked bits are active */ 437 422 if (!(status[0] & ~masks[0]) && !(status[1] & ~masks[1]) && 438 423 !(status[2] & ~masks[2]) && !(status[3] & ~masks[3])) 439 - return IRQ_NONE; 424 + goto done; 440 425 441 426 if (status[3] & CS35L41_OTP_BOOT_DONE) { 442 427 regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK4, ··· 541 526 ret = IRQ_HANDLED; 542 527 } 543 528 529 + done: 530 + pm_runtime_mark_last_busy(cs35l41->dev); 531 + pm_runtime_put_autosuspend(cs35l41->dev); 532 + 544 533 return ret; 545 534 } 546 535 547 536 static const struct reg_sequence cs35l41_pup_patch[] = { 548 - { 0x00000040, 0x00000055 }, 549 - { 0x00000040, 0x000000AA }, 537 + { CS35L41_TEST_KEY_CTL, 0x00000055 }, 538 + { CS35L41_TEST_KEY_CTL, 0x000000AA }, 550 539 { 0x00002084, 0x002F1AA0 }, 551 - { 0x00000040, 0x000000CC }, 552 - { 0x00000040, 0x00000033 }, 540 + { CS35L41_TEST_KEY_CTL, 0x000000CC }, 541 + { CS35L41_TEST_KEY_CTL, 0x00000033 }, 553 542 }; 554 543 555 544 static const struct reg_sequence cs35l41_pdn_patch[] = { 556 - { 0x00000040, 0x00000055 }, 557 - { 0x00000040, 0x000000AA }, 545 + { CS35L41_TEST_KEY_CTL, 0x00000055 }, 546 + { CS35L41_TEST_KEY_CTL, 0x000000AA }, 558 547 { 0x00002084, 0x002F1AA3 }, 559 - { 0x00000040, 0x000000CC }, 560 - { 0x00000040, 0x00000033 }, 548 + { CS35L41_TEST_KEY_CTL, 0x000000CC }, 549 + { CS35L41_TEST_KEY_CTL, 0x00000033 }, 561 550 }; 562 551 563 552 static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w, ··· 1195 1176 dsp->cs_dsp.type = WMFW_HALO; 1196 1177 dsp->cs_dsp.rev = 0; 1197 1178 dsp->fw = 9; /* 9 is WM_ADSP_FW_SPK_PROT in wm_adsp.c */ 1179 + dsp->toggle_preload = true; 1198 1180 dsp->cs_dsp.dev = cs35l41->dev; 1199 1181 dsp->cs_dsp.regmap = cs35l41->regmap; 1200 1182 dsp->cs_dsp.base = CS35L41_DSP1_CTRL_BASE; ··· 1345 1325 goto err; 1346 1326 } 1347 1327 1328 + cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); 1329 + 1348 1330 ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); 1349 1331 if (ret) 1350 1332 goto err; 1333 + 1334 + ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); 1335 + if (ret < 0) { 1336 + dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); 1337 + goto err; 1338 + } 1339 + 1340 + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); 1351 1341 1352 1342 irq_pol = cs35l41_irq_gpio_config(cs35l41); 1353 1343 ··· 1368 1338 ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL, cs35l41_irq, 1369 1339 IRQF_ONESHOT | IRQF_SHARED | irq_pol, 1370 1340 "cs35l41", cs35l41); 1371 - 1372 - /* CS35L41 needs INT for PDN_DONE */ 1373 1341 if (ret != 0) { 1374 1342 dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret); 1375 - goto err; 1376 - } 1377 - 1378 - ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); 1379 - if (ret < 0) { 1380 - dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); 1381 1343 goto err; 1382 1344 } 1383 1345 ··· 1383 1361 if (ret < 0) 1384 1362 goto err; 1385 1363 1364 + pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); 1365 + pm_runtime_use_autosuspend(cs35l41->dev); 1366 + pm_runtime_mark_last_busy(cs35l41->dev); 1367 + pm_runtime_set_active(cs35l41->dev); 1368 + pm_runtime_get_noresume(cs35l41->dev); 1369 + pm_runtime_enable(cs35l41->dev); 1370 + 1386 1371 ret = devm_snd_soc_register_component(cs35l41->dev, 1387 1372 &soc_component_dev_cs35l41, 1388 1373 cs35l41_dai, ARRAY_SIZE(cs35l41_dai)); 1389 1374 if (ret < 0) { 1390 1375 dev_err(cs35l41->dev, "Register codec failed: %d\n", ret); 1391 - goto err_dsp; 1376 + goto err_pm; 1392 1377 } 1378 + 1379 + pm_runtime_put_autosuspend(cs35l41->dev); 1393 1380 1394 1381 dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", 1395 1382 regid, reg_revid); 1396 1383 1397 1384 return 0; 1398 1385 1399 - err_dsp: 1386 + err_pm: 1387 + pm_runtime_disable(cs35l41->dev); 1388 + pm_runtime_put_noidle(cs35l41->dev); 1389 + 1400 1390 wm_adsp2_remove(&cs35l41->dsp); 1401 1391 err: 1402 1392 regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); ··· 1420 1386 1421 1387 void cs35l41_remove(struct cs35l41_private *cs35l41) 1422 1388 { 1389 + pm_runtime_get_sync(cs35l41->dev); 1390 + pm_runtime_disable(cs35l41->dev); 1391 + 1423 1392 regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF); 1424 1393 wm_adsp2_remove(&cs35l41->dsp); 1394 + 1395 + pm_runtime_put_noidle(cs35l41->dev); 1396 + 1425 1397 regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies); 1426 1398 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 1427 1399 } 1428 1400 EXPORT_SYMBOL_GPL(cs35l41_remove); 1401 + 1402 + static int __maybe_unused cs35l41_runtime_suspend(struct device *dev) 1403 + { 1404 + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); 1405 + 1406 + dev_dbg(cs35l41->dev, "Runtime suspend\n"); 1407 + 1408 + if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) 1409 + return 0; 1410 + 1411 + dev_dbg(cs35l41->dev, "Enter hibernate\n"); 1412 + 1413 + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); 1414 + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); 1415 + 1416 + // Don't wait for ACK since bus activity would wake the device 1417 + regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, 1418 + CSPL_MBOX_CMD_HIBERNATE); 1419 + 1420 + regcache_cache_only(cs35l41->regmap, true); 1421 + regcache_mark_dirty(cs35l41->regmap); 1422 + 1423 + return 0; 1424 + } 1425 + 1426 + static void cs35l41_wait_for_pwrmgt_sts(struct cs35l41_private *cs35l41) 1427 + { 1428 + const int pwrmgt_retries = 10; 1429 + unsigned int sts; 1430 + int i, ret; 1431 + 1432 + for (i = 0; i < pwrmgt_retries; i++) { 1433 + ret = regmap_read(cs35l41->regmap, CS35L41_PWRMGT_STS, &sts); 1434 + if (ret) 1435 + dev_err(cs35l41->dev, "Failed to read PWRMGT_STS: %d\n", ret); 1436 + else if (!(sts & CS35L41_WR_PEND_STS_MASK)) 1437 + return; 1438 + 1439 + udelay(20); 1440 + } 1441 + 1442 + dev_err(cs35l41->dev, "Timed out reading PWRMGT_STS\n"); 1443 + } 1444 + 1445 + static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) 1446 + { 1447 + const int wake_retries = 20; 1448 + const int sleep_retries = 5; 1449 + int ret, i, j; 1450 + 1451 + for (i = 0; i < sleep_retries; i++) { 1452 + dev_dbg(cs35l41->dev, "Exit hibernate\n"); 1453 + 1454 + for (j = 0; j < wake_retries; j++) { 1455 + ret = cs35l41_set_cspl_mbox_cmd(cs35l41, 1456 + CSPL_MBOX_CMD_OUT_OF_HIBERNATE); 1457 + if (!ret) 1458 + break; 1459 + 1460 + usleep_range(100, 200); 1461 + } 1462 + 1463 + if (j < wake_retries) { 1464 + dev_dbg(cs35l41->dev, "Wake success at cycle: %d\n", j); 1465 + return 0; 1466 + } 1467 + 1468 + dev_err(cs35l41->dev, "Wake failed, re-enter hibernate: %d\n", ret); 1469 + 1470 + cs35l41_wait_for_pwrmgt_sts(cs35l41); 1471 + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088); 1472 + 1473 + cs35l41_wait_for_pwrmgt_sts(cs35l41); 1474 + regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188); 1475 + 1476 + cs35l41_wait_for_pwrmgt_sts(cs35l41); 1477 + regmap_write(cs35l41->regmap, CS35L41_PWRMGT_CTL, 0x3); 1478 + } 1479 + 1480 + dev_err(cs35l41->dev, "Timed out waking device\n"); 1481 + 1482 + return -ETIMEDOUT; 1483 + } 1484 + 1485 + static int __maybe_unused cs35l41_runtime_resume(struct device *dev) 1486 + { 1487 + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); 1488 + int ret; 1489 + 1490 + dev_dbg(cs35l41->dev, "Runtime resume\n"); 1491 + 1492 + if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running) 1493 + return 0; 1494 + 1495 + regcache_cache_only(cs35l41->regmap, false); 1496 + 1497 + ret = cs35l41_exit_hibernate(cs35l41); 1498 + if (ret) 1499 + return ret; 1500 + 1501 + /* Test key needs to be unlocked to allow the OTP settings to re-apply */ 1502 + cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); 1503 + ret = regcache_sync(cs35l41->regmap); 1504 + cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); 1505 + if (ret) { 1506 + dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); 1507 + return ret; 1508 + } 1509 + 1510 + return 0; 1511 + } 1512 + 1513 + static int __maybe_unused cs35l41_sys_suspend(struct device *dev) 1514 + { 1515 + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); 1516 + 1517 + dev_dbg(cs35l41->dev, "System suspend, disabling IRQ\n"); 1518 + disable_irq(cs35l41->irq); 1519 + 1520 + return 0; 1521 + } 1522 + 1523 + static int __maybe_unused cs35l41_sys_suspend_noirq(struct device *dev) 1524 + { 1525 + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); 1526 + 1527 + dev_dbg(cs35l41->dev, "Late system suspend, reenabling IRQ\n"); 1528 + enable_irq(cs35l41->irq); 1529 + 1530 + return 0; 1531 + } 1532 + 1533 + static int __maybe_unused cs35l41_sys_resume_noirq(struct device *dev) 1534 + { 1535 + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); 1536 + 1537 + dev_dbg(cs35l41->dev, "Early system resume, disabling IRQ\n"); 1538 + disable_irq(cs35l41->irq); 1539 + 1540 + return 0; 1541 + } 1542 + 1543 + static int __maybe_unused cs35l41_sys_resume(struct device *dev) 1544 + { 1545 + struct cs35l41_private *cs35l41 = dev_get_drvdata(dev); 1546 + 1547 + dev_dbg(cs35l41->dev, "System resume, reenabling IRQ\n"); 1548 + enable_irq(cs35l41->irq); 1549 + 1550 + return 0; 1551 + } 1552 + 1553 + const struct dev_pm_ops cs35l41_pm_ops = { 1554 + SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) 1555 + 1556 + SET_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend, cs35l41_sys_resume) 1557 + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend_noirq, cs35l41_sys_resume_noirq) 1558 + }; 1559 + EXPORT_SYMBOL_GPL(cs35l41_pm_ops); 1429 1560 1430 1561 MODULE_DESCRIPTION("ASoC CS35L41 driver"); 1431 1562 MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
+4
sound/soc/codecs/cs35l41.h
··· 21 21 #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 22 22 #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 23 23 24 + extern const struct dev_pm_ops cs35l41_pm_ops; 25 + 24 26 enum cs35l41_cspl_mbox_status { 25 27 CSPL_MBOX_STS_RUNNING = 0, 26 28 CSPL_MBOX_STS_PAUSED = 1, ··· 35 33 CSPL_MBOX_CMD_RESUME = 2, 36 34 CSPL_MBOX_CMD_REINIT = 3, 37 35 CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, 36 + CSPL_MBOX_CMD_HIBERNATE = 5, 37 + CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, 38 38 CSPL_MBOX_CMD_UNKNOWN_CMD = -1, 39 39 CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, 40 40 };
+11
sound/soc/codecs/cs4265.c
··· 626 626 ARRAY_SIZE(cs4265_dai)); 627 627 } 628 628 629 + static int cs4265_i2c_remove(struct i2c_client *i2c) 630 + { 631 + struct cs4265_private *cs4265 = i2c_get_clientdata(i2c); 632 + 633 + if (cs4265->reset_gpio) 634 + gpiod_set_value_cansleep(cs4265->reset_gpio, 0); 635 + 636 + return 0; 637 + } 638 + 629 639 static const struct of_device_id cs4265_of_match[] = { 630 640 { .compatible = "cirrus,cs4265", }, 631 641 { } ··· 655 645 }, 656 646 .id_table = cs4265_id, 657 647 .probe = cs4265_i2c_probe, 648 + .remove = cs4265_i2c_remove, 658 649 }; 659 650 660 651 module_i2c_driver(cs4265_i2c_driver);
+56 -15
sound/soc/codecs/rt5640.c
··· 2160 2160 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); 2161 2161 int val; 2162 2162 2163 - val = snd_soc_component_read(component, RT5640_INT_IRQ_ST); 2163 + if (rt5640->jd_gpio) 2164 + val = gpiod_get_value(rt5640->jd_gpio) ? RT5640_JD_STATUS : 0; 2165 + else 2166 + val = snd_soc_component_read(component, RT5640_INT_IRQ_ST); 2167 + 2164 2168 dev_dbg(component->dev, "irq status %#04x\n", val); 2165 2169 2166 2170 if (rt5640->jd_inverted) ··· 2302 2298 static void rt5640_jack_work(struct work_struct *work) 2303 2299 { 2304 2300 struct rt5640_priv *rt5640 = 2305 - container_of(work, struct rt5640_priv, jack_work); 2301 + container_of(work, struct rt5640_priv, jack_work.work); 2306 2302 struct snd_soc_component *component = rt5640->component; 2307 2303 int status; 2308 2304 ··· 2385 2381 * disabled the OVCD IRQ, the IRQ pin will stay high and as 2386 2382 * we react to edges, we miss the unplug event -> recheck. 2387 2383 */ 2388 - queue_work(system_long_wq, &rt5640->jack_work); 2384 + queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); 2389 2385 } 2390 2386 } 2391 2387 ··· 2394 2390 struct rt5640_priv *rt5640 = data; 2395 2391 2396 2392 if (rt5640->jack) 2397 - queue_work(system_long_wq, &rt5640->jack_work); 2393 + queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); 2394 + 2395 + return IRQ_HANDLED; 2396 + } 2397 + 2398 + static irqreturn_t rt5640_jd_gpio_irq(int irq, void *data) 2399 + { 2400 + struct rt5640_priv *rt5640 = data; 2401 + 2402 + queue_delayed_work(system_long_wq, &rt5640->jack_work, 2403 + msecs_to_jiffies(JACK_SETTLE_TIME)); 2398 2404 2399 2405 return IRQ_HANDLED; 2400 2406 } ··· 2413 2399 { 2414 2400 struct rt5640_priv *rt5640 = data; 2415 2401 2416 - cancel_work_sync(&rt5640->jack_work); 2402 + cancel_delayed_work_sync(&rt5640->jack_work); 2417 2403 cancel_delayed_work_sync(&rt5640->bp_work); 2418 2404 } 2419 2405 ··· 2453 2439 if (!rt5640->jack) 2454 2440 return; 2455 2441 2456 - free_irq(rt5640->irq, rt5640); 2442 + if (rt5640->jd_gpio_irq_requested) 2443 + free_irq(rt5640->jd_gpio_irq, rt5640); 2444 + 2445 + if (rt5640->irq_requested) 2446 + free_irq(rt5640->irq, rt5640); 2447 + 2457 2448 rt5640_cancel_work(rt5640); 2458 2449 2459 2450 if (rt5640->jack->status & SND_JACK_MICROPHONE) { ··· 2467 2448 snd_soc_jack_report(rt5640->jack, 0, SND_JACK_BTN_0); 2468 2449 } 2469 2450 2451 + rt5640->jd_gpio_irq_requested = false; 2452 + rt5640->irq_requested = false; 2453 + rt5640->jd_gpio = NULL; 2470 2454 rt5640->jack = NULL; 2471 2455 } 2472 2456 2473 2457 static void rt5640_enable_jack_detect(struct snd_soc_component *component, 2474 - struct snd_soc_jack *jack) 2458 + struct snd_soc_jack *jack, 2459 + struct rt5640_set_jack_data *jack_data) 2475 2460 { 2476 2461 struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); 2477 2462 int ret; ··· 2519 2496 rt5640_enable_micbias1_ovcd_irq(component); 2520 2497 } 2521 2498 2499 + if (jack_data && jack_data->codec_irq_override) 2500 + rt5640->irq = jack_data->codec_irq_override; 2501 + 2502 + if (jack_data && jack_data->jd_gpio) { 2503 + rt5640->jd_gpio = jack_data->jd_gpio; 2504 + rt5640->jd_gpio_irq = gpiod_to_irq(rt5640->jd_gpio); 2505 + 2506 + ret = request_irq(rt5640->jd_gpio_irq, rt5640_jd_gpio_irq, 2507 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 2508 + "rt5640-jd-gpio", rt5640); 2509 + if (ret) { 2510 + dev_warn(component->dev, "Failed to request jd GPIO IRQ %d: %d\n", 2511 + rt5640->jd_gpio_irq, ret); 2512 + rt5640_disable_jack_detect(component); 2513 + return; 2514 + } 2515 + rt5640->jd_gpio_irq_requested = true; 2516 + } 2517 + 2522 2518 ret = request_irq(rt5640->irq, rt5640_irq, 2523 2519 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 2524 2520 "rt5640", rt5640); 2525 2521 if (ret) { 2526 2522 dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); 2527 - rt5640->irq = -ENXIO; 2528 - /* Undo above settings */ 2529 2523 rt5640_disable_jack_detect(component); 2530 2524 return; 2531 2525 } 2526 + rt5640->irq_requested = true; 2532 2527 2533 2528 /* sync initial jack state */ 2534 - queue_work(system_long_wq, &rt5640->jack_work); 2529 + queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); 2535 2530 } 2536 2531 2537 2532 static void rt5640_enable_hda_jack_detect( ··· 2587 2546 } 2588 2547 2589 2548 /* sync initial jack state */ 2590 - queue_work(system_long_wq, &rt5640->jack_work); 2549 + queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); 2591 2550 } 2592 2551 2593 2552 static int rt5640_set_jack(struct snd_soc_component *component, ··· 2599 2558 if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) 2600 2559 rt5640_enable_hda_jack_detect(component, jack); 2601 2560 else 2602 - rt5640_enable_jack_detect(component, jack); 2561 + rt5640_enable_jack_detect(component, jack, data); 2603 2562 } else { 2604 2563 rt5640_disable_jack_detect(component); 2605 2564 } ··· 2778 2737 regcache_cache_only(rt5640->regmap, false); 2779 2738 regcache_sync(rt5640->regmap); 2780 2739 2781 - if (rt5640->jd_src) { 2740 + if (rt5640->jack) { 2782 2741 if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) 2783 2742 snd_soc_component_update_bits(component, 2784 2743 RT5640_DUMMY2, 0x1100, 0x1100); ··· 2786 2745 snd_soc_component_write(component, RT5640_DUMMY2, 2787 2746 0x4001); 2788 2747 2789 - queue_work(system_long_wq, &rt5640->jack_work); 2748 + queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); 2790 2749 } 2791 2750 2792 2751 return 0; ··· 2991 2950 rt5640->hp_mute = true; 2992 2951 rt5640->irq = i2c->irq; 2993 2952 INIT_DELAYED_WORK(&rt5640->bp_work, rt5640_button_press_work); 2994 - INIT_WORK(&rt5640->jack_work, rt5640_jack_work); 2953 + INIT_DELAYED_WORK(&rt5640->jack_work, rt5640_jack_work); 2995 2954 2996 2955 /* Make sure work is stopped on probe-error / remove */ 2997 2956 ret = devm_add_action_or_reset(&i2c->dev, rt5640_cancel_work, rt5640);
+10 -1
sound/soc/codecs/rt5640.h
··· 2124 2124 2125 2125 int ldo1_en; /* GPIO for LDO1_EN */ 2126 2126 int irq; 2127 + int jd_gpio_irq; 2127 2128 int sysclk; 2128 2129 int sysclk_src; 2129 2130 int lrck[RT5640_AIFS]; ··· 2137 2136 2138 2137 bool hp_mute; 2139 2138 bool asrc_en; 2139 + bool irq_requested; 2140 + bool jd_gpio_irq_requested; 2140 2141 2141 2142 /* Jack and button detect data */ 2142 2143 bool ovcd_irq_enabled; ··· 2148 2145 int release_count; 2149 2146 int poll_count; 2150 2147 struct delayed_work bp_work; 2151 - struct work_struct jack_work; 2148 + struct delayed_work jack_work; 2152 2149 struct snd_soc_jack *jack; 2150 + struct gpio_desc *jd_gpio; 2153 2151 unsigned int jd_src; 2154 2152 bool jd_inverted; 2155 2153 unsigned int ovcd_th; 2156 2154 unsigned int ovcd_sf; 2155 + }; 2156 + 2157 + struct rt5640_set_jack_data { 2158 + int codec_irq_override; 2159 + struct gpio_desc *jd_gpio; 2157 2160 }; 2158 2161 2159 2162 int rt5640_dmic_enable(struct snd_soc_component *component,
+9 -8
sound/soc/codecs/wcd9335.c
··· 341 341 int reset_gpio; 342 342 struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY]; 343 343 344 - unsigned int rx_port_value; 344 + unsigned int rx_port_value[WCD9335_RX_MAX]; 345 345 unsigned int tx_port_value; 346 346 int hph_l_gain; 347 347 int hph_r_gain; ··· 1269 1269 static int slim_rx_mux_get(struct snd_kcontrol *kc, 1270 1270 struct snd_ctl_elem_value *ucontrol) 1271 1271 { 1272 - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kc); 1273 - struct wcd9335_codec *wcd = dev_get_drvdata(dapm->dev); 1272 + struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kc); 1273 + struct wcd9335_codec *wcd = dev_get_drvdata(w->dapm->dev); 1274 + u32 port_id = w->shift; 1274 1275 1275 - ucontrol->value.enumerated.item[0] = wcd->rx_port_value; 1276 + ucontrol->value.enumerated.item[0] = wcd->rx_port_value[port_id]; 1276 1277 1277 1278 return 0; 1278 1279 } ··· 1287 1286 struct snd_soc_dapm_update *update = NULL; 1288 1287 u32 port_id = w->shift; 1289 1288 1290 - wcd->rx_port_value = ucontrol->value.enumerated.item[0]; 1289 + wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; 1291 1290 1292 - switch (wcd->rx_port_value) { 1291 + switch (wcd->rx_port_value[port_id]) { 1293 1292 case 0: 1294 1293 list_del_init(&wcd->rx_chs[port_id].list); 1295 1294 break; ··· 1310 1309 &wcd->dai[AIF4_PB].slim_ch_list); 1311 1310 break; 1312 1311 default: 1313 - dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value); 1312 + dev_err(wcd->dev, "Unknown AIF %d\n", wcd->rx_port_value[port_id]); 1314 1313 goto err; 1315 1314 } 1316 1315 1317 - snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value, 1316 + snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id], 1318 1317 e, update); 1319 1318 1320 1319 return 0;
+11 -3
sound/soc/codecs/wm_adsp.c
··· 896 896 struct wm_adsp *dsp = &dsps[mc->shift - 1]; 897 897 char preload[32]; 898 898 899 + if (dsp->preloaded == ucontrol->value.integer.value[0]) 900 + return 0; 901 + 899 902 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name); 900 903 901 - dsp->preloaded = ucontrol->value.integer.value[0]; 902 - 903 - if (ucontrol->value.integer.value[0]) 904 + if (ucontrol->value.integer.value[0] || dsp->toggle_preload) 904 905 snd_soc_component_force_enable_pin(component, preload); 905 906 else 906 907 snd_soc_component_disable_pin(component, preload); ··· 909 908 snd_soc_dapm_sync(dapm); 910 909 911 910 flush_work(&dsp->boot_work); 911 + 912 + dsp->preloaded = ucontrol->value.integer.value[0]; 913 + 914 + if (dsp->toggle_preload) { 915 + snd_soc_component_disable_pin(component, preload); 916 + snd_soc_dapm_sync(dapm); 917 + } 912 918 913 919 return 0; 914 920 }
+8
sound/soc/codecs/wm_adsp.h
··· 41 41 42 42 struct list_head compr_list; 43 43 struct list_head buffer_list; 44 + 45 + /* 46 + * Flag indicating the preloader widget only needs power toggled 47 + * on state change rather than held on for the duration of the 48 + * preload, useful for devices that can retain firmware memory 49 + * across power down. 50 + */ 51 + bool toggle_preload; 44 52 }; 45 53 46 54 #define WM_ADSP1(wname, num) \
+58 -11
sound/soc/fsl/fsl_asrc.c
··· 19 19 #include "fsl_asrc.h" 20 20 21 21 #define IDEAL_RATIO_DECIMAL_DEPTH 26 22 + #define DIVIDER_NUM 64 22 23 23 24 #define pair_err(fmt, ...) \ 24 25 dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) ··· 101 100 0xf, 0xf, 0x6, 0xf, 0xf, 0xf, 0xa, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 102 101 }, 103 102 }; 103 + 104 + /* 105 + * According to RM, the divider range is 1 ~ 8, 106 + * prescaler is power of 2 from 1 ~ 128. 107 + */ 108 + static int asrc_clk_divider[DIVIDER_NUM] = { 109 + 1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */ 110 + 2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */ 111 + 3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */ 112 + 4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */ 113 + 5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */ 114 + 6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */ 115 + 7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */ 116 + 8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */ 117 + }; 118 + 119 + /* 120 + * Check if the divider is available for internal ratio mode 121 + */ 122 + static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div) 123 + { 124 + u32 rem, i; 125 + u64 n; 126 + 127 + if (div) 128 + *div = 0; 129 + 130 + if (clk_rate == 0 || rate == 0) 131 + return false; 132 + 133 + n = clk_rate; 134 + rem = do_div(n, rate); 135 + 136 + if (div) 137 + *div = n; 138 + 139 + if (rem != 0) 140 + return false; 141 + 142 + for (i = 0; i < DIVIDER_NUM; i++) { 143 + if (n == asrc_clk_divider[i]) 144 + break; 145 + } 146 + 147 + if (i == DIVIDER_NUM) 148 + return false; 149 + 150 + return true; 151 + } 104 152 105 153 /** 106 154 * fsl_asrc_sel_proc - Select the pre-processing and post-processing options ··· 380 330 enum asrc_word_width input_word_width; 381 331 enum asrc_word_width output_word_width; 382 332 u32 inrate, outrate, indiv, outdiv; 383 - u32 clk_index[2], div[2], rem[2]; 333 + u32 clk_index[2], div[2]; 384 334 u64 clk_rate; 385 335 int in, out, channels; 386 336 int pre_proc, post_proc; 387 337 struct clk *clk; 388 - bool ideal; 338 + bool ideal, div_avail; 389 339 390 340 if (!config) { 391 341 pair_err("invalid pair config\n"); ··· 465 415 clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]]; 466 416 467 417 clk_rate = clk_get_rate(clk); 468 - rem[IN] = do_div(clk_rate, inrate); 469 - div[IN] = (u32)clk_rate; 418 + div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]); 470 419 471 420 /* 472 421 * The divider range is [1, 1024], defined by the hardware. For non- ··· 474 425 * only result in different converting speeds. So remainder does not 475 426 * matter, as long as we keep the divider within its valid range. 476 427 */ 477 - if (div[IN] == 0 || (!ideal && (div[IN] > 1024 || rem[IN] != 0))) { 428 + if (div[IN] == 0 || (!ideal && !div_avail)) { 478 429 pair_err("failed to support input sample rate %dHz by asrck_%x\n", 479 430 inrate, clk_index[ideal ? OUT : IN]); 480 431 return -EINVAL; ··· 485 436 clk = asrc_priv->asrck_clk[clk_index[OUT]]; 486 437 clk_rate = clk_get_rate(clk); 487 438 if (ideal && use_ideal_rate) 488 - rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE); 439 + div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]); 489 440 else 490 - rem[OUT] = do_div(clk_rate, outrate); 491 - div[OUT] = clk_rate; 441 + div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]); 492 442 493 443 /* Output divider has the same limitation as the input one */ 494 - if (div[OUT] == 0 || (!ideal && (div[OUT] > 1024 || rem[OUT] != 0))) { 444 + if (div[OUT] == 0 || (!ideal && !div_avail)) { 495 445 pair_err("failed to support output sample rate %dHz by asrck_%x\n", 496 446 outrate, clk_index[OUT]); 497 447 return -EINVAL; ··· 669 621 clk_index = asrc_priv->clk_map[j][i]; 670 622 clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]); 671 623 /* Only match a perfect clock source with no remainder */ 672 - if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 && 673 - (clk_rate % rate[j]) == 0) 624 + if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL)) 674 625 break; 675 626 } 676 627
+24 -8
sound/soc/fsl/imx-card.c
··· 120 120 121 121 static struct imx_akcodec_fs_mul ak4458_fs_mul[] = { 122 122 /* Normal, < 32kHz */ 123 - { .rmin = 8000, .rmax = 24000, .wmin = 1024, .wmax = 1024, }, 123 + { .rmin = 8000, .rmax = 24000, .wmin = 256, .wmax = 1024, }, 124 124 /* Normal, 32kHz */ 125 125 { .rmin = 32000, .rmax = 32000, .wmin = 256, .wmax = 1024, }, 126 126 /* Normal */ ··· 151 151 * Table 7 - mapping multiplier and speed mode 152 152 * Tables 8 & 9 - mapping speed mode and LRCK fs 153 153 */ 154 - { .rmin = 8000, .rmax = 32000, .wmin = 1024, .wmax = 1024, }, /* Normal, <= 32kHz */ 155 - { .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, }, /* Normal */ 154 + { .rmin = 8000, .rmax = 32000, .wmin = 256, .wmax = 1024, }, /* Normal, <= 32kHz */ 155 + { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 512, }, /* Normal */ 156 156 { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, }, /* Double */ 157 157 { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, }, /* Quad */ 158 158 { .rmin = 352800, .rmax = 384000, .wmin = 128, .wmax = 128, }, /* Oct */ ··· 164 164 * (Table 4 from datasheet) 165 165 */ 166 166 static struct imx_akcodec_fs_mul ak5558_fs_mul[] = { 167 - { .rmin = 8000, .rmax = 32000, .wmin = 1024, .wmax = 1024, }, 167 + { .rmin = 8000, .rmax = 32000, .wmin = 512, .wmax = 1024, }, 168 168 { .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, }, 169 169 { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, }, 170 170 { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, }, ··· 247 247 } 248 248 249 249 static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream, 250 - struct snd_pcm_hw_params *params) 250 + struct snd_pcm_hw_params *params, 251 + int slots, int slot_width) 251 252 { 252 253 struct snd_soc_pcm_runtime *rtd = substream->private_data; 253 254 struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card); 254 255 const struct imx_card_plat_data *plat_data = data->plat_data; 255 256 struct dai_link_data *link_data = &data->link_data[rtd->num]; 256 - unsigned int width = link_data->slots * link_data->slot_width; 257 + unsigned int width = slots * slot_width; 257 258 unsigned int rate = params_rate(params); 258 259 int i; 259 260 ··· 350 349 351 350 /* Set MCLK freq */ 352 351 if (codec_is_akcodec(plat_data->type)) 353 - mclk_freq = akcodec_get_mclk_rate(substream, params); 352 + mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width); 354 353 else 355 354 mclk_freq = params_rate(params) * slots * slot_width; 356 355 /* Use the maximum freq from DSD512 (512*44100 = 22579200) */ ··· 554 553 link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1; 555 554 556 555 /* sai may support mclk/bclk = 1 */ 557 - if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) 556 + if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) { 558 557 link_data->one2one_ratio = true; 558 + } else { 559 + int i; 560 + 561 + /* 562 + * i.MX8MQ don't support one2one ratio, then 563 + * with ak4497 only 16bit case is supported. 564 + */ 565 + for (i = 0; i < ARRAY_SIZE(ak4497_fs_mul); i++) { 566 + if (ak4497_fs_mul[i].rmin == 705600 && 567 + ak4497_fs_mul[i].rmax == 768000) { 568 + ak4497_fs_mul[i].wmin = 32; 569 + ak4497_fs_mul[i].wmax = 32; 570 + } 571 + } 572 + } 559 573 } 560 574 561 575 link->cpus->of_node = args.np;
+80 -6
sound/soc/intel/boards/bytcr_rt5640.c
··· 40 40 BYT_RT5640_NO_INTERNAL_MIC_MAP, 41 41 }; 42 42 43 + #define RT5640_JD_SRC_EXT_GPIO 0x0f 44 + 43 45 enum { 44 46 BYT_RT5640_JD_SRC_GPIO1 = (RT5640_JD_SRC_GPIO1 << 4), 45 47 BYT_RT5640_JD_SRC_JD1_IN4P = (RT5640_JD_SRC_JD1_IN4P << 4), ··· 49 47 BYT_RT5640_JD_SRC_GPIO2 = (RT5640_JD_SRC_GPIO2 << 4), 50 48 BYT_RT5640_JD_SRC_GPIO3 = (RT5640_JD_SRC_GPIO3 << 4), 51 49 BYT_RT5640_JD_SRC_GPIO4 = (RT5640_JD_SRC_GPIO4 << 4), 50 + BYT_RT5640_JD_SRC_EXT_GPIO = (RT5640_JD_SRC_EXT_GPIO << 4) 52 51 }; 53 52 54 53 enum { ··· 82 79 #define BYT_RT5640_LINEOUT_AS_HP2 BIT(26) 83 80 #define BYT_RT5640_HSMIC2_ON_IN1 BIT(27) 84 81 #define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28) 82 + #define BYT_RT5640_USE_AMCR0F28 BIT(29) 85 83 86 84 #define BYTCR_INPUT_DEFAULTS \ 87 85 (BYT_RT5640_IN3_MAP | \ ··· 97 93 struct byt_rt5640_private { 98 94 struct snd_soc_jack jack; 99 95 struct snd_soc_jack jack2; 96 + struct rt5640_set_jack_data jack_data; 100 97 struct gpio_desc *hsmic_detect; 101 98 struct clk *mclk; 102 99 struct device *codec_dev; ··· 602 597 BYT_RT5640_OVCD_TH_2000UA | 603 598 BYT_RT5640_OVCD_SF_0P75 | 604 599 BYT_RT5640_SSP0_AIF1 | 605 - BYT_RT5640_MCLK_EN), 600 + BYT_RT5640_MCLK_EN | 601 + BYT_RT5640_USE_AMCR0F28), 606 602 }, 607 603 { 608 604 .matches = { ··· 629 623 BYT_RT5640_DIFF_MIC | 630 624 BYT_RT5640_SSP0_AIF2 | 631 625 BYT_RT5640_MCLK_EN), 626 + }, 627 + { 628 + .matches = { 629 + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 630 + DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), 631 + }, 632 + .driver_data = (void *)(BYT_RT5640_IN1_MAP | 633 + BYT_RT5640_JD_SRC_EXT_GPIO | 634 + BYT_RT5640_OVCD_TH_2000UA | 635 + BYT_RT5640_OVCD_SF_0P75 | 636 + BYT_RT5640_SSP0_AIF1 | 637 + BYT_RT5640_MCLK_EN | 638 + BYT_RT5640_USE_AMCR0F28), 632 639 }, 633 640 { /* Chuwi Vi8 (CWI506) */ 634 641 .matches = { ··· 1099 1080 } 1100 1081 1101 1082 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) { 1102 - props[cnt++] = PROPERTY_ENTRY_U32( 1103 - "realtek,jack-detect-source", 1104 - BYT_RT5640_JDSRC(byt_rt5640_quirk)); 1083 + if (BYT_RT5640_JDSRC(byt_rt5640_quirk) != RT5640_JD_SRC_EXT_GPIO) { 1084 + props[cnt++] = PROPERTY_ENTRY_U32( 1085 + "realtek,jack-detect-source", 1086 + BYT_RT5640_JDSRC(byt_rt5640_quirk)); 1087 + } 1105 1088 1106 1089 props[cnt++] = PROPERTY_ENTRY_U32( 1107 1090 "realtek,over-current-threshold-microamp", ··· 1127 1106 1128 1107 fwnode_handle_put(fwnode); 1129 1108 1109 + return ret; 1110 + } 1111 + 1112 + /* Some Android devs specify IRQs/GPIOS in a special AMCR0F28 ACPI device */ 1113 + static const struct acpi_gpio_params amcr0f28_jd_gpio = { 1, 0, false }; 1114 + 1115 + static const struct acpi_gpio_mapping amcr0f28_gpios[] = { 1116 + { "rt5640-jd-gpios", &amcr0f28_jd_gpio, 1 }, 1117 + { } 1118 + }; 1119 + 1120 + static int byt_rt5640_get_amcr0f28_settings(struct snd_soc_card *card) 1121 + { 1122 + struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); 1123 + struct rt5640_set_jack_data *data = &priv->jack_data; 1124 + struct acpi_device *adev; 1125 + int ret = 0; 1126 + 1127 + adev = acpi_dev_get_first_match_dev("AMCR0F28", "1", -1); 1128 + if (!adev) { 1129 + dev_err(card->dev, "error cannot find AMCR0F28 adev\n"); 1130 + return -ENOENT; 1131 + } 1132 + 1133 + data->codec_irq_override = acpi_dev_gpio_irq_get(adev, 0); 1134 + if (data->codec_irq_override < 0) { 1135 + ret = data->codec_irq_override; 1136 + dev_err(card->dev, "error %d getting codec IRQ\n", ret); 1137 + goto put_adev; 1138 + } 1139 + 1140 + if (BYT_RT5640_JDSRC(byt_rt5640_quirk) == RT5640_JD_SRC_EXT_GPIO) { 1141 + acpi_dev_add_driver_gpios(adev, amcr0f28_gpios); 1142 + data->jd_gpio = devm_fwnode_gpiod_get(card->dev, acpi_fwnode_handle(adev), 1143 + "rt5640-jd", GPIOD_IN, "rt5640-jd"); 1144 + acpi_dev_remove_driver_gpios(adev); 1145 + 1146 + if (IS_ERR(data->jd_gpio)) { 1147 + ret = PTR_ERR(data->jd_gpio); 1148 + dev_err(card->dev, "error %d getting jd GPIO\n", ret); 1149 + } 1150 + } 1151 + 1152 + put_adev: 1153 + acpi_dev_put(adev); 1130 1154 return ret; 1131 1155 } 1132 1156 ··· 1310 1244 } 1311 1245 snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, 1312 1246 KEY_PLAYPAUSE); 1313 - snd_soc_component_set_jack(component, &priv->jack, NULL); 1247 + 1248 + if (byt_rt5640_quirk & BYT_RT5640_USE_AMCR0F28) { 1249 + ret = byt_rt5640_get_amcr0f28_settings(card); 1250 + if (ret) 1251 + return ret; 1252 + } 1253 + 1254 + snd_soc_component_set_jack(component, &priv->jack, &priv->jack_data); 1314 1255 } 1315 1256 1316 1257 if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) { ··· 1521 1448 for_each_card_components(card, component) { 1522 1449 if (!strcmp(component->name, byt_rt5640_codec_name)) { 1523 1450 dev_dbg(component->dev, "re-enabling jack detect after resume\n"); 1524 - snd_soc_component_set_jack(component, &priv->jack, NULL); 1451 + snd_soc_component_set_jack(component, &priv->jack, 1452 + &priv->jack_data); 1525 1453 break; 1526 1454 } 1527 1455 }
+1 -1
sound/soc/soc-topology.c
··· 56 56 const struct firmware *fw; 57 57 58 58 /* runtime FW parsing */ 59 - const u8 *pos; /* read postion */ 59 + const u8 *pos; /* read position */ 60 60 const u8 *hdr_pos; /* header position */ 61 61 unsigned int pass; /* pass number */ 62 62