diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/sh/fsi.c | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 162416e3e6b4..cbb5643794b3 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -747,17 +747,14 @@ static void fsi_fifo_init(struct fsi_priv *fsi, | |||
747 | } | 747 | } |
748 | } | 748 | } |
749 | 749 | ||
750 | static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | 750 | static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io, |
751 | void (*run16)(struct fsi_priv *fsi, int size), | ||
752 | void (*run32)(struct fsi_priv *fsi, int size), | ||
753 | int samples) | ||
751 | { | 754 | { |
752 | struct snd_pcm_runtime *runtime; | 755 | struct snd_pcm_runtime *runtime; |
753 | struct snd_pcm_substream *substream = NULL; | 756 | struct snd_pcm_substream *substream; |
754 | int is_play = fsi_stream_is_play(stream); | ||
755 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | ||
756 | int sample_residues; | ||
757 | int samples; | ||
758 | int samples_max; | ||
759 | int over_period; | 757 | int over_period; |
760 | void (*fn)(struct fsi_priv *fsi, int size); | ||
761 | 758 | ||
762 | if (!fsi || | 759 | if (!fsi || |
763 | !io->substream || | 760 | !io->substream || |
@@ -781,57 +778,17 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
781 | io->buff_sample_pos = 0; | 778 | io->buff_sample_pos = 0; |
782 | } | 779 | } |
783 | 780 | ||
784 | /* get number of residue samples */ | 781 | switch (io->sample_width) { |
785 | sample_residues = io->buff_sample_capa - io->buff_sample_pos; | 782 | case 2: |
786 | 783 | run16(fsi, samples); | |
787 | if (is_play) { | 784 | break; |
788 | /* | 785 | case 4: |
789 | * for play-back | 786 | run32(fsi, samples); |
790 | * | 787 | break; |
791 | * samples_max : number of FSI fifo free samples space | 788 | default: |
792 | * samples : number of ALSA residue samples | 789 | return -EINVAL; |
793 | */ | ||
794 | samples_max = io->fifo_sample_capa; | ||
795 | samples_max -= fsi_get_current_fifo_samples(fsi, is_play); | ||
796 | |||
797 | samples = sample_residues; | ||
798 | |||
799 | switch (io->sample_width) { | ||
800 | case 2: | ||
801 | fn = fsi_dma_soft_push16; | ||
802 | break; | ||
803 | case 4: | ||
804 | fn = fsi_dma_soft_push32; | ||
805 | break; | ||
806 | default: | ||
807 | return -EINVAL; | ||
808 | } | ||
809 | } else { | ||
810 | /* | ||
811 | * for capture | ||
812 | * | ||
813 | * samples_max : number of ALSA free samples space | ||
814 | * samples : number of samples in FSI fifo | ||
815 | */ | ||
816 | samples_max = sample_residues; | ||
817 | samples = fsi_get_current_fifo_samples(fsi, is_play); | ||
818 | |||
819 | switch (io->sample_width) { | ||
820 | case 2: | ||
821 | fn = fsi_dma_soft_pop16; | ||
822 | break; | ||
823 | case 4: | ||
824 | fn = fsi_dma_soft_pop32; | ||
825 | break; | ||
826 | default: | ||
827 | return -EINVAL; | ||
828 | } | ||
829 | } | 790 | } |
830 | 791 | ||
831 | samples = min(samples, samples_max); | ||
832 | |||
833 | fn(fsi, samples); | ||
834 | |||
835 | /* update buff_sample_pos */ | 792 | /* update buff_sample_pos */ |
836 | io->buff_sample_pos += samples; | 793 | io->buff_sample_pos += samples; |
837 | 794 | ||
@@ -843,12 +800,41 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
843 | 800 | ||
844 | static int fsi_data_pop(struct fsi_priv *fsi) | 801 | static int fsi_data_pop(struct fsi_priv *fsi) |
845 | { | 802 | { |
846 | return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE); | 803 | int is_play = fsi_stream_is_play(SNDRV_PCM_STREAM_CAPTURE); |
804 | int sample_residues; /* samples in FSI fifo */ | ||
805 | int sample_space; /* ALSA free samples space */ | ||
806 | int samples; | ||
807 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | ||
808 | |||
809 | sample_residues = fsi_get_current_fifo_samples(fsi, is_play); | ||
810 | sample_space = io->buff_sample_capa - io->buff_sample_pos; | ||
811 | |||
812 | samples = min(sample_residues, sample_space); | ||
813 | |||
814 | return fsi_fifo_data_ctrl(fsi, io, | ||
815 | fsi_dma_soft_pop16, | ||
816 | fsi_dma_soft_pop32, | ||
817 | samples); | ||
847 | } | 818 | } |
848 | 819 | ||
849 | static int fsi_data_push(struct fsi_priv *fsi) | 820 | static int fsi_data_push(struct fsi_priv *fsi) |
850 | { | 821 | { |
851 | return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK); | 822 | int is_play = fsi_stream_is_play(SNDRV_PCM_STREAM_PLAYBACK); |
823 | int sample_residues; /* ALSA residue samples */ | ||
824 | int sample_space; /* FSI fifo free samples space */ | ||
825 | int samples; | ||
826 | struct fsi_stream *io = fsi_stream_get(fsi, is_play); | ||
827 | |||
828 | sample_residues = io->buff_sample_capa - io->buff_sample_pos; | ||
829 | sample_space = io->fifo_sample_capa - | ||
830 | fsi_get_current_fifo_samples(fsi, is_play); | ||
831 | |||
832 | samples = min(sample_residues, sample_space); | ||
833 | |||
834 | return fsi_fifo_data_ctrl(fsi, io, | ||
835 | fsi_dma_soft_push16, | ||
836 | fsi_dma_soft_push32, | ||
837 | samples); | ||
852 | } | 838 | } |
853 | 839 | ||
854 | static irqreturn_t fsi_interrupt(int irq, void *data) | 840 | static irqreturn_t fsi_interrupt(int irq, void *data) |