diff options
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 83aabea259d..289f582c913 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -333,8 +333,9 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) err = usb_submit_urb(ctx->urb, GFP_ATOMIC); if (err < 0) - snd_printk(KERN_ERR "Unable to submit urb #%d: %d (urb %p)\n", - ctx->index, err, ctx->urb); + usb_audio_err(ep->chip, + "Unable to submit urb #%d: %d (urb %p)\n", + ctx->index, err, ctx->urb); else set_bit(ctx->index, &ep->active_mask); } @@ -387,7 +388,7 @@ static void snd_complete_urb(struct urb *urb) if (err == 0) return; - snd_printk(KERN_ERR "cannot submit urb (err = %d)\n", err); + usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); //snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); exit_clear: @@ -426,13 +427,14 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, if (ep->ep_num == ep_num && ep->iface == alts->desc.bInterfaceNumber && ep->altsetting == alts->desc.bAlternateSetting) { - snd_printdd(KERN_DEBUG "Re-using EP %x in iface %d,%d @%p\n", + usb_audio_dbg(ep->chip, + "Re-using EP %x in iface %d,%d @%p\n", ep_num, ep->iface, ep->altsetting, ep); goto __exit_unlock; } } - snd_printdd(KERN_DEBUG "Creating new %s %s endpoint #%x\n", + usb_audio_dbg(chip, "Creating new %s %s endpoint #%x\n", is_playback ? "playback" : "capture", type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync", ep_num); @@ -469,6 +471,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, ep->syncinterval = 3; ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); + + if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ && + ep->syncmaxsize == 4) + ep->udh01_fb_quirk = 1; } list_add_tail(&ep->list, &chip->ep_list); @@ -496,8 +502,9 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) } while (time_before(jiffies, end_time)); if (alive) - snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", - alive, ep->ep_num); + usb_audio_err(ep->chip, + "timeout: still %d active urbs on EP #%x\n", + alive, ep->ep_num); clear_bit(EP_FLAG_STOPPING, &ep->flags); return 0; @@ -794,8 +801,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, int err; if (ep->use_count != 0) { - snd_printk(KERN_WARNING "Unable to change format on ep #%x: already in use\n", - ep->ep_num); + usb_audio_warn(ep->chip, + "Unable to change format on ep #%x: already in use\n", + ep->ep_num); return -EBUSY; } @@ -830,8 +838,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, err = -EINVAL; } - snd_printdd(KERN_DEBUG "Setting params for ep #%x (type %d, %d urbs), ret=%d\n", - ep->ep_num, ep->type, ep->nurbs, err); + usb_audio_dbg(ep->chip, + "Setting params for ep #%x (type %d, %d urbs), ret=%d\n", + ep->ep_num, ep->type, ep->nurbs, err); return err; } @@ -906,8 +915,9 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - snd_printk(KERN_ERR "cannot submit urb %d, error %d: %s\n", - i, err, usb_error_string(err)); + usb_audio_err(ep->chip, + "cannot submit urb %d, error %d: %s\n", + i, err, usb_error_string(err)); goto __error; } set_bit(i, &ep->active_mask); @@ -1099,7 +1109,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, if (f == 0) return; - if (unlikely(ep->freqshift == INT_MIN)) { + if (unlikely(sender->udh01_fb_quirk)) { + /* + * The TEAC UD-H01 firmware sometimes changes the feedback value + * by +/- 0x1.0000. + */ + if (f < ep->freqn - 0x8000) + f += 0x10000; + else if (f > ep->freqn + 0x8000) + f -= 0x10000; + } else if (unlikely(ep->freqshift == INT_MIN)) { /* * The first time we see a feedback value, determine its format * by shifting it left or right until it matches the nominal |