Skip to content

Commit 1b7ecc2

Browse files
marcantiwai
authored andcommitted
ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109
Further investigation of the L-R swap problem on the MS2109 reveals that the problem isn't that the channels are swapped, but rather that they are swapped and also out of phase by one sample. In other words, the issue is actually that the very first frame that comes from the hardware is a half-frame containing only the right channel, and after that everything becomes offset. So introduce a new quirk field to drop the very first 2 bytes that come in after the format is configured and a capture stream starts. This puts the channels in phase and in the correct order. Cc: [email protected] Signed-off-by: Hector Martin <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 386a653 commit 1b7ecc2

File tree

4 files changed

+11
-0
lines changed

4 files changed

+11
-0
lines changed

sound/usb/card.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ struct snd_usb_substream {
137137
unsigned int tx_length_quirk:1; /* add length specifier to transfers */
138138
unsigned int fmt_type; /* USB audio format type (1-3) */
139139
unsigned int pkt_offset_adj; /* Bytes to drop from beginning of packets (for non-compliant devices) */
140+
unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */
140141

141142
unsigned int running: 1; /* running status */
142143

sound/usb/pcm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,12 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
14201420
// continue;
14211421
}
14221422
bytes = urb->iso_frame_desc[i].actual_length;
1423+
if (subs->stream_offset_adj > 0) {
1424+
unsigned int adj = min(subs->stream_offset_adj, bytes);
1425+
cp += adj;
1426+
bytes -= adj;
1427+
subs->stream_offset_adj -= adj;
1428+
}
14231429
frames = bytes / stride;
14241430
if (!subs->txfr_quirk)
14251431
bytes = frames * stride;

sound/usb/quirks.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,9 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
14951495
case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
14961496
pioneer_djm_set_format_quirk(subs);
14971497
break;
1498+
case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
1499+
subs->stream_offset_adj = 2;
1500+
break;
14981501
}
14991502
}
15001503

sound/usb/stream.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
9494
subs->tx_length_quirk = as->chip->tx_length_quirk;
9595
subs->speed = snd_usb_get_speed(subs->dev);
9696
subs->pkt_offset_adj = 0;
97+
subs->stream_offset_adj = 0;
9798

9899
snd_usb_set_pcm_ops(as->pcm, stream);
99100

0 commit comments

Comments
 (0)