summaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_native.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2007-12-13 10:19:42 +0100
committerJaroslav Kysela <perex@perex.cz>2008-01-31 17:29:31 +0100
commitb751eef1fdffca5532344285f2fad0c60d2f0158 (patch)
treed504104c6315a8abc4b3f657f8f4828fb55a8795 /sound/core/pcm_native.c
parent25543fa785a32ce22e7374ba403eb6d38854d037 (diff)
[ALSA] Use posix clock monotonic for PCM and timer timestamps
We need an accurate and continuous (monotonic) time sources to do accurate synchronization among more timing sources. This patch allows to enable monotonic timestamps for ALSA PCM devices and enables monotonic timestamps for ALSA timer devices. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r--sound/core/pcm_native.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 6245bdaffa6..cdeae7c46e3 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -598,9 +598,9 @@ int snd_pcm_status(struct snd_pcm_substream *substream,
if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP)
status->tstamp = runtime->status->tstamp;
else
- getnstimeofday(&status->tstamp);
+ snd_pcm_gettime(runtime, &status->tstamp);
} else
- getnstimeofday(&status->tstamp);
+ snd_pcm_gettime(runtime, &status->tstamp);
status->appl_ptr = runtime->control->appl_ptr;
status->hw_ptr = runtime->status->hw_ptr;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -688,7 +688,7 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
if (runtime->trigger_master == NULL)
return;
if (runtime->trigger_master == substream) {
- getnstimeofday(&runtime->trigger_tstamp);
+ snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
} else {
snd_pcm_trigger_tstamp(runtime->trigger_master);
runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -2519,6 +2519,21 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
return -EFAULT;
return 0;
}
+
+static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int arg;
+
+ if (get_user(arg, _arg))
+ return -EFAULT;
+ if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
+ return -EINVAL;
+ runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
+ if (arg == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC)
+ runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
+ return 0;
+}
static int snd_pcm_common_ioctl1(struct file *file,
struct snd_pcm_substream *substream,
@@ -2531,8 +2546,8 @@ static int snd_pcm_common_ioctl1(struct file *file,
return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
case SNDRV_PCM_IOCTL_INFO:
return snd_pcm_info_user(substream, arg);
- case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
- return 0;
+ case SNDRV_PCM_IOCTL_TTSTAMP:
+ return snd_pcm_tstamp(substream, arg);
case SNDRV_PCM_IOCTL_HW_REFINE:
return snd_pcm_hw_refine_user(substream, arg);
case SNDRV_PCM_IOCTL_HW_PARAMS: