From patchwork Thu Oct 26 18:01:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 13437780 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BF32EC25B48 for ; Thu, 26 Oct 2023 18:02:35 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 72A98A4D; Thu, 26 Oct 2023 20:01:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 72A98A4D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1698343353; bh=HDEpKX/S+wM4Gg0v4TrUmCQAOUsU+ulqs/uHggFvVWM=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=i6oLn/E7hutJpLwiWJ2Io2FvyhPqNbkze/ymP+qDSX59bn9VcdQBjrKpfk+7ku0ge bOYF9Bna9tSVfYxxW/h/0zuaELHqeI+hMri2WFY6ihxmr1+APBwXKauAG1Ziif7bqg yUgS91n6xHWIOqJD8o17GA4qhGNb2PaAfqwHR0qI= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2A87CF8024E; Thu, 26 Oct 2023 20:01:43 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id BB51EF80224; Thu, 26 Oct 2023 20:01:42 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9FB14F80557; Thu, 26 Oct 2023 20:01:39 +0200 (CEST) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id E8ED4F80165 for ; Thu, 26 Oct 2023 20:01:32 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz E8ED4F80165 Received: by m.b4.vu (Postfix, from userid 1000) id BDED1604F28E; Fri, 27 Oct 2023 04:31:28 +1030 (ACDT) Date: Fri, 27 Oct 2023 04:31:28 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: alsa-devel@alsa-project.org Subject: [PATCH 1/5] ALSA: scarlett2: Rename scarlett_gen2 to scarlett2 Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: E2GGCBKTBDTQZZH567HDGBXWGMXTZLVU X-Message-ID-Hash: E2GGCBKTBDTQZZH567HDGBXWGMXTZLVU X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: This driver was originally developed for the Focusrite Scarlett Gen 2 series. Since then Focusrite have used a similar protocol for their Gen 3, Gen 4, Clarett USB, Clarett+, and Vocaster series. Let's call this common protocol the "Scarlett 2 Protocol" and rename the driver to scarlett2 to not imply that it is restricted to Gen 2 series devices. Signed-off-by: Geoffrey D. Bennett --- MAINTAINERS | 2 +- sound/usb/Makefile | 2 +- sound/usb/mixer_quirks.c | 4 ++-- .../usb/{mixer_scarlett_gen2.c => mixer_scarlett2.c} | 12 +++++++----- sound/usb/mixer_scarlett2.h | 7 +++++++ sound/usb/mixer_scarlett_gen2.h | 7 ------- 6 files changed, 18 insertions(+), 16 deletions(-) rename sound/usb/{mixer_scarlett_gen2.c => mixer_scarlett2.c} (99%) create mode 100644 sound/usb/mixer_scarlett2.h delete mode 100644 sound/usb/mixer_scarlett_gen2.h diff --git a/MAINTAINERS b/MAINTAINERS index 4cc6bf79fdd8..ffa2367822fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8066,7 +8066,7 @@ M: Geoffrey D. Bennett L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git -F: sound/usb/mixer_scarlett_gen2.c +F: sound/usb/mixer_scarlett2.c FORCEDETH GIGABIT ETHERNET DRIVER M: Rain River diff --git a/sound/usb/Makefile b/sound/usb/Makefile index db5ff76d0e61..8c657c2753c8 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -12,7 +12,7 @@ snd-usb-audio-objs := card.o \ mixer.o \ mixer_quirks.o \ mixer_scarlett.o \ - mixer_scarlett_gen2.o \ + mixer_scarlett2.o \ mixer_us16x08.o \ mixer_s1810c.o \ pcm.o \ diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ac521b71cb57..898bc3baca7b 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -33,7 +33,7 @@ #include "mixer.h" #include "mixer_quirks.h" #include "mixer_scarlett.h" -#include "mixer_scarlett_gen2.h" +#include "mixer_scarlett2.h" #include "mixer_us16x08.h" #include "mixer_s1810c.h" #include "helper.h" @@ -3426,7 +3426,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) case USB_ID(0x1235, 0x820a): /* Focusrite Clarett+ 2Pre */ case USB_ID(0x1235, 0x820b): /* Focusrite Clarett+ 4Pre */ case USB_ID(0x1235, 0x820c): /* Focusrite Clarett+ 8Pre */ - err = snd_scarlett_gen2_init(mixer); + err = snd_scarlett2_init(mixer); break; case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett2.c similarity index 99% rename from sound/usb/mixer_scarlett_gen2.c rename to sound/usb/mixer_scarlett2.c index ffd398f26d2c..1a9d62b67323 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett2.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Focusrite Scarlett Gen 2/3 and Clarett USB/Clarett+ Driver for ALSA + * Focusrite Scarlett 2 Protocol Driver for ALSA + * (including Scarlett 2nd Gen, 3rd Gen, Clarett USB, and Clarett+ + * series products) * * Supported models: * - 6i6/18i8/18i20 Gen 2 @@ -149,7 +151,7 @@ #include "mixer.h" #include "helper.h" -#include "mixer_scarlett_gen2.h" +#include "mixer_scarlett2.h" /* device_setup value to allow turning MSD mode back on */ #define SCARLETT2_MSD_ENABLE 0x02 @@ -4174,7 +4176,7 @@ static const struct scarlett2_device_entry *get_scarlett2_device_entry( return entry; } -static int snd_scarlett_gen2_controls_create( +static int snd_scarlett2_controls_create( struct usb_mixer_interface *mixer, const struct scarlett2_device_entry *entry) { @@ -4262,7 +4264,7 @@ static int snd_scarlett_gen2_controls_create( return 0; } -int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer) +int snd_scarlett2_init(struct usb_mixer_interface *mixer) { struct snd_usb_audio *chip = mixer->chip; const struct scarlett2_device_entry *entry; @@ -4301,7 +4303,7 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer) entry->series_name, USB_ID_PRODUCT(chip->usb_id)); - err = snd_scarlett_gen2_controls_create(mixer, entry); + err = snd_scarlett2_controls_create(mixer, entry); if (err < 0) usb_audio_err(mixer->chip, "Error initialising %s Mixer Driver: %d", diff --git a/sound/usb/mixer_scarlett2.h b/sound/usb/mixer_scarlett2.h new file mode 100644 index 000000000000..d209362cf41a --- /dev/null +++ b/sound/usb/mixer_scarlett2.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __USB_MIXER_SCARLETT2_H +#define __USB_MIXER_SCARLETT2_H + +int snd_scarlett2_init(struct usb_mixer_interface *mixer); + +#endif /* __USB_MIXER_SCARLETT2_H */ diff --git a/sound/usb/mixer_scarlett_gen2.h b/sound/usb/mixer_scarlett_gen2.h deleted file mode 100644 index 668c6b0cb50a..000000000000 --- a/sound/usb/mixer_scarlett_gen2.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __USB_MIXER_SCARLETT_GEN2_H -#define __USB_MIXER_SCARLETT_GEN2_H - -int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer); - -#endif /* __USB_MIXER_SCARLETT_GEN2_H */ From patchwork Thu Oct 26 18:02:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 13437781 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0EC90C25B48 for ; Thu, 26 Oct 2023 18:04:15 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 33C82A4B; Thu, 26 Oct 2023 20:03:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 33C82A4B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1698343453; bh=3NfJbs8vjcgpTEva5H1IJNaX6ajRaN/FtCF16NkLjKc=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=oTep9JbWDSprV9ML84JfnLtM6AlSR3ca3bzca2FBYuaL2HCSLgE3eZMzcwms/2wOC XiYs/jP9P33FnW1r0i8iDgfja4uCd2FQOR2j6S+11PDiK6j4+U9xfxIo9GjonP3kEx fJQTUzM0US7S4m/aljmkq6Z+EYV5geg2g92oxywE= Received: by alsa1.perex.cz (Postfix, from userid 50401) id D5157F8020D; Thu, 26 Oct 2023 20:02:53 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 4340CF80224; Thu, 26 Oct 2023 20:02:53 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 47DC2F80165; Thu, 26 Oct 2023 20:02:50 +0200 (CEST) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 1E9C4F8019B for ; Thu, 26 Oct 2023 20:02:43 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1E9C4F8019B Received: by m.b4.vu (Postfix, from userid 1000) id 2AADB604F28E; Fri, 27 Oct 2023 04:32:39 +1030 (ACDT) Date: Fri, 27 Oct 2023 04:32:39 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: alsa-devel@alsa-project.org Subject: [PATCH 2/5] ALSA: scarlett2: Rename Gen 3 config sets Message-ID: <19ae5eea7fc499945efa8eeda7fcd8afe73f62d9.1698342632.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: IKT66FAQF76JO6BXKP6RMKQX6GL3Y3VG X-Message-ID-Hash: IKT66FAQF76JO6BXKP6RMKQX6GL3Y3VG X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: <> List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The config sets are named NO_MIXER, GEN_2, GEN_3, and CLARETT currently. Rename NO_MIXER and GEN_3 to GEN_3A and GEN_3B respectively as NO_MIXER is only for the smaller Gen 3 devices. Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 74 ++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 1a9d62b67323..2f9619bc6d4f 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -213,15 +213,15 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = { /* Maximum number of meters (sum of output port counts) */ #define SCARLETT2_MAX_METERS 65 -/* There are three different sets of configuration parameters across - * the devices +/* There are different sets of configuration parameters across the + * devices, dependent on series and model. */ enum { - SCARLETT2_CONFIG_SET_NO_MIXER = 0, - SCARLETT2_CONFIG_SET_GEN_2 = 1, - SCARLETT2_CONFIG_SET_GEN_3 = 2, + SCARLETT2_CONFIG_SET_GEN_2 = 0, + SCARLETT2_CONFIG_SET_GEN_3A = 1, + SCARLETT2_CONFIG_SET_GEN_3B = 2, SCARLETT2_CONFIG_SET_CLARETT = 3, - SCARLETT2_CONFIG_SET_COUNT = 4 + SCARLETT2_CONFIG_SET_COUNT = 4 }; /* Hardware port types: @@ -595,7 +595,7 @@ static const struct scarlett2_device_info s18i20_gen2_info = { static const struct scarlett2_device_info solo_gen3_info = { .has_msd_mode = 1, - .config_set = SCARLETT2_CONFIG_SET_NO_MIXER, + .config_set = SCARLETT2_CONFIG_SET_GEN_3A, .level_input_count = 1, .level_input_first = 1, .air_input_count = 1, @@ -606,7 +606,7 @@ static const struct scarlett2_device_info solo_gen3_info = { static const struct scarlett2_device_info s2i2_gen3_info = { .has_msd_mode = 1, - .config_set = SCARLETT2_CONFIG_SET_NO_MIXER, + .config_set = SCARLETT2_CONFIG_SET_GEN_3A, .level_input_count = 2, .air_input_count = 2, .phantom_count = 1, @@ -616,7 +616,7 @@ static const struct scarlett2_device_info s2i2_gen3_info = { static const struct scarlett2_device_info s4i4_gen3_info = { .has_msd_mode = 1, - .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .config_set = SCARLETT2_CONFIG_SET_GEN_3B, .level_input_count = 2, .pad_input_count = 2, .air_input_count = 2, @@ -660,7 +660,7 @@ static const struct scarlett2_device_info s4i4_gen3_info = { static const struct scarlett2_device_info s8i6_gen3_info = { .has_msd_mode = 1, - .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .config_set = SCARLETT2_CONFIG_SET_GEN_3B, .level_input_count = 2, .pad_input_count = 2, .air_input_count = 2, @@ -711,7 +711,7 @@ static const struct scarlett2_device_info s8i6_gen3_info = { static const struct scarlett2_device_info s18i8_gen3_info = { .has_msd_mode = 1, - .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .config_set = SCARLETT2_CONFIG_SET_GEN_3B, .line_out_hw_vol = 1, .has_speaker_switching = 1, .level_input_count = 2, @@ -779,7 +779,7 @@ static const struct scarlett2_device_info s18i8_gen3_info = { static const struct scarlett2_device_info s18i20_gen3_info = { .has_msd_mode = 1, - .config_set = SCARLETT2_CONFIG_SET_GEN_3, + .config_set = SCARLETT2_CONFIG_SET_GEN_3B, .line_out_hw_vol = 1, .has_speaker_switching = 1, .has_talkback = 1, @@ -1116,28 +1116,8 @@ static const struct scarlett2_config scarlett2_config_items[SCARLETT2_CONFIG_SET_COUNT] [SCARLETT2_CONFIG_COUNT] = -/* Devices without a mixer (Gen 3 Solo and 2i2) */ -{ { - [SCARLETT2_CONFIG_MSD_SWITCH] = { - .offset = 0x04, .size = 8, .activate = 6 }, - - [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = { - .offset = 0x05, .size = 8, .activate = 6 }, - - [SCARLETT2_CONFIG_PHANTOM_SWITCH] = { - .offset = 0x06, .size = 8, .activate = 3 }, - - [SCARLETT2_CONFIG_DIRECT_MONITOR] = { - .offset = 0x07, .size = 8, .activate = 4 }, - - [SCARLETT2_CONFIG_LEVEL_SWITCH] = { - .offset = 0x08, .size = 1, .activate = 7 }, - - [SCARLETT2_CONFIG_AIR_SWITCH] = { - .offset = 0x09, .size = 1, .activate = 8 }, - /* Gen 2 devices: 6i6, 18i8, 18i20 */ -}, { +{ { [SCARLETT2_CONFIG_DIM_MUTE] = { .offset = 0x31, .size = 8, .activate = 2 }, @@ -1159,6 +1139,26 @@ static const struct scarlett2_config [SCARLETT2_CONFIG_STANDALONE_SWITCH] = { .offset = 0x8d, .size = 8, .activate = 6 }, +/* Gen 3 devices without a mixer (Solo and 2i2) */ +}, { + [SCARLETT2_CONFIG_MSD_SWITCH] = { + .offset = 0x04, .size = 8, .activate = 6 }, + + [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = { + .offset = 0x05, .size = 8, .activate = 6 }, + + [SCARLETT2_CONFIG_PHANTOM_SWITCH] = { + .offset = 0x06, .size = 8, .activate = 3 }, + + [SCARLETT2_CONFIG_DIRECT_MONITOR] = { + .offset = 0x07, .size = 8, .activate = 4 }, + + [SCARLETT2_CONFIG_LEVEL_SWITCH] = { + .offset = 0x08, .size = 1, .activate = 7 }, + + [SCARLETT2_CONFIG_AIR_SWITCH] = { + .offset = 0x09, .size = 1, .activate = 8 }, + /* Gen 3 devices: 4i4, 8i6, 18i8, 18i20 */ }, { [SCARLETT2_CONFIG_DIM_MUTE] = { @@ -1907,7 +1907,7 @@ static int scarlett2_add_sync_ctl(struct usb_mixer_interface *mixer) struct scarlett2_data *private = mixer->private_data; /* devices without a mixer also don't support reporting sync status */ - if (private->info->config_set == SCARLETT2_CONFIG_SET_NO_MIXER) + if (private->info->config_set == SCARLETT2_CONFIG_SET_GEN_3A) return 0; return scarlett2_add_new_ctl(mixer, &scarlett2_sync_ctl, @@ -3614,7 +3614,7 @@ static int scarlett2_add_meter_ctl(struct usb_mixer_interface *mixer) struct scarlett2_data *private = mixer->private_data; /* devices without a mixer also don't support reporting levels */ - if (private->info->config_set == SCARLETT2_CONFIG_SET_NO_MIXER) + if (private->info->config_set == SCARLETT2_CONFIG_SET_GEN_3A) return 0; return scarlett2_add_new_ctl(mixer, &scarlett2_meter_ctl, @@ -3744,7 +3744,7 @@ static int scarlett2_add_standalone_ctl(struct usb_mixer_interface *mixer) { struct scarlett2_data *private = mixer->private_data; - if (private->info->config_set == SCARLETT2_CONFIG_SET_NO_MIXER) + if (private->info->config_set == SCARLETT2_CONFIG_SET_GEN_3A) return 0; /* Add standalone control */ @@ -3911,7 +3911,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer) return err; /* the rest of the configuration is for devices with a mixer */ - if (info->config_set == SCARLETT2_CONFIG_SET_NO_MIXER) + if (info->config_set == SCARLETT2_CONFIG_SET_GEN_3A) return 0; err = scarlett2_usb_get_config( From patchwork Thu Oct 26 18:05:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 13437782 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 71655C25B67 for ; Thu, 26 Oct 2023 18:07:21 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B5D70A4B; Thu, 26 Oct 2023 20:06:29 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B5D70A4B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1698343639; bh=Gm5lKEdmAUzGHr5DsgvREl1eTfW1Ldc5Sao8k55pSbY=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=EXIfxqQx3ili7MRPudgAMU2iJXhfiAP+/POcqXOmVyN4/jeT7AYhajnNFML6LB8Y2 d9AlZzz0SvToyNVY0l1TULmIwgKDEpCrUo+Zs4hpztPyzW2E5TZrCvLJCVEOqy+AhX r0N+I4qe1wvqT2G1puqF9rl/SjVgbZ2pNIahYFCA= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 53942F80558; Thu, 26 Oct 2023 20:05:59 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id D1723F8019B; Thu, 26 Oct 2023 20:05:58 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 553C6F8019B; Thu, 26 Oct 2023 20:05:55 +0200 (CEST) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 54B92F8014B for ; Thu, 26 Oct 2023 20:05:50 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 54B92F8014B Received: by m.b4.vu (Postfix, from userid 1000) id B5525604F28E; Fri, 27 Oct 2023 04:35:46 +1030 (ACDT) Date: Fri, 27 Oct 2023 04:35:46 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: alsa-devel@alsa-project.org Subject: [PATCH 3/5] ALSA: scarlett2: Add support for reading firmware version Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: JK7NWJIH52RYSMG4T6QN2ZFYV4GYZVZU X-Message-ID-Hash: JK7NWJIH52RYSMG4T6QN2ZFYV4GYZVZU X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The 84 bytes read during initialisation step 2 were previously ignored. This patch retrieves the firmware version from bytes 8-11, stores it in the scarlett2_data struct, and makes it available through a new control "Firmware Version". Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 62 +++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 2f9619bc6d4f..9badb08177b5 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -406,6 +406,7 @@ struct scarlett2_data { __u8 bInterval; int num_mux_srcs; int num_mux_dsts; + u32 firmware_version; u16 scarlett2_seq; u8 sync_updated; u8 vol_updated; @@ -1856,6 +1857,44 @@ static int scarlett2_add_new_ctl(struct usb_mixer_interface *mixer, return 0; } +/*** Firmware Version Control ***/ + +static int scarlett2_firmware_version_ctl_get( + struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_info *elem = kctl->private_data; + struct scarlett2_data *private = elem->head.mixer->private_data; + + ucontrol->value.integer.value[0] = private->firmware_version; + + return 0; +} + +static int scarlett2_firmware_version_ctl_info( + struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + + return 0; +} + +static const struct snd_kcontrol_new scarlett2_firmware_version_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .name = "", + .info = scarlett2_firmware_version_ctl_info, + .get = scarlett2_firmware_version_ctl_get +}; + +static int scarlett2_add_firmware_version_ctl( + struct usb_mixer_interface *mixer) +{ + return scarlett2_add_new_ctl(mixer, &scarlett2_firmware_version_ctl, + 0, 0, "Firmware Version", NULL); +} /*** Sync Control ***/ /* Update sync control after receiving notification that the status @@ -3854,7 +3893,8 @@ static int scarlett2_usb_init(struct usb_mixer_interface *mixer) { struct usb_device *dev = mixer->chip->dev; struct scarlett2_data *private = mixer->private_data; - u8 buf[24]; + u8 step0_buf[24]; + u8 step2_buf[84]; int err; if (usb_pipe_type_check(dev, usb_sndctrlpipe(dev, 0))) @@ -3862,7 +3902,8 @@ static int scarlett2_usb_init(struct usb_mixer_interface *mixer) /* step 0 */ err = scarlett2_usb_rx(dev, private->bInterfaceNumber, - SCARLETT2_USB_CMD_INIT, buf, sizeof(buf)); + SCARLETT2_USB_CMD_INIT, + step0_buf, sizeof(step0_buf)); if (err < 0) return err; @@ -3874,7 +3915,19 @@ static int scarlett2_usb_init(struct usb_mixer_interface *mixer) /* step 2 */ private->scarlett2_seq = 1; - return scarlett2_usb(mixer, SCARLETT2_USB_INIT_2, NULL, 0, NULL, 84); + err = scarlett2_usb(mixer, SCARLETT2_USB_INIT_2, + NULL, 0, + step2_buf, sizeof(step2_buf)); + if (err < 0) + return err; + + /* extract 4-byte firmware version from step2_buf[8] */ + private->firmware_version = le32_to_cpu(*(__le32 *)(step2_buf + 8)); + usb_audio_info(mixer->chip, + "Firmware version %d\n", + private->firmware_version); + + return 0; } /* Read configuration from the interface on start */ @@ -4192,6 +4245,9 @@ static int snd_scarlett2_controls_create( if (err < 0) return err; + /* Add firmware version control */ + err = scarlett2_add_firmware_version_ctl(mixer); + /* Read volume levels and controls from the interface */ err = scarlett2_read_configs(mixer); if (err < 0) From patchwork Thu Oct 26 18:06:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 13437783 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 01D58C25B67 for ; Thu, 26 Oct 2023 18:07:41 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 030A0A4D; Thu, 26 Oct 2023 20:06:50 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 030A0A4D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1698343660; bh=A7g++7MmHeakfIWdu8Bsiz3vVlF8JnKzBYBXufhHHPw=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=I+J4+1n1id2krfbgV5gnyrRIH1t/DVn5hrBw9zUSyBVeLatnjGj8MtYGz/vqPNOOz SYQriHyySUJyVtDXisYYKnoWl7oO8y5tPr94wFpODLxGvoDs5vwwBFb1pydQ30//ld uP/M7LNlsK55HIk8rsa0aFjKlj63ZB52nV3hfSEU= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 99D0AF8055C; Thu, 26 Oct 2023 20:06:27 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id 40CCCF8055B; Thu, 26 Oct 2023 20:06:27 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 23813F8055B; Thu, 26 Oct 2023 20:06:23 +0200 (CEST) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 83138F8019B for ; Thu, 26 Oct 2023 20:06:20 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 83138F8019B Received: by m.b4.vu (Postfix, from userid 1000) id 854BC604F28E; Fri, 27 Oct 2023 04:36:16 +1030 (ACDT) Date: Fri, 27 Oct 2023 04:36:16 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: alsa-devel@alsa-project.org Subject: [PATCH 4/5] ALSA: scarlett2: Allow passing any output to line_out_remap() Message-ID: <3b70267931f5994628ab27306c73cddd17b93c8f.1698342632.git.g@b4.vu> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: LQ34FDGOFLBZWMYORPPXOW6B4AO5XMTF X-Message-ID-Hash: LQ34FDGOFLBZWMYORPPXOW6B4AO5XMTF X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Line outputs 3 & 4 on the Gen 3 18i8 are internally the analogue 7 and 8 outputs, and this renumbering is hidden from the user by line_out_remap(). By allowing higher values (representing non-analogue outputs) to be passed to line_out_remap(), repeated code from scarlett2_mux_src_enum_ctl_get() and scarlett2_mux_src_enum_ctl_put() can be removed. Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 9badb08177b5..48cd765cf36d 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -2026,9 +2026,16 @@ static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl, static int line_out_remap(struct scarlett2_data *private, int index) { const struct scarlett2_device_info *info = private->info; + const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; + int line_out_count = + port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; if (!info->line_out_remap_enable) return index; + + if (index >= line_out_count) + return index; + return info->line_out_remap[index]; } @@ -3513,14 +3520,7 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - const struct scarlett2_device_info *info = private->info; - const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; - int line_out_count = - port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; - int index = elem->control; - - if (index < line_out_count) - index = line_out_remap(private, index); + int index = line_out_remap(private, elem->control); mutex_lock(&private->data_mutex); if (private->mux_updated) @@ -3537,16 +3537,9 @@ static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - const struct scarlett2_device_info *info = private->info; - const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; - int line_out_count = - port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; - int index = elem->control; + int index = line_out_remap(private, elem->control); int oval, val, err = 0; - if (index < line_out_count) - index = line_out_remap(private, index); - mutex_lock(&private->data_mutex); oval = private->mux[index]; From patchwork Thu Oct 26 18:08:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Geoffrey D. Bennett" X-Patchwork-Id: 13437784 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AAD38C25B67 for ; Thu, 26 Oct 2023 18:10:00 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 0B694A4A; Thu, 26 Oct 2023 20:09:09 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 0B694A4A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1698343799; bh=UiOY2ygZAN8S9KIBqZTjjg+cyOItDiUqTFio6y9BouU=; h=Date:From:To:Cc:Subject:References:In-Reply-To:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=JKUtrEej6QxTtnbVqz44wRnfiasub0H7g0/W3dbYoEnNtLum9KCPWFIUIqA5nd1ZW pg95CdMchQojzH1UP0MC5VChSLpKndU38clxn2FdJdQ6FloxHEvhSJyX/clXsaP0dn 8lI2j6jk/ggDULJ7d1LTu4gg9/AThcRBKvckZDuI= Received: by alsa1.perex.cz (Postfix, from userid 50401) id 478F9F80557; Thu, 26 Oct 2023 20:08:39 +0200 (CEST) Received: from mailman-core.alsa-project.org (mailman-core.alsa-project.org [10.254.200.10]) by alsa1.perex.cz (Postfix) with ESMTP id CE12EF8019B; Thu, 26 Oct 2023 20:08:38 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id E1FE9F8019B; Thu, 26 Oct 2023 20:08:35 +0200 (CEST) Received: from m.b4.vu (m.b4.vu [203.16.231.148]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B55F8F8014B for ; Thu, 26 Oct 2023 20:08:30 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B55F8F8014B Received: by m.b4.vu (Postfix, from userid 1000) id CE860604F28E; Fri, 27 Oct 2023 04:38:26 +1030 (ACDT) Date: Fri, 27 Oct 2023 04:38:26 +1030 From: "Geoffrey D. Bennett" To: Takashi Iwai Cc: alsa-devel@alsa-project.org Subject: [PATCH 5/5] ALSA: scarlett2: Remap Level Meter values Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Message-ID-Hash: NMYGE2XB522XLTG6LOTUNDGBQVXG6OTO X-Message-ID-Hash: NMYGE2XB522XLTG6LOTUNDGBQVXG6OTO X-MailFrom: g@b4.vu X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-alsa-devel.alsa-project.org-0; header-match-alsa-devel.alsa-project.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.8 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The values previously returned by the Level Meter control were passed through from the interface without interpretation, but it has been discovered that the order of the values matches the mux assignment order (which is not presented to userspace). In addition, the values for disabled mux outputs, and mux outputs which share a source are invalid. This patch adds a per-device meter_map[], and a dynamic meter_level_map[] which is updated on routing changes. The meter level map gets used by scarlett2_meter_ctl_get() to both present the values in a standard order, and to fix up the invalid values by zeroing them (for disabled outputs) and copying them (for mux outputs which share a source). Signed-off-by: Geoffrey D. Bennett --- sound/usb/mixer_scarlett2.c | 188 +++++++++++++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 2 deletions(-) diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 48cd765cf36d..f6d1fdfa88e1 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -210,6 +210,9 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = { */ #define SCARLETT2_MUX_MAX 77 +/* Maximum number of sources (sum of input port counts) */ +#define SCARLETT2_MAX_SRCS 52 + /* Maximum number of meters (sum of output port counts) */ #define SCARLETT2_MAX_METERS 65 @@ -328,6 +331,18 @@ struct scarlett2_mux_entry { u8 count; }; +/* Maximum number of entries in a mux table */ +#define SCARLETT2_MAX_METER_ENTRIES 9 + +/* One entry within meter_assignment defines the range of mux outputs + * that consecutive meter entries are mapped to. The end of the list + * is marked with count == 0. + */ +struct scarlett2_meter_entry { + u8 start; + u8 count; +}; + struct scarlett2_device_info { /* Gen 3 devices have an internal MSD mode switch that needs * to be disabled in order to access the full functionality of @@ -381,6 +396,7 @@ struct scarlett2_device_info { */ u8 line_out_remap_enable; u8 line_out_remap[SCARLETT2_ANALOGUE_MAX]; + u8 line_out_unmap[SCARLETT2_ANALOGUE_MAX]; /* additional description for the line out volume controls */ const char * const line_out_descrs[SCARLETT2_ANALOGUE_MAX]; @@ -391,6 +407,12 @@ struct scarlett2_device_info { /* layout/order of the entries in the set_mux message */ struct scarlett2_mux_entry mux_assignment[SCARLETT2_MUX_TABLES] [SCARLETT2_MAX_MUX_ENTRIES]; + + /* map from meter level order returned by + * SCARLETT2_USB_GET_METER to index into mux[] entries (same + * as the order returned by scarlett2_meter_ctl_get()) + */ + struct scarlett2_meter_entry meter_map[SCARLETT2_MAX_METER_ENTRIES]; }; struct scarlett2_data { @@ -431,6 +453,7 @@ struct scarlett2_data { u8 talkback_map[SCARLETT2_OUTPUT_MIX_MAX]; u8 msd_switch; u8 standalone_switch; + u8 meter_level_map[SCARLETT2_MAX_METERS]; struct snd_kcontrol *sync_ctl; struct snd_kcontrol *master_vol_ctl; struct snd_kcontrol *vol_ctls[SCARLETT2_ANALOGUE_MAX]; @@ -493,6 +516,12 @@ static const struct scarlett2_device_info s6i6_gen2_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 8 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 24, 6 }, + { 0, 24 }, + { 0, 0 }, + } }; static const struct scarlett2_device_info s18i8_gen2_info = { @@ -540,6 +569,12 @@ static const struct scarlett2_device_info s18i8_gen2_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 4 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 26, 18 }, + { 0, 26 }, + { 0, 0 }, + } }; static const struct scarlett2_device_info s18i20_gen2_info = { @@ -592,6 +627,12 @@ static const struct scarlett2_device_info s18i20_gen2_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 6 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 38, 18 }, + { 0, 38 }, + { 0, 0 }, + } }; static const struct scarlett2_device_info solo_gen3_info = { @@ -657,6 +698,12 @@ static const struct scarlett2_device_info s4i4_gen3_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 16 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 12, 6 }, + { 0, 12 }, + { 0, 0 }, + } }; static const struct scarlett2_device_info s8i6_gen3_info = { @@ -708,6 +755,14 @@ static const struct scarlett2_device_info s8i6_gen3_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 18 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 14, 8 }, + { 0, 6 }, + { 22, 2 }, + { 6, 8 }, + { 0, 0 }, + } }; static const struct scarlett2_device_info s18i8_gen3_info = { @@ -723,6 +778,7 @@ static const struct scarlett2_device_info s18i8_gen3_info = { .line_out_remap_enable = 1, .line_out_remap = { 0, 1, 6, 7, 2, 3, 4, 5 }, + .line_out_unmap = { 0, 1, 4, 5, 6, 7, 2, 3 }, .line_out_descrs = { "Monitor L", @@ -776,6 +832,18 @@ static const struct scarlett2_device_info s18i8_gen3_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 10 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 30, 10 }, + { 42, 8 }, + { 0, 2 }, + { 6, 2 }, + { 2, 4 }, + { 8, 2 }, + { 40, 2 }, + { 10, 20 }, + { 0, 0 } + } }; static const struct scarlett2_device_info s18i20_gen3_info = { @@ -839,6 +907,15 @@ static const struct scarlett2_device_info s18i20_gen3_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 24 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 45, 8 }, + { 55, 10 }, + { 0, 20 }, + { 53, 2 }, + { 20, 25 }, + { 0, 0 }, + } }; static const struct scarlett2_device_info clarett_2pre_info = { @@ -881,6 +958,12 @@ static const struct scarlett2_device_info clarett_2pre_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 26 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 22, 12 }, + { 0, 22 }, + { 0, 0 } + } }; static const struct scarlett2_device_info clarett_4pre_info = { @@ -928,6 +1011,12 @@ static const struct scarlett2_device_info clarett_4pre_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 24 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 26, 18 }, + { 0, 26 }, + { 0, 0 } + } }; static const struct scarlett2_device_info clarett_8pre_info = { @@ -981,6 +1070,12 @@ static const struct scarlett2_device_info clarett_8pre_info = { { SCARLETT2_PORT_TYPE_NONE, 0, 22 }, { 0, 0, 0 }, } }, + + .meter_map = { + { 38, 18 }, + { 0, 38 }, + { 0, 0 } + } }; struct scarlett2_device_entry { @@ -1688,6 +1783,79 @@ static void scarlett2_usb_populate_mux(struct scarlett2_data *private, private->mux[dst_idx] = src_idx; } +/* Update the meter level map + * + * The meter level data from the interface (SCARLETT2_USB_GET_METER + * request) is returned in mux_assignment order, but to avoid exposing + * that to userspace, scarlett2_meter_ctl_get() rearranges the data + * into scarlett2_ports order using the meter_level_map[] array which + * is set up by this function. + * + * In addition, the meter level data values returned from the + * interface are invalid for destinations where: + * + * - the source is "Off"; therefore we set those values to zero (map + * value of 255) + * + * - the source is assigned to a previous (with respect to the + * mux_assignment order) destination; therefore we set those values + * to the value previously reported for that source + */ +static void scarlett2_update_meter_level_map(struct scarlett2_data *private) +{ + const struct scarlett2_device_info *info = private->info; + const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count; + int line_out_count = + port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT]; + const struct scarlett2_meter_entry *entry; + + /* sources already assigned to a destination + * value is 255 for None, otherwise the value of i + * (index into array returned by + * scarlett2_usb_get_meter_levels()) + */ + u8 seen_src[SCARLETT2_MAX_SRCS] = { 1 }; + u8 seen_src_value[SCARLETT2_MAX_SRCS] = { 255 }; + + /* index in meter_map[] order */ + int i = 0; + + /* go through the meter_map[] entries */ + for (entry = info->meter_map; + entry->count; + entry++) { + + /* fill in each meter_level_map[] entry */ + int j, mux_idx; + + for (j = 0, mux_idx = entry->start; + j < entry->count; + i++, j++, mux_idx++) { + + /* convert mux_idx using line_out_unmap[] */ + int map_mux_idx = ( + info->line_out_remap_enable && + mux_idx < line_out_count + ) ? info->line_out_unmap[mux_idx] + : mux_idx; + + /* check which source is connected, and if + * that source is already connected elsewhere, + * use that existing connection's destination + * for this meter entry instead + */ + int mux_src = private->mux[mux_idx]; + + if (!seen_src[mux_src]) { + seen_src[mux_src] = 1; + seen_src_value[mux_src] = i; + } + private->meter_level_map[map_mux_idx] = + seen_src_value[mux_src]; + } + } +} + /* Send USB message to get mux inputs and then populate private->mux[] */ static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer) { @@ -1716,6 +1884,8 @@ static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer) for (i = 0; i < count; i++) scarlett2_usb_populate_mux(private, le32_to_cpu(data[i])); + scarlett2_update_meter_level_map(private); + return 0; } @@ -1782,6 +1952,8 @@ static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer) return err; } + scarlett2_update_meter_level_map(private); + return 0; } @@ -3619,6 +3791,8 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol) { struct usb_mixer_elem_info *elem = kctl->private_data; + struct scarlett2_data *private = elem->head.mixer->private_data; + u8 *meter_level_map = private->meter_level_map; u16 meter_levels[SCARLETT2_MAX_METERS]; int i, err; @@ -3627,8 +3801,18 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, if (err < 0) return err; - for (i = 0; i < elem->channels; i++) - ucontrol->value.integer.value[i] = meter_levels[i]; + /* copy & translate from meter_levels[] using meter_level_map[] */ + for (i = 0; i < elem->channels; i++) { + int idx = meter_level_map[i]; + int value; + + if (idx == 255) + value = 0; + else + value = meter_levels[idx]; + + ucontrol->value.integer.value[i] = value; + } return 0; }