diff options
| -rw-r--r-- | sound/usb/usbaudio.c | 31 | ||||
| -rw-r--r-- | sound/usb/usbaudio.h | 1 |
2 files changed, 30 insertions, 2 deletions
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 8fcb5d5a94b6..617515f6ec7b 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
| @@ -169,6 +169,7 @@ struct snd_usb_substream { | |||
| 169 | unsigned int curpacksize; /* current packet size in bytes (for capture) */ | 169 | unsigned int curpacksize; /* current packet size in bytes (for capture) */ |
| 170 | unsigned int curframesize; /* current packet size in frames (for capture) */ | 170 | unsigned int curframesize; /* current packet size in frames (for capture) */ |
| 171 | unsigned int fill_max: 1; /* fill max packet size always */ | 171 | unsigned int fill_max: 1; /* fill max packet size always */ |
| 172 | unsigned int txfr_quirk:1; /* allow sub-frame alignment */ | ||
| 172 | unsigned int fmt_type; /* USB audio format type (1-3) */ | 173 | unsigned int fmt_type; /* USB audio format type (1-3) */ |
| 173 | 174 | ||
| 174 | unsigned int running: 1; /* running status */ | 175 | unsigned int running: 1; /* running status */ |
| @@ -353,14 +354,25 @@ static int retire_capture_urb(struct snd_usb_substream *subs, | |||
| 353 | snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); | 354 | snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); |
| 354 | // continue; | 355 | // continue; |
| 355 | } | 356 | } |
| 356 | frames = urb->iso_frame_desc[i].actual_length / stride; | 357 | bytes = urb->iso_frame_desc[i].actual_length; |
| 357 | bytes = frames * stride; | 358 | frames = bytes / stride; |
| 359 | if (!subs->txfr_quirk) | ||
| 360 | bytes = frames * stride; | ||
| 361 | if (bytes % (runtime->sample_bits >> 3) != 0) { | ||
| 362 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
| 363 | int oldbytes = bytes; | ||
| 364 | #endif | ||
| 365 | bytes = frames * stride; | ||
| 366 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", | ||
| 367 | oldbytes, bytes); | ||
| 368 | } | ||
| 358 | /* update the current pointer */ | 369 | /* update the current pointer */ |
| 359 | spin_lock_irqsave(&subs->lock, flags); | 370 | spin_lock_irqsave(&subs->lock, flags); |
| 360 | oldptr = subs->hwptr_done; | 371 | oldptr = subs->hwptr_done; |
| 361 | subs->hwptr_done += bytes; | 372 | subs->hwptr_done += bytes; |
| 362 | if (subs->hwptr_done >= runtime->buffer_size * stride) | 373 | if (subs->hwptr_done >= runtime->buffer_size * stride) |
| 363 | subs->hwptr_done -= runtime->buffer_size * stride; | 374 | subs->hwptr_done -= runtime->buffer_size * stride; |
| 375 | frames = (bytes + (oldptr % stride)) / stride; | ||
| 364 | subs->transfer_done += frames; | 376 | subs->transfer_done += frames; |
| 365 | if (subs->transfer_done >= runtime->period_size) { | 377 | if (subs->transfer_done >= runtime->period_size) { |
| 366 | subs->transfer_done -= runtime->period_size; | 378 | subs->transfer_done -= runtime->period_size; |
| @@ -2238,6 +2250,7 @@ static void init_substream(struct snd_usb_stream *as, int stream, struct audiofo | |||
| 2238 | subs->stream = as; | 2250 | subs->stream = as; |
| 2239 | subs->direction = stream; | 2251 | subs->direction = stream; |
| 2240 | subs->dev = as->chip->dev; | 2252 | subs->dev = as->chip->dev; |
| 2253 | subs->txfr_quirk = as->chip->txfr_quirk; | ||
| 2241 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { | 2254 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) { |
| 2242 | subs->ops = audio_urb_ops[stream]; | 2255 | subs->ops = audio_urb_ops[stream]; |
| 2243 | } else { | 2256 | } else { |
| @@ -3618,6 +3631,20 @@ static void *snd_usb_audio_probe(struct usb_device *dev, | |||
| 3618 | } | 3631 | } |
| 3619 | } | 3632 | } |
| 3620 | 3633 | ||
| 3634 | switch (chip->usb_id) { | ||
| 3635 | case USB_ID(0x2040, 0x7200): /* Hauppage hvr950Q */ | ||
| 3636 | case USB_ID(0x2040, 0x7221): /* Hauppage hvr950Q */ | ||
| 3637 | case USB_ID(0x2040, 0x7222): /* Hauppage hvr950Q */ | ||
| 3638 | case USB_ID(0x2040, 0x7223): /* Hauppage hvr950Q */ | ||
| 3639 | case USB_ID(0x2040, 0x7224): /* Hauppage hvr950Q */ | ||
| 3640 | case USB_ID(0x2040, 0x7225): /* Hauppage hvr950Q */ | ||
| 3641 | case USB_ID(0x2040, 0x7230): /* Hauppage hvr850 */ | ||
| 3642 | case USB_ID(0x2040, 0x7250): /* Hauppage hvr950Q */ | ||
| 3643 | chip->txfr_quirk = 1; | ||
| 3644 | break; | ||
| 3645 | default: | ||
| 3646 | chip->txfr_quirk = 0; | ||
| 3647 | } | ||
| 3621 | err = 1; /* continue */ | 3648 | err = 1; /* continue */ |
| 3622 | if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { | 3649 | if (quirk && quirk->ifnum != QUIRK_NO_INTERFACE) { |
| 3623 | /* need some special handlings */ | 3650 | /* need some special handlings */ |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 152216738cce..d180554b81f0 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -125,6 +125,7 @@ struct snd_usb_audio { | |||
| 125 | struct snd_card *card; | 125 | struct snd_card *card; |
| 126 | u32 usb_id; | 126 | u32 usb_id; |
| 127 | int shutdown; | 127 | int shutdown; |
| 128 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ | ||
| 128 | int num_interfaces; | 129 | int num_interfaces; |
| 129 | int num_suspended_intf; | 130 | int num_suspended_intf; |
| 130 | 131 | ||
