cs35l45.c (74b14e2850a34740c121cf2758d4181063d4c77c) | cs35l45.c (6c07be8fe92c6b0c24ee1c599601dce3506b83c7) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2// 3// cs35l45.c - CS35L45 ALSA SoC audio driver 4// 5// Copyright 2019-2022 Cirrus Logic, Inc. 6// 7// Author: James Schulman <james.schulman@cirrus.com> 8 --- 22 unchanged lines hidden (view full) --- 31 case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: 32 return (sts == CSPL_MBOX_STS_PAUSED); 33 case CSPL_MBOX_CMD_RESUME: 34 return (sts == CSPL_MBOX_STS_RUNNING); 35 case CSPL_MBOX_CMD_REINIT: 36 return (sts == CSPL_MBOX_STS_RUNNING); 37 case CSPL_MBOX_CMD_STOP_PRE_REINIT: 38 return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); | 1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2// 3// cs35l45.c - CS35L45 ALSA SoC audio driver 4// 5// Copyright 2019-2022 Cirrus Logic, Inc. 6// 7// Author: James Schulman <james.schulman@cirrus.com> 8 --- 22 unchanged lines hidden (view full) --- 31 case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: 32 return (sts == CSPL_MBOX_STS_PAUSED); 33 case CSPL_MBOX_CMD_RESUME: 34 return (sts == CSPL_MBOX_STS_RUNNING); 35 case CSPL_MBOX_CMD_REINIT: 36 return (sts == CSPL_MBOX_STS_RUNNING); 37 case CSPL_MBOX_CMD_STOP_PRE_REINIT: 38 return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); |
39 case CSPL_MBOX_CMD_HIBERNATE: 40 return (sts == CSPL_MBOX_STS_HIBERNATE); |
|
39 default: 40 return false; 41 } 42} 43 44static int cs35l45_set_cspl_mbox_cmd(struct cs35l45_private *cs35l45, 45 struct regmap *regmap, 46 const enum cs35l45_cspl_mboxcmd cmd) --- 692 unchanged lines hidden (view full) --- 739 .controls = cs35l45_controls, 740 .num_controls = ARRAY_SIZE(cs35l45_controls), 741 742 .name = "cs35l45", 743 744 .endianness = 1, 745}; 746 | 41 default: 42 return false; 43 } 44} 45 46static int cs35l45_set_cspl_mbox_cmd(struct cs35l45_private *cs35l45, 47 struct regmap *regmap, 48 const enum cs35l45_cspl_mboxcmd cmd) --- 692 unchanged lines hidden (view full) --- 741 .controls = cs35l45_controls, 742 .num_controls = ARRAY_SIZE(cs35l45_controls), 743 744 .name = "cs35l45", 745 746 .endianness = 1, 747}; 748 |
749static void cs35l45_setup_hibernate(struct cs35l45_private *cs35l45) 750{ 751 unsigned int wksrc; 752 753 if (cs35l45->bus_type == CONTROL_BUS_I2C) 754 wksrc = CS35L45_WKSRC_I2C; 755 else 756 wksrc = CS35L45_WKSRC_SPI; 757 758 regmap_update_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL, 759 CS35L45_WKSRC_EN_MASK, 760 wksrc << CS35L45_WKSRC_EN_SHIFT); 761 762 regmap_set_bits(cs35l45->regmap, CS35L45_WAKESRC_CTL, 763 CS35L45_UPDT_WKCTL_MASK); 764 765 regmap_update_bits(cs35l45->regmap, CS35L45_WKI2C_CTL, 766 CS35L45_WKI2C_ADDR_MASK, cs35l45->i2c_addr); 767 768 regmap_set_bits(cs35l45->regmap, CS35L45_WKI2C_CTL, 769 CS35L45_UPDT_WKI2C_MASK); 770} 771 772static int cs35l45_enter_hibernate(struct cs35l45_private *cs35l45) 773{ 774 dev_dbg(cs35l45->dev, "Enter hibernate\n"); 775 776 cs35l45_setup_hibernate(cs35l45); 777 778 // Don't wait for ACK since bus activity would wake the device 779 regmap_write(cs35l45->regmap, CS35L45_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE); 780 781 return 0; 782} 783 784static int cs35l45_exit_hibernate(struct cs35l45_private *cs35l45) 785{ 786 const int wake_retries = 20; 787 const int sleep_retries = 5; 788 int ret, i, j; 789 790 for (i = 0; i < sleep_retries; i++) { 791 dev_dbg(cs35l45->dev, "Exit hibernate\n"); 792 793 for (j = 0; j < wake_retries; j++) { 794 ret = cs35l45_set_cspl_mbox_cmd(cs35l45, cs35l45->regmap, 795 CSPL_MBOX_CMD_OUT_OF_HIBERNATE); 796 if (!ret) { 797 dev_dbg(cs35l45->dev, "Wake success at cycle: %d\n", j); 798 return 0; 799 } 800 usleep_range(100, 200); 801 } 802 803 dev_err(cs35l45->dev, "Wake failed, re-enter hibernate: %d\n", ret); 804 805 cs35l45_setup_hibernate(cs35l45); 806 } 807 808 dev_err(cs35l45->dev, "Timed out waking device\n"); 809 810 return -ETIMEDOUT; 811} 812 |
|
747static int __maybe_unused cs35l45_runtime_suspend(struct device *dev) 748{ 749 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev); 750 | 813static int __maybe_unused cs35l45_runtime_suspend(struct device *dev) 814{ 815 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev); 816 |
817 if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running) 818 return 0; 819 820 cs35l45_enter_hibernate(cs35l45); 821 |
|
751 regcache_cache_only(cs35l45->regmap, true); | 822 regcache_cache_only(cs35l45->regmap, true); |
823 regcache_mark_dirty(cs35l45->regmap); |
|
752 753 dev_dbg(cs35l45->dev, "Runtime suspended\n"); 754 755 return 0; 756} 757 758static int __maybe_unused cs35l45_runtime_resume(struct device *dev) 759{ 760 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev); 761 int ret; 762 | 824 825 dev_dbg(cs35l45->dev, "Runtime suspended\n"); 826 827 return 0; 828} 829 830static int __maybe_unused cs35l45_runtime_resume(struct device *dev) 831{ 832 struct cs35l45_private *cs35l45 = dev_get_drvdata(dev); 833 int ret; 834 |
835 if (!cs35l45->dsp.preloaded || !cs35l45->dsp.cs_dsp.running) 836 return 0; 837 |
|
763 dev_dbg(cs35l45->dev, "Runtime resume\n"); 764 765 regcache_cache_only(cs35l45->regmap, false); | 838 dev_dbg(cs35l45->dev, "Runtime resume\n"); 839 840 regcache_cache_only(cs35l45->regmap, false); |
841 842 ret = cs35l45_exit_hibernate(cs35l45); 843 if (ret) 844 return ret; 845 |
|
766 ret = regcache_sync(cs35l45->regmap); 767 if (ret != 0) 768 dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret); 769 770 /* Clear global error status */ 771 regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); 772 regmap_set_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); 773 regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); --- 446 unchanged lines hidden --- | 846 ret = regcache_sync(cs35l45->regmap); 847 if (ret != 0) 848 dev_warn(cs35l45->dev, "regcache_sync failed: %d\n", ret); 849 850 /* Clear global error status */ 851 regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); 852 regmap_set_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); 853 regmap_clear_bits(cs35l45->regmap, CS35L45_ERROR_RELEASE, CS35L45_GLOBAL_ERR_RLS_MASK); --- 446 unchanged lines hidden --- |