diff options
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/pcm_lib.c | 2 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 25 | ||||
-rw-r--r-- | sound/core/timer.c | 16 |
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 | |||
2523 | static 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 | ||
2523 | static int snd_pcm_common_ioctl1(struct file *file, | 2538 | static 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 | ||
46 | static int timer_limit = DEFAULT_TIMER_LIMIT; | 46 | static int timer_limit = DEFAULT_TIMER_LIMIT; |
47 | static int timer_tstamp_monotonic = 1; | ||
47 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); | 48 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.de>"); |
48 | MODULE_DESCRIPTION("ALSA timer interface"); | 49 | MODULE_DESCRIPTION("ALSA timer interface"); |
49 | MODULE_LICENSE("GPL"); | 50 | MODULE_LICENSE("GPL"); |
50 | module_param(timer_limit, int, 0444); | 51 | module_param(timer_limit, int, 0444); |
51 | MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); | 52 | MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); |
53 | module_param(timer_tstamp_monotonic, int, 0444); | ||
54 | MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); | ||
52 | 55 | ||
53 | struct snd_timer_user { | 56 | struct 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; |