diff options
Diffstat (limited to 'sound/soc/pxa/pxa-ssp.c')
-rw-r--r-- | sound/soc/pxa/pxa-ssp.c | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a16df0fa6eff..fd04ce139031 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -668,6 +668,38 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
668 | return 0; | 668 | return 0; |
669 | } | 669 | } |
670 | 670 | ||
671 | static void pxa_ssp_set_running_bit(struct snd_pcm_substream *substream, | ||
672 | struct ssp_device *ssp, int value) | ||
673 | { | ||
674 | uint32_t sscr0 = pxa_ssp_read_reg(ssp, SSCR0); | ||
675 | uint32_t sscr1 = pxa_ssp_read_reg(ssp, SSCR1); | ||
676 | uint32_t sspsp = pxa_ssp_read_reg(ssp, SSPSP); | ||
677 | uint32_t sssr = pxa_ssp_read_reg(ssp, SSSR); | ||
678 | |||
679 | if (value && (sscr0 & SSCR0_SSE)) | ||
680 | pxa_ssp_write_reg(ssp, SSCR0, sscr0 & ~SSCR0_SSE); | ||
681 | |||
682 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
683 | if (value) | ||
684 | sscr1 |= SSCR1_TSRE; | ||
685 | else | ||
686 | sscr1 &= ~SSCR1_TSRE; | ||
687 | } else { | ||
688 | if (value) | ||
689 | sscr1 |= SSCR1_RSRE; | ||
690 | else | ||
691 | sscr1 &= ~SSCR1_RSRE; | ||
692 | } | ||
693 | |||
694 | pxa_ssp_write_reg(ssp, SSCR1, sscr1); | ||
695 | |||
696 | if (value) { | ||
697 | pxa_ssp_write_reg(ssp, SSSR, sssr); | ||
698 | pxa_ssp_write_reg(ssp, SSPSP, sspsp); | ||
699 | pxa_ssp_write_reg(ssp, SSCR0, sscr0 | SSCR0_SSE); | ||
700 | } | ||
701 | } | ||
702 | |||
671 | static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, | 703 | static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, |
672 | struct snd_soc_dai *cpu_dai) | 704 | struct snd_soc_dai *cpu_dai) |
673 | { | 705 | { |
@@ -681,42 +713,21 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, | |||
681 | pxa_ssp_enable(ssp); | 713 | pxa_ssp_enable(ssp); |
682 | break; | 714 | break; |
683 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 715 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
684 | val = pxa_ssp_read_reg(ssp, SSCR1); | 716 | pxa_ssp_set_running_bit(substream, ssp, 1); |
685 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
686 | val |= SSCR1_TSRE; | ||
687 | else | ||
688 | val |= SSCR1_RSRE; | ||
689 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
690 | val = pxa_ssp_read_reg(ssp, SSSR); | 717 | val = pxa_ssp_read_reg(ssp, SSSR); |
691 | pxa_ssp_write_reg(ssp, SSSR, val); | 718 | pxa_ssp_write_reg(ssp, SSSR, val); |
692 | break; | 719 | break; |
693 | case SNDRV_PCM_TRIGGER_START: | 720 | case SNDRV_PCM_TRIGGER_START: |
694 | val = pxa_ssp_read_reg(ssp, SSCR1); | 721 | pxa_ssp_set_running_bit(substream, ssp, 1); |
695 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
696 | val |= SSCR1_TSRE; | ||
697 | else | ||
698 | val |= SSCR1_RSRE; | ||
699 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
700 | pxa_ssp_enable(ssp); | ||
701 | break; | 722 | break; |
702 | case SNDRV_PCM_TRIGGER_STOP: | 723 | case SNDRV_PCM_TRIGGER_STOP: |
703 | val = pxa_ssp_read_reg(ssp, SSCR1); | 724 | pxa_ssp_set_running_bit(substream, ssp, 0); |
704 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
705 | val &= ~SSCR1_TSRE; | ||
706 | else | ||
707 | val &= ~SSCR1_RSRE; | ||
708 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
709 | break; | 725 | break; |
710 | case SNDRV_PCM_TRIGGER_SUSPEND: | 726 | case SNDRV_PCM_TRIGGER_SUSPEND: |
711 | pxa_ssp_disable(ssp); | 727 | pxa_ssp_disable(ssp); |
712 | break; | 728 | break; |
713 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 729 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
714 | val = pxa_ssp_read_reg(ssp, SSCR1); | 730 | pxa_ssp_set_running_bit(substream, ssp, 0); |
715 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
716 | val &= ~SSCR1_TSRE; | ||
717 | else | ||
718 | val &= ~SSCR1_RSRE; | ||
719 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
720 | break; | 731 | break; |
721 | 732 | ||
722 | default: | 733 | default: |