Skip to content

Commit

Permalink
ALSA: USB-audio: Adjust max packet size calculation for tx_length_quirk
Browse files Browse the repository at this point in the history
For the Zoom R16/24 (tx_length_quirk set), when calculating the maximum
sample frequency, consideration must be made for the fact that four bytes
of the packet contain a length descriptor and consequently must not be
counted as part of the audio data.

This is corroborated by the wMaxPacketSize for this device, which is 108
bytes according for the USB playback endpoint descriptor. The frame size
is 8 bytes (2 channels of 4 bytes each), and the 108 bytes thus work out
as 13 * 8 + 4, i.e. corresponding to 13 frames plus the additional 4 byte
length descriptor.

Signed-off-by: Ricard Wanderlof <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
Ricard Wanderlof authored and tiwai committed Oct 19, 2015
1 parent e057044 commit 759c90f
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions sound/usb/endpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,8 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
unsigned int max_packs_per_period, urbs_per_period, urb_packs;
unsigned int max_urbs, i;
int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels;
int tx_length_quirk = (ep->chip->tx_length_quirk &&
usb_pipeout(ep->pipe));

if (pcm_format == SNDRV_PCM_FORMAT_DSD_U16_LE && fmt->dsd_dop) {
/*
Expand Down Expand Up @@ -650,11 +652,17 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
*/
maxsize = (((ep->freqmax << ep->datainterval) + 0xffff) >> 16) *
(frame_bits >> 3);
if (tx_length_quirk)
maxsize += sizeof(__le32); /* Space for length descriptor */
/* but wMaxPacketSize might reduce this */
if (ep->maxpacksize && ep->maxpacksize < maxsize) {
/* whatever fits into a max. size packet */
maxsize = ep->maxpacksize;
ep->freqmax = (maxsize / (frame_bits >> 3))
unsigned int data_maxsize = maxsize = ep->maxpacksize;

if (tx_length_quirk)
/* Need to remove the length descriptor to calc freq */
data_maxsize -= sizeof(__le32);
ep->freqmax = (data_maxsize / (frame_bits >> 3))
<< (16 - ep->datainterval);
}

Expand Down

0 comments on commit 759c90f

Please sign in to comment.