summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_lib.c2
-rw-r--r--sound/core/pcm_native.c25
-rw-r--r--sound/core/timer.c16
3 files changed, 34 insertions, 9 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 93d7ca502730..db3d7e934ec3 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -188,7 +188,7 @@ static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *subs
snd_pcm_sframes_t delta;
if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP)
- getnstimeofday((struct timespec *)&runtime->status->tstamp);
+ snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
if (pos == SNDRV_PCM_POS_XRUN) {
xrun(substream);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 6245bdaffa68..cdeae7c46e3b 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:
diff --git a/sound/core/timer.c b/sound/core/timer.c
index e7dc56ca4b97..7e5fe2d91662 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -44,11 +44,14 @@
#endif
static int timer_limit = DEFAULT_TIMER_LIMIT;
+static int timer_tstamp_monotonic = 1;
MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ALSA timer interface");
MODULE_LICENSE("GPL");
module_param(timer_limit, int, 0444);
MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
+module_param(timer_tstamp_monotonic, int, 0444);
+MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
struct snd_timer_user {
struct snd_timer_instance *timeri;
@@ -381,7 +384,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
struct snd_timer_instance *ts;
struct timespec tstamp;
- getnstimeofday(&tstamp);
+ if (timer_tstamp_monotonic)
+ do_posix_clock_monotonic_gettime(&tstamp);
+ else
+ getnstimeofday(&tstamp);
snd_assert(event >= SNDRV_TIMER_EVENT_START &&
event <= SNDRV_TIMER_EVENT_PAUSE, return);
if (event == SNDRV_TIMER_EVENT_START ||
@@ -1182,8 +1188,12 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
spin_unlock(&tu->qlock);
return;
}
- if (tu->last_resolution != resolution || ticks > 0)
- getnstimeofday(&tstamp);
+ if (tu->last_resolution != resolution || ticks > 0) {
+ if (timer_tstamp_monotonic)
+ do_posix_clock_monotonic_gettime(&tstamp);
+ else
+ getnstimeofday(&tstamp);
+ }
if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
tu->last_resolution != resolution) {
r1.event = SNDRV_TIMER_EVENT_RESOLUTION;