aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorShengjiu Wang <b02247@freescale.com>2014-06-23 06:52:02 -0400
committerShengjiu Wang <b02247@freescale.com>2014-06-24 03:52:29 -0400
commit27c369795208a9a0e4a275655a2e479a762c47ed (patch)
treec19481d1336735fa183ab0e5f0db9c4724951829 /sound/soc/fsl
parent6dd40bb4a070adaced87a51ce231336334541692 (diff)
ENGR00319687 ASoC: fsl_esai: esai reset can't work after adding regcache
The reason is that PRRC and PCRC isn't cleared in restore_reg(), then update_bits for PCRC and PRRC will fail for cache is not updated. In other side, remove the store_reg() and restore_reg for adding regcache, and use regcache_sync to restore the registers. Signed-off-by: Shengjiu Wang <b02247@freescale.com>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_esai.c67
1 files changed, 21 insertions, 46 deletions
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 7204171edca6..0d8da0924608 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -24,7 +24,6 @@
24 SNDRV_PCM_FMTBIT_S16_LE | \ 24 SNDRV_PCM_FMTBIT_S16_LE | \
25 SNDRV_PCM_FMTBIT_S20_3LE | \ 25 SNDRV_PCM_FMTBIT_S20_3LE | \
26 SNDRV_PCM_FMTBIT_S24_LE) 26 SNDRV_PCM_FMTBIT_S24_LE)
27#define REG_CACHE_NUM 20
28 27
29/** 28/**
30 * fsl_esai: ESAI private data 29 * fsl_esai: ESAI private data
@@ -64,7 +63,6 @@ struct fsl_esai {
64 bool slave_mode; 63 bool slave_mode;
65 bool synchronous; 64 bool synchronous;
66 char name[32]; 65 char name[32];
67 u32 reg_cache[REG_CACHE_NUM];
68}; 66};
69 67
70static irqreturn_t esai_isr(int irq, void *devid) 68static irqreturn_t esai_isr(int irq, void *devid)
@@ -736,46 +734,6 @@ static bool fsl_esai_check_xrun(struct snd_pcm_substream *substream)
736 return saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE) ; 734 return saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE) ;
737} 735}
738 736
739static int store_reg(struct snd_soc_dai *cpu_dai)
740{
741 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(cpu_dai);
742
743 regmap_read(esai_priv->regmap, REG_ESAI_ECR, &esai_priv->reg_cache[0]);
744 regmap_read(esai_priv->regmap, REG_ESAI_TFCR, &esai_priv->reg_cache[2]);
745 regmap_read(esai_priv->regmap, REG_ESAI_RFCR, &esai_priv->reg_cache[4]);
746 regmap_read(esai_priv->regmap, REG_ESAI_SAICR, &esai_priv->reg_cache[8]);
747 regmap_read(esai_priv->regmap, REG_ESAI_TCR, &esai_priv->reg_cache[9]);
748 regmap_read(esai_priv->regmap, REG_ESAI_TCCR, &esai_priv->reg_cache[10]);
749 regmap_read(esai_priv->regmap, REG_ESAI_RCR, &esai_priv->reg_cache[11]);
750 regmap_read(esai_priv->regmap, REG_ESAI_RCCR, &esai_priv->reg_cache[12]);
751 regmap_read(esai_priv->regmap, REG_ESAI_TSMA, &esai_priv->reg_cache[13]);
752 regmap_read(esai_priv->regmap, REG_ESAI_TSMB, &esai_priv->reg_cache[14]);
753 regmap_read(esai_priv->regmap, REG_ESAI_RSMA, &esai_priv->reg_cache[15]);
754 regmap_read(esai_priv->regmap, REG_ESAI_RSMB, &esai_priv->reg_cache[16]);
755
756 return 0;
757}
758
759static int restore_reg(struct snd_soc_dai *cpu_dai)
760{
761 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(cpu_dai);
762
763 regmap_write(esai_priv->regmap, REG_ESAI_ECR, esai_priv->reg_cache[0]);
764 regmap_write(esai_priv->regmap, REG_ESAI_TFCR, esai_priv->reg_cache[2] & ~ESAI_xFCR_xFEN);
765 regmap_write(esai_priv->regmap, REG_ESAI_RFCR, esai_priv->reg_cache[4] & ~ESAI_xFCR_xFEN);
766 regmap_write(esai_priv->regmap, REG_ESAI_SAICR, esai_priv->reg_cache[8]);
767 regmap_write(esai_priv->regmap, REG_ESAI_TCR, esai_priv->reg_cache[9] & ~ESAI_xCR_TE(6));
768 regmap_write(esai_priv->regmap, REG_ESAI_TCCR, esai_priv->reg_cache[10]);
769 regmap_write(esai_priv->regmap, REG_ESAI_RCR, esai_priv->reg_cache[11] & ~ESAI_xCR_RE(4));
770 regmap_write(esai_priv->regmap, REG_ESAI_RCCR, esai_priv->reg_cache[12]);
771 regmap_write(esai_priv->regmap, REG_ESAI_TSMA, esai_priv->reg_cache[13]);
772 regmap_write(esai_priv->regmap, REG_ESAI_TSMB, esai_priv->reg_cache[14]);
773 regmap_write(esai_priv->regmap, REG_ESAI_RSMA, esai_priv->reg_cache[15]);
774 regmap_write(esai_priv->regmap, REG_ESAI_RSMB, esai_priv->reg_cache[16]);
775
776 return 0;
777}
778
779static int stop_lock_stream(struct snd_pcm_substream *substream) 737static int stop_lock_stream(struct snd_pcm_substream *substream)
780{ 738{
781 if (substream) { 739 if (substream) {
@@ -822,15 +780,32 @@ static void fsl_esai_reset(struct snd_pcm_substream *substream, bool stop)
822 stop_lock_stream(esai_priv->substream[1]); 780 stop_lock_stream(esai_priv->substream[1]);
823 } 781 }
824 782
825 store_reg(cpu_dai);
826 783
827 regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN | ESAI_ECR_ERST); 784 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
828 regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN); 785 ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
786 ESAI_ECR_ESAIEN | ESAI_ECR_ERST);
787 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
788 ESAI_ECR_ESAIEN_MASK | ESAI_ECR_ERST_MASK,
789 ESAI_ECR_ESAIEN);
829 790
830 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, ESAI_xCR_xPR_MASK, ESAI_xCR_xPR); 791 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
831 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, ESAI_xCR_xPR_MASK, ESAI_xCR_xPR); 792 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, ESAI_xCR_xPR_MASK, ESAI_xCR_xPR);
832 793
833 restore_reg(cpu_dai); 794 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC, ESAI_PRRC_PDC_MASK, 0);
795 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC, ESAI_PCRC_PC_MASK, 0);
796
797 /*
798 * Add fifo reset here, because the regcache_sync will write one more data to ETDR.
799 * Which will cause channel shift.
800 */
801 regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
802 regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
803
804 regcache_mark_dirty(esai_priv->regmap);
805 regcache_sync(esai_priv->regmap);
806
807 regmap_update_bits(esai_priv->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR_MASK, 0);
808 regmap_update_bits(esai_priv->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR_MASK, 0);
834 809
835 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, ESAI_xCR_xPR_MASK, 0); 810 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, ESAI_xCR_xPR_MASK, 0);
836 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, ESAI_xCR_xPR_MASK, 0); 811 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, ESAI_xCR_xPR_MASK, 0);