diff options
author | Shengjiu Wang <b02247@freescale.com> | 2014-06-23 06:52:02 -0400 |
---|---|---|
committer | Shengjiu Wang <b02247@freescale.com> | 2014-06-24 03:52:29 -0400 |
commit | 27c369795208a9a0e4a275655a2e479a762c47ed (patch) | |
tree | c19481d1336735fa183ab0e5f0db9c4724951829 /sound/soc/fsl | |
parent | 6dd40bb4a070adaced87a51ce231336334541692 (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.c | 67 |
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 | ||
70 | static irqreturn_t esai_isr(int irq, void *devid) | 68 | static 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 | ||
739 | static 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 | |||
759 | static 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 | |||
779 | static int stop_lock_stream(struct snd_pcm_substream *substream) | 737 | static 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); |