From patchwork Thu Aug 20 09:22:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 265549 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21C3EC433E1 for ; Thu, 20 Aug 2020 11:40:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E011F204EA for ; Thu, 20 Aug 2020 11:40:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597923633; bh=tcGqj/7/ZofFfawDGf6YWAYDXchoGbIZXO0mDruMJEw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=TSMuBxNDxmeTShKUdooK5bvNZcRKCei2h97QZE5P+R/bkmikoY3kAtHiPh7axFhYT KUSsD4LpL1a46bG/1Ow9tuGMeyb+orFZWQdMRcYUbfp8yKOFD4xwPa//qvNWTYv+fm QKrNswxIwwXKKMHmeELw2I+3vnpHo+cv2a/eWgEA= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730323AbgHTLj5 (ORCPT ); Thu, 20 Aug 2020 07:39:57 -0400 Received: from mail.kernel.org ([198.145.29.99]:58536 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729429AbgHTKFU (ORCPT ); Thu, 20 Aug 2020 06:05:20 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4DD5D22B40; Thu, 20 Aug 2020 10:05:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597917919; bh=tcGqj/7/ZofFfawDGf6YWAYDXchoGbIZXO0mDruMJEw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j/zpOTUcLBPc/ZAzKh8iZt+mcexzVdZUDb+74AAB0BxwR36l2Oab5lRXp059yKMyq YuRzgo5nHNSPyKotSNB+TbHgpwYVw89JPZH/TpkcMEOFNjF1mM1tZR2HzWjakHXYiR oikZrsTNevfqu3ICDI1P8AvzgMtYhOdMS5lSlzo0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hector Martin , Takashi Iwai Subject: [PATCH 4.9 163/212] ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109 Date: Thu, 20 Aug 2020 11:22:16 +0200 Message-Id: <20200820091610.636812289@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200820091602.251285210@linuxfoundation.org> References: <20200820091602.251285210@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Hector Martin commit 1b7ecc241a67ad6b584e071bd791a54e0cd5f097 upstream. 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: stable@vger.kernel.org Signed-off-by: Hector Martin Link: https://lore.kernel.org/r/20200810082400.225858-1-marcan@marcan.st Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/card.h | 1 + sound/usb/pcm.c | 6 ++++++ sound/usb/quirks.c | 3 +++ sound/usb/stream.c | 1 + 4 files changed, 11 insertions(+) --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -125,6 +125,7 @@ struct snd_usb_substream { unsigned int tx_length_quirk:1; /* add length specifier to transfers */ unsigned int fmt_type; /* USB audio format type (1-3) */ unsigned int pkt_offset_adj; /* Bytes to drop from beginning of packets (for non-compliant devices) */ + unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */ unsigned int running: 1; /* running status */ --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1312,6 +1312,12 @@ static void retire_capture_urb(struct sn // continue; } bytes = urb->iso_frame_desc[i].actual_length; + if (subs->stream_offset_adj > 0) { + unsigned int adj = min(subs->stream_offset_adj, bytes); + cp += adj; + bytes -= adj; + subs->stream_offset_adj -= adj; + } frames = bytes / stride; if (!subs->txfr_quirk) bytes = frames * stride; --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1121,6 +1121,9 @@ void snd_usb_set_format_quirk(struct snd case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */ set_format_emu_quirk(subs, fmt); break; + case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */ + subs->stream_offset_adj = 2; + break; } } --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -95,6 +95,7 @@ static void snd_usb_init_substream(struc subs->tx_length_quirk = as->chip->tx_length_quirk; subs->speed = snd_usb_get_speed(subs->dev); subs->pkt_offset_adj = 0; + subs->stream_offset_adj = 0; snd_usb_set_pcm_ops(as->pcm, stream);