aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2015-02-06 16:55:53 -0500
committerTakashi Iwai <tiwai@suse.de>2015-02-09 10:02:43 -0500
commitea33d359c4421f369443f6fee92a1e893541eb73 (patch)
treefb4894cc8b73df8929f36d746dc14367831060ce
parented610af86a717152be5aa5e29410c5183992b4f2 (diff)
ALSA: usb: update trigger timestamp on first non-zero URB submitted
The first URBs are submitted during the prepare stage. When .trigger is called, the ALSA core saves a trigger tstamp that doesn't correspond to the actual time when the samples are submitted. The trigger_tstamp is now updated when the first data are submitted to avoid any time offsets. A usb-specific trigger_tstamp_pending_update flag is used for now, at some point the flag would need to move to the ALSA core, USB is not the only interface where silent block transfers are programmed as part of the prepare stage, with actual data enabled when .trigger is called. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/card.h2
-rw-r--r--sound/usb/pcm.c9
2 files changed, 11 insertions, 0 deletions
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 97acb906acc2..ef580b43f1e3 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -153,6 +153,8 @@ struct snd_usb_substream {
153 int channel; 153 int channel;
154 int byte_idx; 154 int byte_idx;
155 } dsd_dop; 155 } dsd_dop;
156
157 bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */
156}; 158};
157 159
158struct snd_usb_stream { 160struct snd_usb_stream {
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 0d8aba5fe1a8..b4ef410e5a98 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1464,6 +1464,14 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
1464 subs->last_frame_number = usb_get_current_frame_number(subs->dev); 1464 subs->last_frame_number = usb_get_current_frame_number(subs->dev);
1465 subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ 1465 subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
1466 1466
1467 if (subs->trigger_tstamp_pending_update) {
1468 /* this is the first actual URB submitted,
1469 * update trigger timestamp to reflect actual start time
1470 */
1471 snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
1472 subs->trigger_tstamp_pending_update = false;
1473 }
1474
1467 spin_unlock_irqrestore(&subs->lock, flags); 1475 spin_unlock_irqrestore(&subs->lock, flags);
1468 urb->transfer_buffer_length = bytes; 1476 urb->transfer_buffer_length = bytes;
1469 if (period_elapsed) 1477 if (period_elapsed)
@@ -1550,6 +1558,7 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
1550 1558
1551 switch (cmd) { 1559 switch (cmd) {
1552 case SNDRV_PCM_TRIGGER_START: 1560 case SNDRV_PCM_TRIGGER_START:
1561 subs->trigger_tstamp_pending_update = true;
1553 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1562 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1554 subs->data_endpoint->prepare_data_urb = prepare_playback_urb; 1563 subs->data_endpoint->prepare_data_urb = prepare_playback_urb;
1555 subs->data_endpoint->retire_data_urb = retire_playback_urb; 1564 subs->data_endpoint->retire_data_urb = retire_playback_urb;