aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/oss/pcm_oss.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/oss/pcm_oss.c')
-rw-r--r--sound/core/oss/pcm_oss.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index d9c96353121a..82d4e3329b3d 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -632,6 +632,12 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes); 632 return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
633} 633}
634 634
635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{
638 return runtime->hw_ptr_interrupt;
639}
640
635/* define extended formats in the recent OSS versions (if any) */ 641/* define extended formats in the recent OSS versions (if any) */
636/* linear formats */ 642/* linear formats */
637#define AFMT_S32_LE 0x00001000 643#define AFMT_S32_LE 0x00001000
@@ -1102,7 +1108,7 @@ static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1102 return err; 1108 return err;
1103 } 1109 }
1104 runtime->oss.prepare = 0; 1110 runtime->oss.prepare = 0;
1105 runtime->oss.prev_hw_ptr_interrupt = 0; 1111 runtime->oss.prev_hw_ptr_period = 0;
1106 runtime->oss.period_ptr = 0; 1112 runtime->oss.period_ptr = 0;
1107 runtime->oss.buffer_used = 0; 1113 runtime->oss.buffer_used = 0;
1108 1114
@@ -1950,7 +1956,8 @@ static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1950 return result; 1956 return result;
1951} 1957}
1952 1958
1953static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr) 1959static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1960 snd_pcm_uframes_t hw_ptr)
1954{ 1961{
1955 struct snd_pcm_runtime *runtime = substream->runtime; 1962 struct snd_pcm_runtime *runtime = substream->runtime;
1956 snd_pcm_uframes_t appl_ptr; 1963 snd_pcm_uframes_t appl_ptr;
@@ -1986,7 +1993,8 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1986 if (runtime->oss.trigger) 1993 if (runtime->oss.trigger)
1987 goto _skip1; 1994 goto _skip1;
1988 if (atomic_read(&psubstream->mmap_count)) 1995 if (atomic_read(&psubstream->mmap_count))
1989 snd_pcm_oss_simulate_fill(psubstream, runtime->hw_ptr_interrupt); 1996 snd_pcm_oss_simulate_fill(psubstream,
1997 get_hw_ptr_period(runtime));
1990 runtime->oss.trigger = 1; 1998 runtime->oss.trigger = 1;
1991 runtime->start_threshold = 1; 1999 runtime->start_threshold = 1;
1992 cmd = SNDRV_PCM_IOCTL_START; 2000 cmd = SNDRV_PCM_IOCTL_START;
@@ -2105,11 +2113,12 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream
2105 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); 2113 info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2106 if (atomic_read(&substream->mmap_count)) { 2114 if (atomic_read(&substream->mmap_count)) {
2107 snd_pcm_sframes_t n; 2115 snd_pcm_sframes_t n;
2108 n = (delay = runtime->hw_ptr_interrupt) - runtime->oss.prev_hw_ptr_interrupt; 2116 delay = get_hw_ptr_period(runtime);
2117 n = delay - runtime->oss.prev_hw_ptr_period;
2109 if (n < 0) 2118 if (n < 0)
2110 n += runtime->boundary; 2119 n += runtime->boundary;
2111 info.blocks = n / runtime->period_size; 2120 info.blocks = n / runtime->period_size;
2112 runtime->oss.prev_hw_ptr_interrupt = delay; 2121 runtime->oss.prev_hw_ptr_period = delay;
2113 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 2122 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2114 snd_pcm_oss_simulate_fill(substream, delay); 2123 snd_pcm_oss_simulate_fill(substream, delay);
2115 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX; 2124 info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
@@ -2673,18 +2682,22 @@ static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2673{ 2682{
2674 struct snd_pcm_runtime *runtime = substream->runtime; 2683 struct snd_pcm_runtime *runtime = substream->runtime;
2675 if (atomic_read(&substream->mmap_count)) 2684 if (atomic_read(&substream->mmap_count))
2676 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2685 return runtime->oss.prev_hw_ptr_period !=
2686 get_hw_ptr_period(runtime);
2677 else 2687 else
2678 return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames; 2688 return snd_pcm_playback_avail(runtime) >=
2689 runtime->oss.period_frames;
2679} 2690}
2680 2691
2681static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream) 2692static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2682{ 2693{
2683 struct snd_pcm_runtime *runtime = substream->runtime; 2694 struct snd_pcm_runtime *runtime = substream->runtime;
2684 if (atomic_read(&substream->mmap_count)) 2695 if (atomic_read(&substream->mmap_count))
2685 return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt; 2696 return runtime->oss.prev_hw_ptr_period !=
2697 get_hw_ptr_period(runtime);
2686 else 2698 else
2687 return snd_pcm_capture_avail(runtime) >= runtime->oss.period_frames; 2699 return snd_pcm_capture_avail(runtime) >=
2700 runtime->oss.period_frames;
2688} 2701}
2689 2702
2690static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) 2703static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)