aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Thomson <Adam.Thomson.Opensource@diasemi.com>2016-05-10 11:11:05 -0400
committerMark Brown <broonie@kernel.org>2016-05-10 14:24:19 -0400
commitd575b0b0f01a805508c5cf48b540f004e9b5de07 (patch)
tree823dd5f75ad5728872306deeada77d9d7146e994
parenta0d5caeaebfd00853efa0080afc850e10be7b39a (diff)
ASoC: da7213: Add checking of SRM lock status before enabling DAI
When the codec is DAI clk slave, and the SRM feature of the PLL is being used, the enabling of the DAI should occur only after the PLL has locked to the incoming WCLK. This update adds checking to the the DAI widget event, so it waits for SRM to lock. There is also a timeout if that lock doesn't occur within a given time. Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/da7213.c23
-rw-r--r--sound/soc/codecs/da7213.h4
2 files changed, 27 insertions, 0 deletions
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c
index 701bd6204747..680d11116ccf 100644
--- a/sound/soc/codecs/da7213.c
+++ b/sound/soc/codecs/da7213.c
@@ -734,6 +734,9 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
734{ 734{
735 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 735 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
736 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); 736 struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
737 u8 pll_ctrl, pll_status;
738 int i = 0;
739 bool srm_lock = false;
737 740
738 switch (event) { 741 switch (event) {
739 case SND_SOC_DAPM_PRE_PMU: 742 case SND_SOC_DAPM_PRE_PMU:
@@ -742,6 +745,26 @@ static int da7213_dai_event(struct snd_soc_dapm_widget *w,
742 snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE, 745 snd_soc_update_bits(codec, DA7213_DAI_CLK_MODE,
743 DA7213_DAI_CLK_EN_MASK, 746 DA7213_DAI_CLK_EN_MASK,
744 DA7213_DAI_CLK_EN_MASK); 747 DA7213_DAI_CLK_EN_MASK);
748
749 /* Slave mode, if SRM not enabled no need for status checks */
750 pll_ctrl = snd_soc_read(codec, DA7213_PLL_CTRL);
751 if (!(pll_ctrl & DA7213_PLL_SRM_EN))
752 return 0;
753
754 /* Check SRM has locked */
755 do {
756 pll_status = snd_soc_read(codec, DA7213_PLL_STATUS);
757 if (pll_status & DA7219_PLL_SRM_LOCK) {
758 srm_lock = true;
759 } else {
760 ++i;
761 msleep(50);
762 }
763 } while ((i < DA7213_SRM_CHECK_RETRIES) & (!srm_lock));
764
765 if (!srm_lock)
766 dev_warn(codec->dev, "SRM failed to lock\n");
767
745 return 0; 768 return 0;
746 case SND_SOC_DAPM_POST_PMD: 769 case SND_SOC_DAPM_POST_PMD:
747 /* Disable DAI clks if in master mode */ 770 /* Disable DAI clks if in master mode */
diff --git a/sound/soc/codecs/da7213.h b/sound/soc/codecs/da7213.h
index 5de5c2997e0c..af75340dea63 100644
--- a/sound/soc/codecs/da7213.h
+++ b/sound/soc/codecs/da7213.h
@@ -142,6 +142,9 @@
142 * Bit fields 142 * Bit fields
143 */ 143 */
144 144
145/* DA7213_PLL_STATUS = 0x03 */
146#define DA7219_PLL_SRM_LOCK (0x1 << 1)
147
145/* DA7213_SR = 0x22 */ 148/* DA7213_SR = 0x22 */
146#define DA7213_SR_8000 (0x1 << 0) 149#define DA7213_SR_8000 (0x1 << 0)
147#define DA7213_SR_11025 (0x2 << 0) 150#define DA7213_SR_11025 (0x2 << 0)
@@ -502,6 +505,7 @@
502#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4 505#define DA7213_PLL_INDIV_10_20_MHZ_VAL 4
503#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8 506#define DA7213_PLL_INDIV_20_40_MHZ_VAL 8
504#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16 507#define DA7213_PLL_INDIV_40_54_MHZ_VAL 16
508#define DA7213_SRM_CHECK_RETRIES 8
505 509
506enum da7213_clk_src { 510enum da7213_clk_src {
507 DA7213_CLKSRC_MCLK = 0, 511 DA7213_CLKSRC_MCLK = 0,