[PATCH 0/4] ALSA: scarlett2: Driver updates
Hi Takashi,
I think it's time to enable this driver by default because:
- Early versions of this mixer driver did not work on all hardware, so out of caution the driver was disabled by default and had to be explicitly enabled with device_setup=1.
- Since commit 764fa6e686e0 ("ALSA: usb-audio: scarlett2: Fix device hang with ehci-pci") (21/May/2021) no more problems of this nature have been reported.
- Therefore, patch 1 in this series proposes to enable the driver by default, but provide a new device_setup option to disable the driver in case that is needed.
Patch 3 adds support for the Clarett 8Pre USB. This is the first device supported by this driver which is controlled identically to another, so patch 2 first allows sharing the device_info struct between models.
Patch 4 adds the specific product series name (like "Scarlett Gen 2") to various messages so the text is correct without being unwieldy & generic (like "Scarlett Gen 2/3/Clarett USB/Clarett+").
Geoffrey D. Bennett (4): ALSA: scarlett2: Default mixer driver to enabled ALSA: scarlett2: Move USB IDs out from device_info struct ALSA: scarlett2: Add support for Clarett 8Pre USB ALSA: scarlett2: Add correct product series name to messages
sound/usb/mixer_quirks.c | 1 + sound/usb/mixer_scarlett_gen2.c | 148 ++++++++++++++++++-------------- 2 files changed, 83 insertions(+), 66 deletions(-)
Early versions of this mixer driver did not work on all hardware, so out of caution the driver was disabled by default and had to be explicitly enabled with device_setup=1.
Since commit 764fa6e686e0 ("ALSA: usb-audio: scarlett2: Fix device hang with ehci-pci") no more problems of this nature have been reported. Therefore, enable the driver by default but provide a new device_setup option to disable the driver in case that is needed.
- device_setup value of 0 now means "enable" rather than "disable". - device_setup value of 1 is now ignored. - device_setup value of 4 now means "disable".
Signed-off-by: Geoffrey D. Bennett g@b4.vu --- sound/usb/mixer_scarlett_gen2.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c index 9d11bb08667e..ecd148ba6908 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett_gen2.c @@ -141,12 +141,12 @@
#include "mixer_scarlett_gen2.h"
-/* device_setup value to enable */ -#define SCARLETT2_ENABLE 0x01 - /* device_setup value to allow turning MSD mode back on */ #define SCARLETT2_MSD_ENABLE 0x02
+/* device_setup value to disable this mixer driver */ +#define SCARLETT2_DISABLE 0x04 + /* some gui mixers can't handle negative ctl values */ #define SCARLETT2_VOLUME_BIAS 127
@@ -4172,19 +4172,20 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer) if (!mixer->protocol) return 0;
- if (!(chip->setup & SCARLETT2_ENABLE)) { + if (chip->setup & SCARLETT2_DISABLE) { usb_audio_info(chip, - "Focusrite Scarlett Gen 2/3 Mixer Driver disabled; " - "use options snd_usb_audio vid=0x%04x pid=0x%04x " - "device_setup=1 to enable and report any issues " - "to g@b4.vu", + "Focusrite Scarlett Gen 2/3 Mixer Driver disabled " + "by modprobe options (snd_usb_audio " + "vid=0x%04x pid=0x%04x device_setup=%d)\n", USB_ID_VENDOR(chip->usb_id), - USB_ID_PRODUCT(chip->usb_id)); + USB_ID_PRODUCT(chip->usb_id), + SCARLETT2_DISABLE); return 0; }
usb_audio_info(chip, - "Focusrite Scarlett Gen 2/3 Mixer Driver enabled pid=0x%04x", + "Focusrite Scarlett Gen 2/3 Mixer Driver enabled (pid=0x%04x); " + "report any issues to g@b4.vu", USB_ID_PRODUCT(chip->usb_id));
err = snd_scarlett_gen2_controls_create(mixer);
By moving the USB IDs from the device_info struct into scarlett2_devices[], that will allow for devices with different USB IDs to share the same device_info.
Tested-by: Philippe Perrot philippe@perrot-net.fr Signed-off-by: Geoffrey D. Bennett g@b4.vu --- sound/usb/mixer_scarlett_gen2.c | 63 ++++++++++++--------------------- 1 file changed, 23 insertions(+), 40 deletions(-)
diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c index ecd148ba6908..e4f1bfc54533 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett_gen2.c @@ -317,8 +317,6 @@ struct scarlett2_mux_entry { };
struct scarlett2_device_info { - u32 usb_id; /* USB device identifier */ - /* Gen 3 devices have an internal MSD mode switch that needs * to be disabled in order to access the full functionality of * the device. @@ -440,8 +438,6 @@ struct scarlett2_data { /*** Model-specific data ***/
static const struct scarlett2_device_info s6i6_gen2_info = { - .usb_id = USB_ID(0x1235, 0x8203), - .config_set = SCARLETT2_CONFIG_SET_GEN_2, .level_input_count = 2, .pad_input_count = 2, @@ -486,8 +482,6 @@ static const struct scarlett2_device_info s6i6_gen2_info = { };
static const struct scarlett2_device_info s18i8_gen2_info = { - .usb_id = USB_ID(0x1235, 0x8204), - .config_set = SCARLETT2_CONFIG_SET_GEN_2, .level_input_count = 2, .pad_input_count = 4, @@ -535,8 +529,6 @@ static const struct scarlett2_device_info s18i8_gen2_info = { };
static const struct scarlett2_device_info s18i20_gen2_info = { - .usb_id = USB_ID(0x1235, 0x8201), - .config_set = SCARLETT2_CONFIG_SET_GEN_2, .line_out_hw_vol = 1,
@@ -589,8 +581,6 @@ static const struct scarlett2_device_info s18i20_gen2_info = { };
static const struct scarlett2_device_info solo_gen3_info = { - .usb_id = USB_ID(0x1235, 0x8211), - .has_msd_mode = 1, .config_set = SCARLETT2_CONFIG_SET_NO_MIXER, .level_input_count = 1, @@ -602,8 +592,6 @@ static const struct scarlett2_device_info solo_gen3_info = { };
static const struct scarlett2_device_info s2i2_gen3_info = { - .usb_id = USB_ID(0x1235, 0x8210), - .has_msd_mode = 1, .config_set = SCARLETT2_CONFIG_SET_NO_MIXER, .level_input_count = 2, @@ -614,8 +602,6 @@ static const struct scarlett2_device_info s2i2_gen3_info = { };
static const struct scarlett2_device_info s4i4_gen3_info = { - .usb_id = USB_ID(0x1235, 0x8212), - .has_msd_mode = 1, .config_set = SCARLETT2_CONFIG_SET_GEN_3, .level_input_count = 2, @@ -660,8 +646,6 @@ static const struct scarlett2_device_info s4i4_gen3_info = { };
static const struct scarlett2_device_info s8i6_gen3_info = { - .usb_id = USB_ID(0x1235, 0x8213), - .has_msd_mode = 1, .config_set = SCARLETT2_CONFIG_SET_GEN_3, .level_input_count = 2, @@ -713,8 +697,6 @@ static const struct scarlett2_device_info s8i6_gen3_info = { };
static const struct scarlett2_device_info s18i8_gen3_info = { - .usb_id = USB_ID(0x1235, 0x8214), - .has_msd_mode = 1, .config_set = SCARLETT2_CONFIG_SET_GEN_3, .line_out_hw_vol = 1, @@ -783,8 +765,6 @@ static const struct scarlett2_device_info s18i8_gen3_info = { };
static const struct scarlett2_device_info s18i20_gen3_info = { - .usb_id = USB_ID(0x1235, 0x8215), - .has_msd_mode = 1, .config_set = SCARLETT2_CONFIG_SET_GEN_3, .line_out_hw_vol = 1, @@ -848,8 +828,6 @@ static const struct scarlett2_device_info s18i20_gen3_info = { };
static const struct scarlett2_device_info clarett_8pre_info = { - .usb_id = USB_ID(0x1235, 0x820c), - .config_set = SCARLETT2_CONFIG_SET_CLARETT, .line_out_hw_vol = 1, .level_input_count = 2, @@ -902,25 +880,30 @@ static const struct scarlett2_device_info clarett_8pre_info = { } }, };
-static const struct scarlett2_device_info *scarlett2_devices[] = { +struct scarlett2_device_entry { + const u32 usb_id; /* USB device identifier */ + const struct scarlett2_device_info *info; +}; + +static const struct scarlett2_device_entry scarlett2_devices[] = { /* Supported Gen 2 devices */ - &s6i6_gen2_info, - &s18i8_gen2_info, - &s18i20_gen2_info, + { USB_ID(0x1235, 0x8203), &s6i6_gen2_info }, + { USB_ID(0x1235, 0x8204), &s18i8_gen2_info }, + { USB_ID(0x1235, 0x8201), &s18i20_gen2_info },
/* Supported Gen 3 devices */ - &solo_gen3_info, - &s2i2_gen3_info, - &s4i4_gen3_info, - &s8i6_gen3_info, - &s18i8_gen3_info, - &s18i20_gen3_info, + { USB_ID(0x1235, 0x8211), &solo_gen3_info }, + { USB_ID(0x1235, 0x8210), &s2i2_gen3_info }, + { USB_ID(0x1235, 0x8212), &s4i4_gen3_info }, + { USB_ID(0x1235, 0x8213), &s8i6_gen3_info }, + { USB_ID(0x1235, 0x8214), &s18i8_gen3_info }, + { USB_ID(0x1235, 0x8215), &s18i20_gen3_info },
/* Supported Clarett+ devices */ - &clarett_8pre_info, + { USB_ID(0x1235, 0x820c), &clarett_8pre_info },
/* End of list */ - NULL + { 0, NULL }, };
/* get the starting port index number for a given port type/direction */ @@ -4072,17 +4055,17 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer)
static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer) { - const struct scarlett2_device_info **info = scarlett2_devices; + const struct scarlett2_device_entry *entry = scarlett2_devices; int err;
- /* Find device in scarlett2_devices */ - while (*info && (*info)->usb_id != mixer->chip->usb_id) - info++; - if (!*info) + /* Find entry in scarlett2_devices */ + while (entry->usb_id && entry->usb_id != mixer->chip->usb_id) + entry++; + if (!entry->usb_id) return -EINVAL;
/* Initialise private data */ - err = scarlett2_init_private(mixer, *info); + err = scarlett2_init_private(mixer, entry->info); if (err < 0) return err;
The Clarett 8Pre USB works the same as the Clarett+ 8Pre, only the USB ID is different.
Tested-by: Philippe Perrot philippe@perrot-net.fr Signed-off-by: Geoffrey D. Bennett g@b4.vu --- sound/usb/mixer_quirks.c | 1 + sound/usb/mixer_scarlett_gen2.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ab0d459f4271..9911859d2750 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -3420,6 +3420,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) case USB_ID(0x1235, 0x8213): /* Focusrite Scarlett 8i6 3rd Gen */ case USB_ID(0x1235, 0x8214): /* Focusrite Scarlett 18i8 3rd Gen */ case USB_ID(0x1235, 0x8215): /* Focusrite Scarlett 18i20 3rd Gen */ + case USB_ID(0x1235, 0x8208): /* Focusrite Clarett 8Pre USB */ case USB_ID(0x1235, 0x820c): /* Focusrite Clarett+ 8Pre */ err = snd_scarlett_gen2_init(mixer); break; diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c index e4f1bfc54533..9b668ea57cb6 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett_gen2.c @@ -1,13 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Focusrite Scarlett Gen 2/3 and Clarett+ Driver for ALSA + * Focusrite Scarlett Gen 2/3 and Clarett USB/Clarett+ Driver for ALSA * * Supported models: * - 6i6/18i8/18i20 Gen 2 * - Solo/2i2/4i4/8i6/18i8/18i20 Gen 3 + * - Clarett 8Pre USB * - Clarett+ 8Pre * - * Copyright (c) 2018-2022 by Geoffrey D. Bennett <g at b4.vu> + * Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu> * Copyright (c) 2020-2021 by Vladimir Sadovnikov sadko4u@gmail.com * Copyright (c) 2022 by Christian Colglazier christian@cacolglazier.com * @@ -56,6 +57,9 @@ * Support for Clarett+ 8Pre added in Aug 2022 by Christian * Colglazier. * + * Support for Clarett 8Pre USB added in Sep 2023 (thanks to Philippe + * Perrot for confirmation). + * * This ALSA mixer gives access to (model-dependent): * - input, output, mixer-matrix muxes * - mixer-matrix gain stages @@ -899,7 +903,8 @@ static const struct scarlett2_device_entry scarlett2_devices[] = { { USB_ID(0x1235, 0x8214), &s18i8_gen3_info }, { USB_ID(0x1235, 0x8215), &s18i20_gen3_info },
- /* Supported Clarett+ devices */ + /* Supported Clarett USB/Clarett+ devices */ + { USB_ID(0x1235, 0x8208), &clarett_8pre_info }, { USB_ID(0x1235, 0x820c), &clarett_8pre_info },
/* End of list */
This driver was originally developed for the Focusrite Scarlett Gen 2 series, but now also supports the Scarlett Gen 3 series, the Clarett 8Pre USB, and the Clarett+ 8Pre. The messages output by the driver on initialisation and error include the identifying text "Scarlett Gen 2/3", but this is no longer accurate, and writing "Scarlett Gen 2/3/Clarett USB/Clarett+" would be unwieldy.
Add series_name field to the scarlett2_device_entry struct so that concise and accurate messages can be output.
Signed-off-by: Geoffrey D. Bennett g@b4.vu --- sound/usb/mixer_scarlett_gen2.c | 81 ++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 27 deletions(-)
diff --git a/sound/usb/mixer_scarlett_gen2.c b/sound/usb/mixer_scarlett_gen2.c index 9b668ea57cb6..481a80e160de 100644 --- a/sound/usb/mixer_scarlett_gen2.c +++ b/sound/usb/mixer_scarlett_gen2.c @@ -391,6 +391,7 @@ struct scarlett2_data { struct mutex data_mutex; /* lock access to this data */ struct delayed_work work; const struct scarlett2_device_info *info; + const char *series_name; __u8 bInterfaceNumber; __u8 bEndpointAddress; __u16 wMaxPacketSize; @@ -887,25 +888,26 @@ static const struct scarlett2_device_info clarett_8pre_info = { struct scarlett2_device_entry { const u32 usb_id; /* USB device identifier */ const struct scarlett2_device_info *info; + const char *series_name; };
static const struct scarlett2_device_entry scarlett2_devices[] = { /* Supported Gen 2 devices */ - { USB_ID(0x1235, 0x8203), &s6i6_gen2_info }, - { USB_ID(0x1235, 0x8204), &s18i8_gen2_info }, - { USB_ID(0x1235, 0x8201), &s18i20_gen2_info }, + { USB_ID(0x1235, 0x8203), &s6i6_gen2_info, "Scarlett Gen 2" }, + { USB_ID(0x1235, 0x8204), &s18i8_gen2_info, "Scarlett Gen 2" }, + { USB_ID(0x1235, 0x8201), &s18i20_gen2_info, "Scarlett Gen 2" },
/* Supported Gen 3 devices */ - { USB_ID(0x1235, 0x8211), &solo_gen3_info }, - { USB_ID(0x1235, 0x8210), &s2i2_gen3_info }, - { USB_ID(0x1235, 0x8212), &s4i4_gen3_info }, - { USB_ID(0x1235, 0x8213), &s8i6_gen3_info }, - { USB_ID(0x1235, 0x8214), &s18i8_gen3_info }, - { USB_ID(0x1235, 0x8215), &s18i20_gen3_info }, + { USB_ID(0x1235, 0x8211), &solo_gen3_info, "Scarlett Gen 3" }, + { USB_ID(0x1235, 0x8210), &s2i2_gen3_info, "Scarlett Gen 3" }, + { USB_ID(0x1235, 0x8212), &s4i4_gen3_info, "Scarlett Gen 3" }, + { USB_ID(0x1235, 0x8213), &s8i6_gen3_info, "Scarlett Gen 3" }, + { USB_ID(0x1235, 0x8214), &s18i8_gen3_info, "Scarlett Gen 3" }, + { USB_ID(0x1235, 0x8215), &s18i20_gen3_info, "Scarlett Gen 3" },
/* Supported Clarett USB/Clarett+ devices */ - { USB_ID(0x1235, 0x8208), &clarett_8pre_info }, - { USB_ID(0x1235, 0x820c), &clarett_8pre_info }, + { USB_ID(0x1235, 0x8208), &clarett_8pre_info, "Clarett USB" }, + { USB_ID(0x1235, 0x820c), &clarett_8pre_info, "Clarett+" },
/* End of list */ { 0, NULL }, @@ -1205,8 +1207,8 @@ static int scarlett2_usb( if (err != req_buf_size) { usb_audio_err( mixer->chip, - "Scarlett Gen 2/3 USB request result cmd %x was %d\n", - cmd, err); + "%s USB request result cmd %x was %d\n", + private->series_name, cmd, err); err = -EINVAL; goto unlock; } @@ -1222,9 +1224,8 @@ static int scarlett2_usb( if (err != resp_buf_size) { usb_audio_err( mixer->chip, - "Scarlett Gen 2/3 USB response result cmd %x was %d " - "expected %zu\n", - cmd, err, resp_buf_size); + "%s USB response result cmd %x was %d expected %zu\n", + private->series_name, cmd, err, resp_buf_size); err = -EINVAL; goto unlock; } @@ -1240,9 +1241,10 @@ static int scarlett2_usb( resp->pad) { usb_audio_err( mixer->chip, - "Scarlett Gen 2/3 USB invalid response; " + "%s USB invalid response; " "cmd tx/rx %d/%d seq %d/%d size %d/%d " "error %d pad %d\n", + private->series_name, le32_to_cpu(req->cmd), le32_to_cpu(resp->cmd), le16_to_cpu(req->seq), le16_to_cpu(resp->seq), resp_size, le16_to_cpu(resp->size), @@ -3721,7 +3723,7 @@ static int scarlett2_find_fc_interface(struct usb_device *dev,
/* Initialise private data */ static int scarlett2_init_private(struct usb_mixer_interface *mixer, - const struct scarlett2_device_info *info) + const struct scarlett2_device_entry *entry) { struct scarlett2_data *private = kzalloc(sizeof(struct scarlett2_data), GFP_KERNEL); @@ -3737,7 +3739,8 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer, mixer->private_free = scarlett2_private_free; mixer->private_suspend = scarlett2_private_suspend;
- private->info = info; + private->info = entry->info; + private->series_name = entry->series_name; scarlett2_count_mux_io(private); private->scarlett2_seq = 0; private->mixer = mixer; @@ -4058,19 +4061,28 @@ static int scarlett2_init_notify(struct usb_mixer_interface *mixer) return usb_submit_urb(mixer->urb, GFP_KERNEL); }
-static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer) +static const struct scarlett2_device_entry *get_scarlett2_device_entry( + struct usb_mixer_interface *mixer) { const struct scarlett2_device_entry *entry = scarlett2_devices; - int err;
/* Find entry in scarlett2_devices */ while (entry->usb_id && entry->usb_id != mixer->chip->usb_id) entry++; if (!entry->usb_id) - return -EINVAL; + return NULL; + + return entry; +} + +static int snd_scarlett_gen2_controls_create( + struct usb_mixer_interface *mixer, + const struct scarlett2_device_entry *entry) +{ + int err;
/* Initialise private data */ - err = scarlett2_init_private(mixer, entry->info); + err = scarlett2_init_private(mixer, entry); if (err < 0) return err;
@@ -4154,17 +4166,30 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer) int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer) { struct snd_usb_audio *chip = mixer->chip; + const struct scarlett2_device_entry *entry; int err;
/* only use UAC_VERSION_2 */ if (!mixer->protocol) return 0;
+ /* find entry in scarlett2_devices */ + entry = get_scarlett2_device_entry(mixer); + if (!entry) { + usb_audio_err(mixer->chip, + "%s: missing device entry for %04x:%04x\n", + __func__, + USB_ID_VENDOR(chip->usb_id), + USB_ID_PRODUCT(chip->usb_id)); + return 0; + } + if (chip->setup & SCARLETT2_DISABLE) { usb_audio_info(chip, - "Focusrite Scarlett Gen 2/3 Mixer Driver disabled " + "Focusrite %s Mixer Driver disabled " "by modprobe options (snd_usb_audio " "vid=0x%04x pid=0x%04x device_setup=%d)\n", + entry->series_name, USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id), SCARLETT2_DISABLE); @@ -4172,14 +4197,16 @@ int snd_scarlett_gen2_init(struct usb_mixer_interface *mixer) }
usb_audio_info(chip, - "Focusrite Scarlett Gen 2/3 Mixer Driver enabled (pid=0x%04x); " + "Focusrite %s Mixer Driver enabled (pid=0x%04x); " "report any issues to g@b4.vu", + entry->series_name, USB_ID_PRODUCT(chip->usb_id));
- err = snd_scarlett_gen2_controls_create(mixer); + err = snd_scarlett_gen2_controls_create(mixer, entry); if (err < 0) usb_audio_err(mixer->chip, - "Error initialising Scarlett Mixer Driver: %d", + "Error initialising %s Mixer Driver: %d", + entry->series_name, err);
return err;
On Thu, 14 Sep 2023 19:31:37 +0200, Geoffrey D. Bennett wrote:
Hi Takashi,
I think it's time to enable this driver by default because:
Early versions of this mixer driver did not work on all hardware, so out of caution the driver was disabled by default and had to be explicitly enabled with device_setup=1.
Since commit 764fa6e686e0 ("ALSA: usb-audio: scarlett2: Fix device hang with ehci-pci") (21/May/2021) no more problems of this nature have been reported.
Therefore, patch 1 in this series proposes to enable the driver by default, but provide a new device_setup option to disable the driver in case that is needed.
Patch 3 adds support for the Clarett 8Pre USB. This is the first device supported by this driver which is controlled identically to another, so patch 2 first allows sharing the device_info struct between models.
Patch 4 adds the specific product series name (like "Scarlett Gen 2") to various messages so the text is correct without being unwieldy & generic (like "Scarlett Gen 2/3/Clarett USB/Clarett+").
Geoffrey D. Bennett (4): ALSA: scarlett2: Default mixer driver to enabled ALSA: scarlett2: Move USB IDs out from device_info struct ALSA: scarlett2: Add support for Clarett 8Pre USB ALSA: scarlett2: Add correct product series name to messages
Applied all four patches now. Thanks.
Takashi
participants (2)
-
Geoffrey D. Bennett
-
Takashi Iwai