Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp4827435imm; Mon, 14 May 2018 13:56:27 -0700 (PDT) X-Google-Smtp-Source: AB8JxZphJK1x5Ggdl78jdpOW1TskQvrrKnNyUvxRFYqA6YMH5SPoCFgC4pGpdP92WTnhmC86kHXA X-Received: by 2002:a17:902:b908:: with SMTP id bf8-v6mr11178424plb.358.1526331387587; Mon, 14 May 2018 13:56:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526331387; cv=none; d=google.com; s=arc-20160816; b=BkXqQBoXzqFzC6nqmgxVX285bCksz+R+qE9jy33CjkpLjlIgMDMFWSfgLJNjcOqSeE uGftXQoVW6x8+jJeXxRhBaKeO9zCv3NBKbtwnfyR+xGH24KAJbejkAFrFdpJf9wWDjbj amy8AaVV5wvG0KsGSqQOu4fxwejaj5wI/DdcXyOQQxi156fa5dnEvr0NUnlrlqylc2jy sGEqshtf2iEAaDYOJHKwjKTx+30LFdjZ8CWmstWU9BLOK/6c7/Y89B13ZdcP3y9PqHft j49MbtxOtHKmplKYpF3bv0iQeNGP1I70fO4Sm6Z8p+M5zreUa084NDlJi3Z74s7RQLMU geBg== 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=6tP0eVSRuMbxTTGGCKFix02BBP/gAhOXcghjTSCc18k=; b=RXdDRpFUyq4EOBelVNAfElDCFXS3fl26IDPRfEaxOWpEMog8XTTNMLJFnGHbphxNng 2oGNd77w8rkOlxcWgH0Os/R/getNjP60KSx5wXn3E5iJ39Rx665gBauP7j+rNmv3/7Ep cHGz3FWw8q28VIR5hisNvI5Jqf3dd6wcRFIOWshR/rS5Z3KOg4GITrlg+DjLJBwvthfl j2jd134vghKyIJF+Lv0dTUkJWgV8peEhqCUoq3JmKBWOwrLCMH/P8165xPN7gDfrePG+ DiKWoafHofmBROc56zjL+LwE2eN59Izb+lRdvwZbyie86TGxuDsOx91AJfp1d9ctW00D mmzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=m3lccLYu; 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 w5-v6si10653923pfi.88.2018.05.14.13.56.13; Mon, 14 May 2018 13:56:27 -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=m3lccLYu; 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 S1752372AbeENUyr (ORCPT + 99 others); Mon, 14 May 2018 16:54:47 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:40516 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752339AbeENUyo (ORCPT ); Mon, 14 May 2018 16:54:44 -0400 Received: by mail-wr0-f193.google.com with SMTP id v60-v6so13738045wrc.7 for ; Mon, 14 May 2018 13:54:43 -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=6tP0eVSRuMbxTTGGCKFix02BBP/gAhOXcghjTSCc18k=; b=m3lccLYuVtuY7g273a6d5dPxTCAB9/EyqXxCRqdSQEyuZI0aKl2Yqij4YaUdeOpkD1 rj4DGX34jh1XIDPYHVDbMoF/tHkmHwg7vOoN5fuDSHnVt/t18/NujsJ5S3TbnvAQeHZQ TuGAlXZimt89PPdL0gC2enRsKRBlBJ1StVwoFqeWeirZQGB4XRvN2wt+AmtlSVPHpf0B mIzil6jFeho4VVJNtYI2EKqLqqzfQOw1XW2NKXWjaRnnLJXnGORL/JS2bNh5cHuSLrz+ NWgBJ3JKuAI3d6an8iSKDGOGa4QcwjC11nEQ77onA7m2kS84Wi9DqD5ras3HgxnHyCjz bZcw== 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=6tP0eVSRuMbxTTGGCKFix02BBP/gAhOXcghjTSCc18k=; b=c5UZ4vHHw3FpDA0C8EIwmO6kai2UpC1ojslxvuWJNDowxFEdSafv9clgM2yDrSYaXW QITMv0TBZ5tD9PpkkIQjxB7239YB8uDJ9XHBPclf+OCLuLkWpvErwsJMDw5fQB4lV6PU ++U14LYzjVMqOY7FCvgGz457A2rsuk3K9C6g0f7k+cCXMoj4CYjfw18OlAC5JkgqO4+N GJzr5OgwYTC0HLkxfTTi2F0e6OkU1eyhsFbkTDEkQABZgkf64B4LFd9yB4tMUMEfTdaI zP46KDifc19A7W7AymxMgV0fbPwsv7ywl2b/RaN/8xEFBwIPRm58p20ZdYlL/cmCP976 kx6Q== X-Gm-Message-State: ALKqPweyrRHgenki7Mesw2HQ/3OAfhuDTHtSOURhLal0bosKTSATg8lq pHjO0JCwk70GPwAGSm6c7ptF+C2zPilgCvhDPrA= X-Received: by 2002:adf:9d8c:: with SMTP id p12-v6mr7991666wre.14.1526331283179; Mon, 14 May 2018 13:54:43 -0700 (PDT) MIME-Version: 1.0 Received: by 10.223.130.49 with HTTP; Mon, 14 May 2018 13:54:42 -0700 (PDT) In-Reply-To: <20180511152537.32267-2-jorge.sanjuan@codethink.co.uk> References: <20180420170327.31569-1-jorge.sanjuan@codethink.co.uk> <20180511152537.32267-1-jorge.sanjuan@codethink.co.uk> <20180511152537.32267-2-jorge.sanjuan@codethink.co.uk> From: Ruslan Bilovol Date: Mon, 14 May 2018 23:54:42 +0300 Message-ID: Subject: Re: [PATCH v4 1/4] ALSA: usb-audio: UAC3. Add support for mixer unit. To: Jorge Sanjuan 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 Fri, May 11, 2018 at 6:25 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. I tested this patch in a similar use-case (with a simple mixer unit), but _with_ controls and along with patch [1] from this series, which added parsing input terminal's channels. So everything works fine, I see all needed requests handling and mixer unit creation on ALSA side, which I can use now. So, as a bottom line: Reviewed-by: Ruslan Bilovol Tested-by: Ruslan Bilovol [1] http://mailman.alsa-project.org/pipermail/alsa-devel/2018-May/136030.html > > 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 76417943ff85..129c1397f0cb 100644 > --- a/sound/usb/mixer.c > +++ b/sound/usb/mixer.c > @@ -719,6 +719,66 @@ static int get_term_name(struct snd_usb_audio *chip, struct usb_audio_term *iter > } > > /* > + * 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; > } > @@ -1798,11 +1870,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; > @@ -1879,14 +1950,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++) { > @@ -1913,7 +1987,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); > } > } > -- > 2.11.0 > -- Best regards, Ruslan Bilovol