Commit 5e682c0e authored by Linus Torvalds's avatar Linus Torvalds

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
parents 6d1a0503 2e4a263c
...@@ -1209,6 +1209,9 @@ static void snd_hda_codec_free(struct hda_codec *codec) ...@@ -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, ...@@ -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, ...@@ -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 { ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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);
...@@ -800,6 +790,8 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, ...@@ -800,6 +790,8 @@ 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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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++) {
if (ctx->packet_size[i])
counts = 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, ...@@ -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, ...@@ -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 ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment