Received: by 10.192.165.148 with SMTP id m20csp414915imm; Wed, 9 May 2018 15:11:42 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqXilAxSf1gWZf5k7Hnw1VF9WU0ZqQocP3sFkeAFS13lG9nr2hzT9oHyesru2ph1zeRxyEW X-Received: by 2002:a17:902:781:: with SMTP id 1-v6mr47257522plj.150.1525903902375; Wed, 09 May 2018 15:11:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525903902; cv=none; d=google.com; s=arc-20160816; b=uxa/ZGtfG+zOPFjeQ769Q86ig1W2kF8I52+ebquybOZSVNIotAWeGhJDZsxezMlILq 9mAp/taX/pyxCHFtAaagBE5UlZ2bGqo74fhPDqeYY0BlkTPQWwESpaAgzsp45U87gCIm VQsHLMVkWjZwFxQMGRxo1ylBUh85WDf7xfKNXh8EhN6nuJnYMKbNDLvp4L9IRIOjIt3g UQfP5BmKlRc67ZpuGoF6dF5w1fAhmTbY3fAcBZFPHFfnCgUSQ4l7KS1rIXMB/0T57mI1 hwn/yK4irscADeHxLldu40wkEkxLq8rToXXlLP1J4BZzuRYDGdk6iLHvA9kqG3n4EYvL RRfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=IeQSXC5YXaG5inp5oRMEEoVCRoJvQHqb1d7BcXVU9jQ=; b=i7XGSHrmsdvbvCPqrdxaK2N0iJbrBthH5Z71Y2PDbLlAIXOZvVnjnS0niRxpBuRhpc fDqmaJGihOmhM/TECNar4WbR8jERkww0Od7GP/fpBBv0BKqHa2q1we98FdBv5loDX6Gz BUXjxcPGd8Sl1RMC6eJfViBISaaQbpNl+FR/kIVoFtt1Bt39VheZki8N6enOeynWLo+n U54DH87aVVF40Hhih2YRvSGgsTU7ScP8QdtO7QsF5/5cveNs/xm8BlL9dt/SUG+U9hXp 5HLe8I+qZwRd3kC+zP0PR0HQHIeDdalv+QwUoy276ZkpVpaE9wO7Hf2I8S4d7+x7MOCk QPhw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=upujpKWw; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k2-v6si21850103plt.374.2018.05.09.15.11.27; Wed, 09 May 2018 15:11:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=upujpKWw; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965790AbeEIWLQ (ORCPT + 99 others); Wed, 9 May 2018 18:11:16 -0400 Received: from mail-ot0-f196.google.com ([74.125.82.196]:44349 "EHLO mail-ot0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965484AbeEIWLO (ORCPT ); Wed, 9 May 2018 18:11:14 -0400 Received: by mail-ot0-f196.google.com with SMTP id g7-v6so92561otj.11 for ; Wed, 09 May 2018 15:11:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=IeQSXC5YXaG5inp5oRMEEoVCRoJvQHqb1d7BcXVU9jQ=; b=upujpKWwLZQLWabE88upSDrrzC9NRPCWnDdh8U/pzqoeufYa/mJvgh4zhZMj09zPvc gVWLcG9Nq11cRHu2HXvMii2PxF+PGDkvlm6sc9FA8AoCSHmCBZ5fJriAX3DWi5fC9csU IJYpXeqYnRa0XhJkO5UxfYO3BAhMi5YNsDuW+4WInH4rkKtDhIb7c3J0h1uOlT0IOajS U8LOGI0VS/DekXmietNy4rlPZ6bGjaPWllhm1jwrCrEfhfGgLYGGdg8o+gPn8Yhr2/+6 HNDuSZjTMx27Zp667U2EXHe2z1gpITEvSiU5iqDGNJSvGa/hBNW0mMtsqVTaIVFb7PSJ QUtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=IeQSXC5YXaG5inp5oRMEEoVCRoJvQHqb1d7BcXVU9jQ=; b=VYNS6ddBtWG2PYepKv5ypqoezNOh/OVkI7y1mhMzh49owvOrH8J/z49gOdZlotg9zf J7bh/5Nf9M7TZCSo0lspKRt0lD/UDRl/6savSv3Kfh5qYEva/c0eEmFIdQyXKypw2XxG 1DTfzrYTXOwMTYM1Y5J2mPNUTutw4pzZC01WcYfL5qHFmx51Sbn/JGhJwra1m4Ei2FBl 04VwGlq80sbdsakbZriSEqo9zcpOZIxWRw8pRZ2/mecMH7lfI6+RMESYOtv3KrlFJ2LB xyWMRtBx2IGk8UO+QAmwsyK4x0bcNMUDHq20Wsq8qzGfmzgQQhBFonbcRgrOBhDPFIOg yz/g== X-Gm-Message-State: ALQs6tAlN2nAHMcmW2gRl8aLxN2so5RJOc4rbbnHCZmcpbp+HjdC0z32 nLHNbehpKTR09P74z+34yCjHZ0l7uQ5PbBZmBVUFAw== X-Received: by 2002:a9d:de2:: with SMTP id 89-v6mr32325368ots.269.1525903873966; Wed, 09 May 2018 15:11:13 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a9d:405:0:0:0:0:0 with HTTP; Wed, 9 May 2018 15:11:13 -0700 (PDT) In-Reply-To: <52c0eb21-0a69-7a2b-da8a-2d33ad4e11d2@codethink.co.uk> References: <20180424172445.31928-2-jorge.sanjuan@codethink.co.uk> <20180427170649.27334-1-jorge.sanjuan@codethink.co.uk> <52c0eb21-0a69-7a2b-da8a-2d33ad4e11d2@codethink.co.uk> From: Ruslan Bilovol Date: Thu, 10 May 2018 01:11:13 +0300 Message-ID: Subject: Re: [PATCH v3 1/4] ALSA: usb-audio: UAC3. Add support for mixer unit. To: Jorge Cc: Takashi Iwai , alsa-devel@alsa-project.org, Greg Kroah-Hartman , linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, May 8, 2018 at 12:43 PM, Jorge wrote: > > > On 04/05/18 01:57, Ruslan Bilovol wrote: >> >> On Fri, Apr 27, 2018 at 8:06 PM, Jorge Sanjuan >> wrote: >>> >>> This adds support for the MIXER UNIT in UAC3. All the information >>> is obtained from the (HIGH CAPABILITY) Cluster's header. We don't >>> read the rest of the logical cluster to obtain the channel config >>> as that wont make any difference in the current mixer behaviour. >>> >>> The name of the mixer unit is not yet requested as there is not >>> support for the UAC3 Class Specific String requests. >>> >>> Tested in an UAC3 device working as a HEADSET with a basic mixer >>> unit (same as the one in the BADD spec) with no controls. >> >> >> So, after deeper looking into the code and after testing this patch, >> in your usecase (mixer with no controls) you'll never execute >> build_mixer_unit_ctl(), correct? So did you try to just fix issues with >> incorrect parsing of mixer unit descriptor? >> >>> >>> Signed-off-by: Jorge Sanjuan >>> --- >>> include/uapi/linux/usb/audio.h | 19 +++++++-- >>> sound/usb/mixer.c | 88 >>> ++++++++++++++++++++++++++++++++++++++---- >>> 2 files changed, 97 insertions(+), 10 deletions(-) >>> >>> diff --git a/include/uapi/linux/usb/audio.h >>> b/include/uapi/linux/usb/audio.h >>> index 3a78e7145689..13d98e6e0db1 100644 >>> --- a/include/uapi/linux/usb/audio.h >>> +++ b/include/uapi/linux/usb/audio.h >>> @@ -285,9 +285,22 @@ static inline __u8 >>> uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor >>> static inline __u8 *uac_mixer_unit_bmControls(struct >>> uac_mixer_unit_descriptor *desc, >>> int protocol) >>> { >>> - return (protocol == UAC_VERSION_1) ? >>> - &desc->baSourceID[desc->bNrInPins + 4] : >>> - &desc->baSourceID[desc->bNrInPins + 6]; >>> + switch (protocol) { >>> + case UAC_VERSION_1: >>> + return &desc->baSourceID[desc->bNrInPins + 4]; >>> + case UAC_VERSION_2: >>> + return &desc->baSourceID[desc->bNrInPins + 6]; >>> + case UAC_VERSION_3: >>> + return &desc->baSourceID[desc->bNrInPins + 2]; >>> + default: >>> + return NULL; >>> + } >>> +} >>> + >>> +static inline __u16 uac3_mixer_unit_wClusterDescrID(struct >>> uac_mixer_unit_descriptor *desc) >>> +{ >>> + return (desc->baSourceID[desc->bNrInPins + 1] << 8) | >>> + desc->baSourceID[desc->bNrInPins]; >>> } >>> >>> static inline __u8 uac_mixer_unit_iMixer(struct >>> uac_mixer_unit_descriptor *desc) >>> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c >>> index 301ad61ed426..3503f4840ec3 100644 >>> --- a/sound/usb/mixer.c >>> +++ b/sound/usb/mixer.c >>> @@ -719,6 +719,66 @@ static int get_term_name(struct mixer_build *state, >>> struct usb_audio_term *iterm >>> } >>> >>> /* >>> + * Get logical cluster information for UAC3 devices. >>> + */ >>> +static int get_cluster_channels_v3(struct mixer_build *state, unsigned >>> int cluster_id) >>> +{ >>> + struct uac3_cluster_header_descriptor c_header; >>> + int err; >>> + >>> + err = snd_usb_ctl_msg(state->chip->dev, >>> + usb_rcvctrlpipe(state->chip->dev, 0), >>> + UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR, >>> + USB_RECIP_INTERFACE | USB_TYPE_CLASS | >>> USB_DIR_IN, >>> + cluster_id, >>> + snd_usb_ctrl_intf(state->chip), >>> + &c_header, sizeof(c_header)); >>> + if (err < 0) >>> + goto error; >>> + if (err != sizeof(c_header)) { >>> + err = -EIO; >>> + goto error; >>> + } >>> + >>> + return c_header.bNrChannels; >>> + >>> +error: >>> + usb_audio_err(state->chip, "cannot request logical cluster ID: %d >>> (err: %d)\n", cluster_id, err); >>> + return err; >>> +} >>> + >>> +/* >>> + * Get number of channels for a Mixer Unit. >>> + */ >>> +static int uac_mixer_unit_get_channels(struct mixer_build *state, >>> + struct uac_mixer_unit_descriptor >>> *desc) >>> +{ >>> + int mu_channels; >>> + >>> + if (desc->bLength < 11) >>> + return -EINVAL; >>> + if (!desc->bNrInPins) >>> + return -EINVAL; >>> + >>> + switch (state->mixer->protocol) { >>> + case UAC_VERSION_1: >>> + case UAC_VERSION_2: >>> + default: >>> + mu_channels = uac_mixer_unit_bNrChannels(desc); >>> + break; >>> + case UAC_VERSION_3: >>> + mu_channels = get_cluster_channels_v3(state, >>> + uac3_mixer_unit_wClusterDescrID(desc)); >>> + break; >>> + } >>> + >>> + if (!mu_channels) >>> + return -EINVAL; >>> + >>> + return mu_channels; >>> +} >>> + >>> +/* >>> * parse the source unit recursively until it reaches to a terminal >>> * or a branched unit. >>> */ >>> @@ -865,6 +925,18 @@ static int check_input_term(struct mixer_build >>> *state, int id, >>> term->name = >>> le16_to_cpu(d->wClockSourceStr); >>> return 0; >>> } >>> + case UAC3_MIXER_UNIT: { >>> + struct uac_mixer_unit_descriptor *d = p1; >>> + >>> + err = uac_mixer_unit_get_channels(state, >>> d); >>> + if (err < 0) >>> + return err; >>> + >>> + term->channels = err; >>> + term->type = d->bDescriptorSubtype << 16; >>> /* virtual type */ >>> + >>> + return 0; >>> + } >>> default: >>> return -ENODEV; >>> } >>> @@ -1797,11 +1869,10 @@ static int parse_audio_feature_unit(struct >>> mixer_build *state, int unitid, >>> */ >>> static void build_mixer_unit_ctl(struct mixer_build *state, >>> struct uac_mixer_unit_descriptor *desc, >>> - int in_pin, int in_ch, int unitid, >>> - struct usb_audio_term *iterm) >>> + int in_pin, int in_ch, int num_outs, >>> + int unitid, struct usb_audio_term >>> *iterm) >>> { >>> struct usb_mixer_elem_info *cval; >>> - unsigned int num_outs = uac_mixer_unit_bNrChannels(desc); >>> unsigned int i, len; >>> struct snd_kcontrol *kctl; >>> const struct usbmix_name_map *map; >>> @@ -1878,14 +1949,17 @@ static int parse_audio_mixer_unit(struct >>> mixer_build *state, int unitid, >>> int input_pins, num_ins, num_outs; >>> int pin, ich, err; >>> >>> - if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) || >>> - !(num_outs = uac_mixer_unit_bNrChannels(desc))) { >>> + err = uac_mixer_unit_get_channels(state, desc); >>> + if (err < 0) { >>> usb_audio_err(state->chip, >>> "invalid MIXER UNIT descriptor %d\n", >>> unitid); >>> - return -EINVAL; >>> + return err; >>> } >>> >>> + num_outs = err; >>> + input_pins = desc->bNrInPins; >>> + >>> num_ins = 0; >>> ich = 0; >>> for (pin = 0; pin < input_pins; pin++) { >>> @@ -1912,7 +1986,7 @@ static int parse_audio_mixer_unit(struct >>> mixer_build *state, int unitid, >>> } >>> } >>> if (ich_has_controls) >>> - build_mixer_unit_ctl(state, desc, pin, >>> ich, >>> + build_mixer_unit_ctl(state, desc, pin, >>> ich, num_outs, >>> unitid, &iterm); >> >> >> So with current sources we will never reach this place. In your >> usecase (mixer with no >> controls) it obviously won't go inside. >> However, I created a mixer with controls but still >> build_mixer_unit_ctl() isn't executed. >> This is because UAC3 input terminal parsing always returns 0 channels, >> this is >> what still needs to be implemented (see comment "REVISIT: UAC3 IT doesn't >> have channels/cfg" in check_input_term) > > > Thanks for testing this! > > I missed that one with the number of input channels. Regarding the "REVISIT: > UAC3 IT doesn't have channels/cfg" comment, we can easily fix that using the > helper function I added in this patch for reading the logical cluster's > number of channels `get_cluster_channels_v3`. The channel config bitmap I > don't see it being used at all so parsing iterm.channels should be enough. > Any thoughts? > I looked into the sources, it seems you are right, we need only number of channels to proceed with mixer unit created. I can hack your patch and test it in a few days, or feel free to send v4 Thanks, Ruslan