aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-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
188 snd_pcm_sframes_t delta; 188 snd_pcm_sframes_t delta;
189 189
190 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP) 190 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP)
191 getnstimeofday((struct timespec *)&runtime->status->tstamp); 191 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
192 pos = snd_pcm_update_hw_ptr_pos(substream, runtime); 192 pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
193 if (pos == SNDRV_PCM_POS_XRUN) { 193 if (pos == SNDRV_PCM_POS_XRUN) {
194 xrun(substream); 194 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,
598 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP) 598 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_MMAP)
599 status->tstamp = runtime->status->tstamp; 599 status->tstamp = runtime->status->tstamp;
600 else 600 else
601 getnstimeofday(&status->tstamp); 601 snd_pcm_gettime(runtime, &status->tstamp);
602 } else 602 } else
603 getnstimeofday(&status->tstamp); 603 snd_pcm_gettime(runtime, &status->tstamp);
604 status->appl_ptr = runtime->control->appl_ptr; 604 status->appl_ptr = runtime->control->appl_ptr;
605 status->hw_ptr = runtime->status->hw_ptr; 605 status->hw_ptr = runtime->status->hw_ptr;
606 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 606 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -688,7 +688,7 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
688 if (runtime->trigger_master == NULL) 688 if (runtime->trigger_master == NULL)
689 return; 689 return;
690 if (runtime->trigger_master == substream) { 690 if (runtime->trigger_master == substream) {
691 getnstimeofday(&runtime->trigger_tstamp); 691 snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
692 } else { 692 } else {
693 snd_pcm_trigger_tstamp(runtime->trigger_master); 693 snd_pcm_trigger_tstamp(runtime->trigger_master);
694 runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp; 694 runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@@ -2519,6 +2519,21 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2519 return -EFAULT; 2519 return -EFAULT;
2520 return 0; 2520 return 0;
2521} 2521}
2522
2523static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
2524{
2525 struct snd_pcm_runtime *runtime = substream->runtime;
2526 int arg;
2527
2528 if (get_user(arg, _arg))
2529 return -EFAULT;
2530 if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
2531 return -EINVAL;
2532 runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY;
2533 if (arg == SNDRV_PCM_TSTAMP_TYPE_MONOTONIC)
2534 runtime->tstamp_type = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC;
2535 return 0;
2536}
2522 2537
2523static int snd_pcm_common_ioctl1(struct file *file, 2538static int snd_pcm_common_ioctl1(struct file *file,
2524 struct snd_pcm_substream *substream, 2539 struct snd_pcm_substream *substream,
@@ -2531,8 +2546,8 @@ static int snd_pcm_common_ioctl1(struct file *file,
2531 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; 2546 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
2532 case SNDRV_PCM_IOCTL_INFO: 2547 case SNDRV_PCM_IOCTL_INFO:
2533 return snd_pcm_info_user(substream, arg); 2548 return snd_pcm_info_user(substream, arg);
2534 case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */ 2549 case SNDRV_PCM_IOCTL_TTSTAMP:
2535 return 0; 2550 return snd_pcm_tstamp(substream, arg);
2536 case SNDRV_PCM_IOCTL_HW_REFINE: 2551 case SNDRV_PCM_IOCTL_HW_REFINE:
2537 return snd_pcm_hw_refine_user(substream, arg); 2552 return snd_pcm_hw_refine_user(substream, arg);
2538 case SNDRV_PCM_IOCTL_HW_PARAMS: 2553 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 @@
44#endif 44#endif
45 45
46static int timer_limit = DEFAULT_TIMER_LIMIT; 46static int timer_limit = DEFAULT_TIMER_LIMIT;
47static int timer_tstamp_monotonic = 1;
47MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); 48MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>");
48MODULE_DESCRIPTION("ALSA timer interface"); 49MODULE_DESCRIPTION("ALSA timer interface");
49MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
50module_param(timer_limit, int, 0444); 51module_param(timer_limit, int, 0444);
51MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); 52MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
53module_param(timer_tstamp_monotonic, int, 0444);
54MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
52 55
53struct snd_timer_user { 56struct snd_timer_user {
54 struct snd_timer_instance *timeri; 57 struct snd_timer_instance *timeri;
@@ -381,7 +384,10 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
381 struct snd_timer_instance *ts; 384 struct snd_timer_instance *ts;
382 struct timespec tstamp; 385 struct timespec tstamp;
383 386
384 getnstimeofday(&tstamp); 387 if (timer_tstamp_monotonic)
388 do_posix_clock_monotonic_gettime(&tstamp);
389 else
390 getnstimeofday(&tstamp);
385 snd_assert(event >= SNDRV_TIMER_EVENT_START && 391 snd_assert(event >= SNDRV_TIMER_EVENT_START &&
386 event <= SNDRV_TIMER_EVENT_PAUSE, return); 392 event <= SNDRV_TIMER_EVENT_PAUSE, return);
387 if (event == SNDRV_TIMER_EVENT_START || 393 if (event == SNDRV_TIMER_EVENT_START ||
@@ -1182,8 +1188,12 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
1182 spin_unlock(&tu->qlock); 1188 spin_unlock(&tu->qlock);
1183 return; 1189 return;
1184 } 1190 }
1185 if (tu->last_resolution != resolution || ticks > 0) 1191 if (tu->last_resolution != resolution || ticks > 0) {
1186 getnstimeofday(&tstamp); 1192 if (timer_tstamp_monotonic)
1193 do_posix_clock_monotonic_gettime(&tstamp);
1194 else
1195 getnstimeofday(&tstamp);
1196 }
1187 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1197 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
1188 tu->last_resolution != resolution) { 1198 tu->last_resolution != resolution) {
1189 r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1199 r1.event = SNDRV_TIMER_EVENT_RESOLUTION;