Sound fixes for 3.6-rc5
There are nothing scaring, contains only small fixes for HD-audio and USB-audio: - EPSS regression fix and GPIO fix for HD-audio IDT codecs - A series of USB-audio regression fixes that are found since 3.5 kernel -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJQRZeCAAoJEGwxgFQ9KSmkPikP/2ZpK3xvf1WnEJT+K+2ErsI+ KEChW70QNRcghvbOa0viUx6v3B8tkPhDuo6YgTIjiP+yde0BjVujSXYAOvznvHxy ea8xX7hR0j0G9y0FVb0oYlj+CIZWupChz9V2uSB7EudMvYPUBUzkkDtrpsb4+t3z 0e/4VEEkWIVhVyuPEnaL8fdzYPLs7UA6/QotC/SLxnFSmbaGvUuryssEmb99vl0h xQHr8FuIF12DTS1ZwdCYcL9VTFriXcYeIWf+ThaoY3evSeStCUuboHf69RUy1WR9 JAn0hArI358m/Xicmr6pG6y0VqIPqfFLgsjXgt8/Fe0ljTcYbXoWL09MXVSL40wA 2jFWAizPe8/OAASHpgzWNb/8WWDFL/XWoeefSwL1lOIArlZhe07b61bA69s2GG0k /rwZn058ZgQCgqC5Dph7RD7squ0ANg6WIq8obdJevLgekw/MCkKUPNA6N2lXjboT KaKEouLUff72A2WKiE7W6ykNATWjqteDe7+11HhDC543lAKBnq/Zyv8zjsqhzPuU TnxA0W1pcfc4GLRBaedIH2AeEzQc/aT0RE79sGGzPSB4SG0MLTRWT3yUXMiVTeWB vBb4ZuEvGeo6i81QovIN/y1m/kEljaSu7uSi0Kzopq663HsUEvJ1BvLAviZsJZ01 pSNAne3Ze7kWQwyWkVDQ =AbfN -----END PGP SIGNATURE----- Merge tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "There are nothing scaring, contains only small fixes for HD-audio and USB-audio: - EPSS regression fix and GPIO fix for HD-audio IDT codecs - A series of USB-audio regression fixes that are found since 3.5 kernel" * tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: snd-usb: fix cross-interface streaming devices ALSA: snd-usb: fix calls to next_packet_size ALSA: snd-usb: restore delay information ALSA: snd-usb: use list_for_each_safe for endpoint resources ALSA: snd-usb: Fix URB cancellation at stream start ALSA: hda - Don't trust codec EPSS bit for IDT 92HD83xx & co ALSA: hda - Avoid unnecessary parameter read for EPSS ALSA: hda - Do not set GPIOs for speakers on IDT if there are no speakers
This commit is contained in:
commit
5e682c0e54
|
@ -1209,6 +1209,9 @@ static void snd_hda_codec_free(struct hda_codec *codec)
|
||||||
kfree(codec);
|
kfree(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
|
||||||
|
hda_nid_t fg, unsigned int power_state);
|
||||||
|
|
||||||
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
||||||
unsigned int power_state);
|
unsigned int power_state);
|
||||||
|
|
||||||
|
@ -1317,6 +1320,10 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
|
||||||
AC_VERB_GET_SUBSYSTEM_ID, 0);
|
AC_VERB_GET_SUBSYSTEM_ID, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codec->epss = snd_hda_codec_get_supported_ps(codec,
|
||||||
|
codec->afg ? codec->afg : codec->mfg,
|
||||||
|
AC_PWRST_EPSS);
|
||||||
|
|
||||||
/* power-up all before initialization */
|
/* power-up all before initialization */
|
||||||
hda_set_power_state(codec,
|
hda_set_power_state(codec,
|
||||||
codec->afg ? codec->afg : codec->mfg,
|
codec->afg ? codec->afg : codec->mfg,
|
||||||
|
@ -3543,8 +3550,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
||||||
/* this delay seems necessary to avoid click noise at power-down */
|
/* this delay seems necessary to avoid click noise at power-down */
|
||||||
if (power_state == AC_PWRST_D3) {
|
if (power_state == AC_PWRST_D3) {
|
||||||
/* transition time less than 10ms for power down */
|
/* transition time less than 10ms for power down */
|
||||||
bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS);
|
msleep(codec->epss ? 10 : 100);
|
||||||
msleep(epss ? 10 : 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* repeat power states setting at most 10 times*/
|
/* repeat power states setting at most 10 times*/
|
||||||
|
|
|
@ -862,6 +862,7 @@ struct hda_codec {
|
||||||
unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
|
unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
|
||||||
unsigned int no_jack_detect:1; /* Machine has no jack-detection */
|
unsigned int no_jack_detect:1; /* Machine has no jack-detection */
|
||||||
unsigned int pcm_format_first:1; /* PCM format must be set first */
|
unsigned int pcm_format_first:1; /* PCM format must be set first */
|
||||||
|
unsigned int epss:1; /* supporting EPSS? */
|
||||||
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
#ifdef CONFIG_SND_HDA_POWER_SAVE
|
||||||
unsigned int power_on :1; /* current (global) power-state */
|
unsigned int power_on :1; /* current (global) power-state */
|
||||||
int power_transition; /* power-state in transition */
|
int power_transition; /* power-state in transition */
|
||||||
|
|
|
@ -4543,6 +4543,9 @@ static void stac92xx_line_out_detect(struct hda_codec *codec,
|
||||||
struct auto_pin_cfg *cfg = &spec->autocfg;
|
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (cfg->speaker_outs == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < cfg->line_outs; i++) {
|
for (i = 0; i < cfg->line_outs; i++) {
|
||||||
if (presence)
|
if (presence)
|
||||||
break;
|
break;
|
||||||
|
@ -5531,6 +5534,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
|
||||||
snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
|
snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codec->epss = 0; /* longer delay needed for D3 */
|
||||||
codec->no_trigger_sense = 1;
|
codec->no_trigger_sense = 1;
|
||||||
codec->spec = spec;
|
codec->spec = spec;
|
||||||
|
|
||||||
|
|
|
@ -553,7 +553,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
|
||||||
struct snd_usb_audio *chip)
|
struct snd_usb_audio *chip)
|
||||||
{
|
{
|
||||||
struct snd_card *card;
|
struct snd_card *card;
|
||||||
struct list_head *p;
|
struct list_head *p, *n;
|
||||||
|
|
||||||
if (chip == (void *)-1L)
|
if (chip == (void *)-1L)
|
||||||
return;
|
return;
|
||||||
|
@ -570,7 +570,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev,
|
||||||
snd_usb_stream_disconnect(p);
|
snd_usb_stream_disconnect(p);
|
||||||
}
|
}
|
||||||
/* release the endpoint resources */
|
/* release the endpoint resources */
|
||||||
list_for_each(p, &chip->ep_list) {
|
list_for_each_safe(p, n, &chip->ep_list) {
|
||||||
snd_usb_endpoint_free(p);
|
snd_usb_endpoint_free(p);
|
||||||
}
|
}
|
||||||
/* release the midi resources */
|
/* release the midi resources */
|
||||||
|
|
|
@ -141,7 +141,7 @@ int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep)
|
||||||
*
|
*
|
||||||
* For implicit feedback, next_packet_size() is unused.
|
* For implicit feedback, next_packet_size() is unused.
|
||||||
*/
|
*/
|
||||||
static int next_packet_size(struct snd_usb_endpoint *ep)
|
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -177,15 +177,6 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,
|
||||||
ep->retire_data_urb(ep->data_subs, urb);
|
ep->retire_data_urb(ep->data_subs, urb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_outbound_urb_sizes(struct snd_usb_endpoint *ep,
|
|
||||||
struct snd_urb_ctx *ctx)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ctx->packets; ++i)
|
|
||||||
ctx->packet_size[i] = next_packet_size(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare a PLAYBACK urb for submission to the bus.
|
* Prepare a PLAYBACK urb for submission to the bus.
|
||||||
*/
|
*/
|
||||||
|
@ -370,7 +361,6 @@ static void snd_complete_urb(struct urb *urb)
|
||||||
goto exit_clear;
|
goto exit_clear;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare_outbound_urb_sizes(ep, ctx);
|
|
||||||
prepare_outbound_urb(ep, ctx);
|
prepare_outbound_urb(ep, ctx);
|
||||||
} else {
|
} else {
|
||||||
retire_inbound_urb(ep, ctx);
|
retire_inbound_urb(ep, ctx);
|
||||||
|
@ -799,7 +789,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
|
||||||
/**
|
/**
|
||||||
* snd_usb_endpoint_start: start an snd_usb_endpoint
|
* snd_usb_endpoint_start: start an snd_usb_endpoint
|
||||||
*
|
*
|
||||||
* @ep: the endpoint to start
|
* @ep: the endpoint to start
|
||||||
|
* @can_sleep: flag indicating whether the operation is executed in
|
||||||
|
* non-atomic context
|
||||||
*
|
*
|
||||||
* A call to this function will increment the use count of the endpoint.
|
* A call to this function will increment the use count of the endpoint.
|
||||||
* In case it is not already running, the URBs for this endpoint will be
|
* In case it is not already running, the URBs for this endpoint will be
|
||||||
|
@ -809,7 +801,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
|
||||||
*
|
*
|
||||||
* Returns an error if the URB submission failed, 0 in all other cases.
|
* Returns an error if the URB submission failed, 0 in all other cases.
|
||||||
*/
|
*/
|
||||||
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
|
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -821,6 +813,11 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
|
||||||
if (++ep->use_count != 1)
|
if (++ep->use_count != 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* just to be sure */
|
||||||
|
deactivate_urbs(ep, 0, can_sleep);
|
||||||
|
if (can_sleep)
|
||||||
|
wait_clear_urbs(ep);
|
||||||
|
|
||||||
ep->active_mask = 0;
|
ep->active_mask = 0;
|
||||||
ep->unlink_mask = 0;
|
ep->unlink_mask = 0;
|
||||||
ep->phase = 0;
|
ep->phase = 0;
|
||||||
|
@ -850,7 +847,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
|
||||||
goto __error;
|
goto __error;
|
||||||
|
|
||||||
if (usb_pipeout(ep->pipe)) {
|
if (usb_pipeout(ep->pipe)) {
|
||||||
prepare_outbound_urb_sizes(ep, urb->context);
|
|
||||||
prepare_outbound_urb(ep, urb->context);
|
prepare_outbound_urb(ep, urb->context);
|
||||||
} else {
|
} else {
|
||||||
prepare_inbound_urb(ep, urb->context);
|
prepare_inbound_urb(ep, urb->context);
|
||||||
|
|
|
@ -13,7 +13,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
|
||||||
struct audioformat *fmt,
|
struct audioformat *fmt,
|
||||||
struct snd_usb_endpoint *sync_ep);
|
struct snd_usb_endpoint *sync_ep);
|
||||||
|
|
||||||
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep);
|
int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
|
||||||
void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
|
void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
|
||||||
int force, int can_sleep, int wait);
|
int force, int can_sleep, int wait);
|
||||||
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
|
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
|
||||||
|
@ -21,6 +21,7 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
|
||||||
void snd_usb_endpoint_free(struct list_head *head);
|
void snd_usb_endpoint_free(struct list_head *head);
|
||||||
|
|
||||||
int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep);
|
int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep);
|
||||||
|
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);
|
||||||
|
|
||||||
void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
|
void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
|
||||||
struct snd_usb_endpoint *sender,
|
struct snd_usb_endpoint *sender,
|
||||||
|
|
|
@ -212,7 +212,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start_endpoints(struct snd_usb_substream *subs)
|
static int start_endpoints(struct snd_usb_substream *subs, int can_sleep)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ static int start_endpoints(struct snd_usb_substream *subs)
|
||||||
snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep);
|
snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep);
|
||||||
|
|
||||||
ep->data_subs = subs;
|
ep->data_subs = subs;
|
||||||
err = snd_usb_endpoint_start(ep);
|
err = snd_usb_endpoint_start(ep, can_sleep);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);
|
clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);
|
||||||
return err;
|
return err;
|
||||||
|
@ -236,10 +236,25 @@ static int start_endpoints(struct snd_usb_substream *subs)
|
||||||
!test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) {
|
!test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) {
|
||||||
struct snd_usb_endpoint *ep = subs->sync_endpoint;
|
struct snd_usb_endpoint *ep = subs->sync_endpoint;
|
||||||
|
|
||||||
|
if (subs->data_endpoint->iface != subs->sync_endpoint->iface ||
|
||||||
|
subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) {
|
||||||
|
err = usb_set_interface(subs->dev,
|
||||||
|
subs->sync_endpoint->iface,
|
||||||
|
subs->sync_endpoint->alt_idx);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_printk(KERN_ERR
|
||||||
|
"%d:%d:%d: cannot set interface (%d)\n",
|
||||||
|
subs->dev->devnum,
|
||||||
|
subs->sync_endpoint->iface,
|
||||||
|
subs->sync_endpoint->alt_idx, err);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep);
|
snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep);
|
||||||
|
|
||||||
ep->sync_slave = subs->data_endpoint;
|
ep->sync_slave = subs->data_endpoint;
|
||||||
err = snd_usb_endpoint_start(ep);
|
err = snd_usb_endpoint_start(ep, can_sleep);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
|
clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
|
||||||
return err;
|
return err;
|
||||||
|
@ -544,13 +559,10 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
|
||||||
subs->last_frame_number = 0;
|
subs->last_frame_number = 0;
|
||||||
runtime->delay = 0;
|
runtime->delay = 0;
|
||||||
|
|
||||||
/* clear the pending deactivation on the target EPs */
|
|
||||||
deactivate_endpoints(subs);
|
|
||||||
|
|
||||||
/* for playback, submit the URBs now; otherwise, the first hwptr_done
|
/* for playback, submit the URBs now; otherwise, the first hwptr_done
|
||||||
* updates for all URBs would happen at the same time when starting */
|
* updates for all URBs would happen at the same time when starting */
|
||||||
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
|
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
|
||||||
return start_endpoints(subs);
|
return start_endpoints(subs, 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1032,6 +1044,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
|
||||||
struct urb *urb)
|
struct urb *urb)
|
||||||
{
|
{
|
||||||
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
|
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
|
||||||
|
struct snd_usb_endpoint *ep = subs->data_endpoint;
|
||||||
struct snd_urb_ctx *ctx = urb->context;
|
struct snd_urb_ctx *ctx = urb->context;
|
||||||
unsigned int counts, frames, bytes;
|
unsigned int counts, frames, bytes;
|
||||||
int i, stride, period_elapsed = 0;
|
int i, stride, period_elapsed = 0;
|
||||||
|
@ -1043,7 +1056,11 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
|
||||||
urb->number_of_packets = 0;
|
urb->number_of_packets = 0;
|
||||||
spin_lock_irqsave(&subs->lock, flags);
|
spin_lock_irqsave(&subs->lock, flags);
|
||||||
for (i = 0; i < ctx->packets; i++) {
|
for (i = 0; i < ctx->packets; i++) {
|
||||||
counts = ctx->packet_size[i];
|
if (ctx->packet_size[i])
|
||||||
|
counts = ctx->packet_size[i];
|
||||||
|
else
|
||||||
|
counts = snd_usb_endpoint_next_packet_size(ep);
|
||||||
|
|
||||||
/* set up descriptor */
|
/* set up descriptor */
|
||||||
urb->iso_frame_desc[i].offset = frames * stride;
|
urb->iso_frame_desc[i].offset = frames * stride;
|
||||||
urb->iso_frame_desc[i].length = counts * stride;
|
urb->iso_frame_desc[i].length = counts * stride;
|
||||||
|
@ -1094,7 +1111,16 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
|
||||||
subs->hwptr_done += bytes;
|
subs->hwptr_done += bytes;
|
||||||
if (subs->hwptr_done >= runtime->buffer_size * stride)
|
if (subs->hwptr_done >= runtime->buffer_size * stride)
|
||||||
subs->hwptr_done -= runtime->buffer_size * stride;
|
subs->hwptr_done -= runtime->buffer_size * stride;
|
||||||
|
|
||||||
|
/* update delay with exact number of samples queued */
|
||||||
|
runtime->delay = subs->last_delay;
|
||||||
runtime->delay += frames;
|
runtime->delay += frames;
|
||||||
|
subs->last_delay = runtime->delay;
|
||||||
|
|
||||||
|
/* realign last_frame_number */
|
||||||
|
subs->last_frame_number = usb_get_current_frame_number(subs->dev);
|
||||||
|
subs->last_frame_number &= 0xFF; /* keep 8 LSBs */
|
||||||
|
|
||||||
spin_unlock_irqrestore(&subs->lock, flags);
|
spin_unlock_irqrestore(&subs->lock, flags);
|
||||||
urb->transfer_buffer_length = bytes;
|
urb->transfer_buffer_length = bytes;
|
||||||
if (period_elapsed)
|
if (period_elapsed)
|
||||||
|
@ -1112,12 +1138,26 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
|
||||||
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
|
struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
|
||||||
int stride = runtime->frame_bits >> 3;
|
int stride = runtime->frame_bits >> 3;
|
||||||
int processed = urb->transfer_buffer_length / stride;
|
int processed = urb->transfer_buffer_length / stride;
|
||||||
|
int est_delay;
|
||||||
|
|
||||||
spin_lock_irqsave(&subs->lock, flags);
|
spin_lock_irqsave(&subs->lock, flags);
|
||||||
if (processed > runtime->delay)
|
est_delay = snd_usb_pcm_delay(subs, runtime->rate);
|
||||||
runtime->delay = 0;
|
/* update delay with exact number of samples played */
|
||||||
|
if (processed > subs->last_delay)
|
||||||
|
subs->last_delay = 0;
|
||||||
else
|
else
|
||||||
runtime->delay -= processed;
|
subs->last_delay -= processed;
|
||||||
|
runtime->delay = subs->last_delay;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Report when delay estimate is off by more than 2ms.
|
||||||
|
* The error should be lower than 2ms since the estimate relies
|
||||||
|
* on two reads of a counter updated every ms.
|
||||||
|
*/
|
||||||
|
if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2)
|
||||||
|
snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n",
|
||||||
|
est_delay, subs->last_delay);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&subs->lock, flags);
|
spin_unlock_irqrestore(&subs->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1215,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
err = start_endpoints(subs);
|
err = start_endpoints(subs, 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue