* [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4
@ 2023-12-24 19:18 Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 01/23] ALSA: scarlett2: Simplify enums by removing explicit values Geoffrey D. Bennett
` (23 more replies)
0 siblings, 24 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:18 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Hi Takashi,
This series is preparation for adding support for the Focusrite
Scarlett 4th Gen devices. It applies on top of the previous series
https://lore.kernel.org/linux-sound/cover.1703001053.git.g@b4.vu/
"ALSA: scarlett2: Firmware Upgrade and Error Handling Improvements".
There should be no notable functional changes in this series, just
refactoring/restructuring/renaming/reformatting.
Regards,
Geoffrey.
Geoffrey D. Bennett (23):
ALSA: scarlett2: Simplify enums by removing explicit values
ALSA: scarlett2: Infer has_msd_mode from config items
ALSA: scarlett2: Infer standalone switch from config items
ALSA: scarlett2: Check for phantom persistence config item
ALSA: scarlett2: Check presence of mixer using mux_assignment
ALSA: scarlett2: Add config set struct
ALSA: scarlett2: Remove scarlett2_config_sets array
ALSA: scarlett2: Add check for config_item presence
ALSA: scarlett2: Refactor scarlett2_usb_set_config()
ALSA: scarlett2: Refactor scarlett2_config_save()
ALSA: scarlett2: Formatting fixes
ALSA: scarlett2: Parameterise notifications
ALSA: scarlett2: Change num_mux_* from int to u8
ALSA: scarlett2: Refactor common port_count lookups
ALSA: scarlett2: Remove struct scarlett2_usb_volume_status
ALSA: scarlett2: Split dim_mute_update from vol_updated
ALSA: scarlett2: Remove line_out_hw_vol device info entry
ALSA: scarlett2: Allow for interfaces without per-channel volume
ALSA: scarlett2: Add scarlett2_mixer_value_to_db()
ALSA: scarlett2: Add #define for SCARLETT2_MIX_MAX
ALSA: scarlett2: Rename db_scale_scarlett2_gain to volume
ALSA: scarlett2: Split input_other into level/pad/air/phantom
ALSA: scarlett2: Split direct_monitor out from monitor_other
sound/usb/mixer_scarlett2.c | 1536 ++++++++++++++++++++---------------
1 file changed, 879 insertions(+), 657 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 01/23] ALSA: scarlett2: Simplify enums by removing explicit values
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
@ 2023-12-24 19:20 ` Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 02/23] ALSA: scarlett2: Infer has_msd_mode from config items Geoffrey D. Bennett
` (22 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:20 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
This commit removes the explicit integer assignments from the enums.
The actual values matter little, and not assigning explicit values
makes it easier to modify the longer lists in the future.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 76 ++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index f1337a379833..6ab8b4c52357 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -223,11 +223,11 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
* devices, dependent on series and model.
*/
enum {
- 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_GEN_2,
+ SCARLETT2_CONFIG_SET_GEN_3A,
+ SCARLETT2_CONFIG_SET_GEN_3B,
+ SCARLETT2_CONFIG_SET_CLARETT,
+ SCARLETT2_CONFIG_SET_COUNT
};
/* Hardware port types:
@@ -239,35 +239,35 @@ enum {
* - PCM I/O
*/
enum {
- SCARLETT2_PORT_TYPE_NONE = 0,
- SCARLETT2_PORT_TYPE_ANALOGUE = 1,
- SCARLETT2_PORT_TYPE_SPDIF = 2,
- SCARLETT2_PORT_TYPE_ADAT = 3,
- SCARLETT2_PORT_TYPE_MIX = 4,
- SCARLETT2_PORT_TYPE_PCM = 5,
- SCARLETT2_PORT_TYPE_COUNT = 6,
+ SCARLETT2_PORT_TYPE_NONE,
+ SCARLETT2_PORT_TYPE_ANALOGUE,
+ SCARLETT2_PORT_TYPE_SPDIF,
+ SCARLETT2_PORT_TYPE_ADAT,
+ SCARLETT2_PORT_TYPE_MIX,
+ SCARLETT2_PORT_TYPE_PCM,
+ SCARLETT2_PORT_TYPE_COUNT
};
/* I/O count of each port type kept in struct scarlett2_ports */
enum {
- SCARLETT2_PORT_IN = 0,
- SCARLETT2_PORT_OUT = 1,
- SCARLETT2_PORT_DIRNS = 2,
+ SCARLETT2_PORT_IN,
+ SCARLETT2_PORT_OUT,
+ SCARLETT2_PORT_DIRNS
};
/* Dim/Mute buttons on the 18i20 */
enum {
- SCARLETT2_BUTTON_MUTE = 0,
- SCARLETT2_BUTTON_DIM = 1,
- SCARLETT2_DIM_MUTE_COUNT = 2,
+ SCARLETT2_BUTTON_MUTE,
+ SCARLETT2_BUTTON_DIM,
+ SCARLETT2_DIM_MUTE_COUNT
};
/* Flash Write State */
enum {
- SCARLETT2_FLASH_WRITE_STATE_IDLE = 0,
- SCARLETT2_FLASH_WRITE_STATE_SELECTED = 1,
- SCARLETT2_FLASH_WRITE_STATE_ERASING = 2,
- SCARLETT2_FLASH_WRITE_STATE_WRITE = 3
+ SCARLETT2_FLASH_WRITE_STATE_IDLE,
+ SCARLETT2_FLASH_WRITE_STATE_SELECTED,
+ SCARLETT2_FLASH_WRITE_STATE_ERASING,
+ SCARLETT2_FLASH_WRITE_STATE_WRITE
};
static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
@@ -1211,22 +1211,22 @@ struct scarlett2_usb_volume_status {
/* Configuration parameters that can be read and written */
enum {
- SCARLETT2_CONFIG_DIM_MUTE = 0,
- SCARLETT2_CONFIG_LINE_OUT_VOLUME = 1,
- SCARLETT2_CONFIG_MUTE_SWITCH = 2,
- SCARLETT2_CONFIG_SW_HW_SWITCH = 3,
- SCARLETT2_CONFIG_LEVEL_SWITCH = 4,
- SCARLETT2_CONFIG_PAD_SWITCH = 5,
- SCARLETT2_CONFIG_MSD_SWITCH = 6,
- SCARLETT2_CONFIG_AIR_SWITCH = 7,
- SCARLETT2_CONFIG_STANDALONE_SWITCH = 8,
- SCARLETT2_CONFIG_PHANTOM_SWITCH = 9,
- SCARLETT2_CONFIG_PHANTOM_PERSISTENCE = 10,
- SCARLETT2_CONFIG_DIRECT_MONITOR = 11,
- SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH = 12,
- SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE = 13,
- SCARLETT2_CONFIG_TALKBACK_MAP = 14,
- SCARLETT2_CONFIG_COUNT = 15
+ SCARLETT2_CONFIG_DIM_MUTE,
+ SCARLETT2_CONFIG_LINE_OUT_VOLUME,
+ SCARLETT2_CONFIG_MUTE_SWITCH,
+ SCARLETT2_CONFIG_SW_HW_SWITCH,
+ SCARLETT2_CONFIG_LEVEL_SWITCH,
+ SCARLETT2_CONFIG_PAD_SWITCH,
+ SCARLETT2_CONFIG_MSD_SWITCH,
+ SCARLETT2_CONFIG_AIR_SWITCH,
+ SCARLETT2_CONFIG_STANDALONE_SWITCH,
+ SCARLETT2_CONFIG_PHANTOM_SWITCH,
+ SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
+ SCARLETT2_CONFIG_DIRECT_MONITOR,
+ SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH,
+ SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
+ SCARLETT2_CONFIG_TALKBACK_MAP,
+ SCARLETT2_CONFIG_COUNT
};
/* Location, size, and activation command number for the configuration
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 02/23] ALSA: scarlett2: Infer has_msd_mode from config items
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 01/23] ALSA: scarlett2: Simplify enums by removing explicit values Geoffrey D. Bennett
@ 2023-12-24 19:20 ` Geoffrey D. Bennett
2023-12-24 19:21 ` [PATCH 03/23] ALSA: scarlett2: Infer standalone switch " Geoffrey D. Bennett
` (21 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:20 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Rather than storing has_msd_mode in the per-device structure, infer
this from the presence of the SCARLETT2_CONFIG_MSD_SWITCH entry in the
device's configuration set.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 6ab8b4c52357..85a93dd0f354 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -355,12 +355,6 @@ struct scarlett2_meter_entry {
};
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
- * the device.
- */
- u8 has_msd_mode;
-
/* which set of configuration parameters the device uses */
u8 config_set;
@@ -652,7 +646,6 @@ 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_GEN_3A,
.level_input_count = 1,
.level_input_first = 1,
@@ -663,7 +656,6 @@ 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_GEN_3A,
.level_input_count = 2,
.air_input_count = 2,
@@ -673,7 +665,6 @@ 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_3B,
.level_input_count = 2,
.pad_input_count = 2,
@@ -723,7 +714,6 @@ 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_3B,
.level_input_count = 2,
.pad_input_count = 2,
@@ -782,7 +772,6 @@ 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_3B,
.line_out_hw_vol = 1,
.has_speaker_switching = 1,
@@ -863,7 +852,6 @@ 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_3B,
.line_out_hw_vol = 1,
.has_speaker_switching = 1,
@@ -1518,6 +1506,19 @@ static int scarlett2_usb_get(
&req, sizeof(req), buf, size);
}
+/* Return true if the given configuration item is present in the
+ * configuration set used by this device.
+ */
+static int scarlett2_has_config_item(
+ struct scarlett2_data *private, int config_item_num)
+{
+ const struct scarlett2_device_info *info = private->info;
+ const struct scarlett2_config *config_item =
+ &scarlett2_config_items[info->config_set][config_item_num];
+
+ return !!config_item->offset;
+}
+
/* Send a USB message to get configuration parameters; result placed in *buf */
static int scarlett2_usb_get_config(
struct usb_mixer_interface *mixer,
@@ -4170,9 +4171,8 @@ static const struct snd_kcontrol_new scarlett2_msd_ctl = {
static int scarlett2_add_msd_ctl(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
- if (!info->has_msd_mode)
+ if (!scarlett2_has_config_item(private, SCARLETT2_CONFIG_MSD_SWITCH))
return 0;
/* If MSD mode is off, hide the switch by default */
@@ -4488,7 +4488,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
struct scarlett2_usb_volume_status volume_status;
int err, i;
- if (info->has_msd_mode) {
+ if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_MSD_SWITCH)) {
err = scarlett2_usb_get_config(
mixer, SCARLETT2_CONFIG_MSD_SWITCH,
1, &private->msd_switch);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 03/23] ALSA: scarlett2: Infer standalone switch from config items
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 01/23] ALSA: scarlett2: Simplify enums by removing explicit values Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 02/23] ALSA: scarlett2: Infer has_msd_mode from config items Geoffrey D. Bennett
@ 2023-12-24 19:21 ` Geoffrey D. Bennett
2023-12-24 19:21 ` [PATCH 04/23] ALSA: scarlett2: Check for phantom persistence config item Geoffrey D. Bennett
` (20 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:21 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Rather than assuming the standalone switch is present for all devices
with a mixer, instead check for the presence of the
SCARLETT2_CONFIG_STANDALONE_SWITCH config item.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 85a93dd0f354..88571abd4a8d 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -4244,7 +4244,8 @@ 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_GEN_3A)
+ if (!scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_STANDALONE_SWITCH))
return 0;
/* Add standalone control */
@@ -4512,11 +4513,14 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (info->config_set == SCARLETT2_CONFIG_SET_GEN_3A)
return 0;
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_STANDALONE_SWITCH,
- 1, &private->standalone_switch);
- if (err < 0)
- return err;
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_STANDALONE_SWITCH)) {
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_STANDALONE_SWITCH,
+ 1, &private->standalone_switch);
+ if (err < 0)
+ return err;
+ }
err = scarlett2_update_sync(mixer);
if (err < 0)
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 04/23] ALSA: scarlett2: Check for phantom persistence config item
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (2 preceding siblings ...)
2023-12-24 19:21 ` [PATCH 03/23] ALSA: scarlett2: Infer standalone switch " Geoffrey D. Bennett
@ 2023-12-24 19:21 ` Geoffrey D. Bennett
2023-12-24 19:22 ` [PATCH 05/23] ALSA: scarlett2: Check presence of mixer using mux_assignment Geoffrey D. Bennett
` (19 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:21 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Allow for the phantom persistence config item to not exist. This is
needed for the Scarlett Gen 4 series.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 88571abd4a8d..95a9b5c41b3d 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -2621,11 +2621,15 @@ static int scarlett2_update_input_other(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
- 1, &private->phantom_persistence);
- if (err < 0)
- return err;
+ if (scarlett2_has_config_item(
+ private,
+ SCARLETT2_CONFIG_PHANTOM_PERSISTENCE)) {
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
+ 1, &private->phantom_persistence);
+ if (err < 0)
+ return err;
+ }
}
return 0;
@@ -3779,7 +3783,9 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
return err;
}
}
- if (info->phantom_count) {
+ if (info->phantom_count &&
+ scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_PHANTOM_PERSISTENCE)) {
err = scarlett2_add_new_ctl(
mixer, &scarlett2_phantom_persistence_ctl, 0, 1,
"Phantom Power Persistence Capture Switch", NULL);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 05/23] ALSA: scarlett2: Check presence of mixer using mux_assignment
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (3 preceding siblings ...)
2023-12-24 19:21 ` [PATCH 04/23] ALSA: scarlett2: Check for phantom persistence config item Geoffrey D. Bennett
@ 2023-12-24 19:22 ` Geoffrey D. Bennett
2023-12-24 19:22 ` [PATCH 06/23] ALSA: scarlett2: Add config set struct Geoffrey D. Bennett
` (18 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:22 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Currently the presence of a mixer is determined by checking if the
device uses the GEN_3A config set. Add scarlett2_has_mixer() function
which checks for the presence of mux_assignment entries instead.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 95a9b5c41b3d..fc9f360d0e1e 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1680,6 +1680,12 @@ static int scarlett2_usb_get_volume_status(
buf, sizeof(*buf));
}
+/* Return true if the device has a mixer that we can control */
+static int scarlett2_has_mixer(struct scarlett2_data *private)
+{
+ return !!private->info->mux_assignment[0][0].count;
+}
+
/* Send a USB message to get the volumes for all inputs of one mix
* and put the values into private->mix[]
*/
@@ -2175,7 +2181,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_GEN_3A)
+ if (!scarlett2_has_mixer(private))
return 0;
return scarlett2_add_new_ctl(mixer, &scarlett2_sync_ctl,
@@ -4111,7 +4117,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_GEN_3A)
+ if (!scarlett2_has_mixer(private))
return 0;
return scarlett2_add_new_ctl(mixer, &scarlett2_meter_ctl,
@@ -4516,7 +4522,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_GEN_3A)
+ if (!scarlett2_has_mixer(private))
return 0;
if (scarlett2_has_config_item(private,
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 06/23] ALSA: scarlett2: Add config set struct
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (4 preceding siblings ...)
2023-12-24 19:22 ` [PATCH 05/23] ALSA: scarlett2: Check presence of mixer using mux_assignment Geoffrey D. Bennett
@ 2023-12-24 19:22 ` Geoffrey D. Bennett
2023-12-24 19:23 ` [PATCH 07/23] ALSA: scarlett2: Remove scarlett2_config_sets array Geoffrey D. Bennett
` (17 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:22 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Add struct scarlett2_config_set so that data which is common to all
devices in a config set can be stored there rather than in the
model-specific data.
Accordingly, rename scarlett2_config_items[] to
scarlett2_config_sets[].
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 167 +++++++++++++++++++-----------------
1 file changed, 89 insertions(+), 78 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index fc9f360d0e1e..6884b41b6dd6 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1226,119 +1226,130 @@ struct scarlett2_config {
u8 activate;
};
-static const struct scarlett2_config
- scarlett2_config_items[SCARLETT2_CONFIG_SET_COUNT]
- [SCARLETT2_CONFIG_COUNT] =
+struct scarlett2_config_set {
+ const struct scarlett2_config items[SCARLETT2_CONFIG_COUNT];
+};
+
+static const struct scarlett2_config_set
+ scarlett2_config_sets[SCARLETT2_CONFIG_SET_COUNT] =
/* Gen 2 devices: 6i6, 18i8, 18i20 */
-{ {
- [SCARLETT2_CONFIG_DIM_MUTE] = {
- .offset = 0x31, .size = 8, .activate = 2 },
+{ [SCARLETT2_CONFIG_SET_GEN_2] = {
+ .items = {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
- [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
- .offset = 0x34, .size = 16, .activate = 1 },
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
- [SCARLETT2_CONFIG_MUTE_SWITCH] = {
- .offset = 0x5c, .size = 8, .activate = 1 },
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
- [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
- .offset = 0x66, .size = 8, .activate = 3 },
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x7c, .size = 8, .activate = 7 },
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
- [SCARLETT2_CONFIG_PAD_SWITCH] = {
- .offset = 0x84, .size = 8, .activate = 8 },
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
- [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
- .offset = 0x8d, .size = 8, .activate = 6 },
+ [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_SET_GEN_3A] = {
+ .items = {
+ [SCARLETT2_CONFIG_MSD_SWITCH] = {
+ .offset = 0x04, .size = 8, .activate = 6 },
- [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
- .offset = 0x05, .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_PHANTOM_SWITCH] = {
+ .offset = 0x06, .size = 8, .activate = 3 },
- [SCARLETT2_CONFIG_DIRECT_MONITOR] = {
- .offset = 0x07, .size = 8, .activate = 4 },
+ [SCARLETT2_CONFIG_DIRECT_MONITOR] = {
+ .offset = 0x07, .size = 8, .activate = 4 },
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x08, .size = 1, .activate = 7 },
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x08, .size = 1, .activate = 7 },
- [SCARLETT2_CONFIG_AIR_SWITCH] = {
- .offset = 0x09, .size = 1, .activate = 8 },
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x09, .size = 1, .activate = 8 },
+ },
/* Gen 3 devices: 4i4, 8i6, 18i8, 18i20 */
-}, {
- [SCARLETT2_CONFIG_DIM_MUTE] = {
- .offset = 0x31, .size = 8, .activate = 2 },
+}, [SCARLETT2_CONFIG_SET_GEN_3B] = {
+ .items = {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
- [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
- .offset = 0x34, .size = 16, .activate = 1 },
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
- [SCARLETT2_CONFIG_MUTE_SWITCH] = {
- .offset = 0x5c, .size = 8, .activate = 1 },
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
- [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
- .offset = 0x66, .size = 8, .activate = 3 },
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x7c, .size = 8, .activate = 7 },
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
- [SCARLETT2_CONFIG_PAD_SWITCH] = {
- .offset = 0x84, .size = 8, .activate = 8 },
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
- [SCARLETT2_CONFIG_AIR_SWITCH] = {
- .offset = 0x8c, .size = 8, .activate = 8 },
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x8c, .size = 8, .activate = 8 },
- [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
- .offset = 0x95, .size = 8, .activate = 6 },
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x95, .size = 8, .activate = 6 },
- [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
- .offset = 0x9c, .size = 1, .activate = 8 },
+ [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
+ .offset = 0x9c, .size = 1, .activate = 8 },
- [SCARLETT2_CONFIG_MSD_SWITCH] = {
- .offset = 0x9d, .size = 8, .activate = 6 },
+ [SCARLETT2_CONFIG_MSD_SWITCH] = {
+ .offset = 0x9d, .size = 8, .activate = 6 },
- [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
- .offset = 0x9e, .size = 8, .activate = 6 },
+ [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
+ .offset = 0x9e, .size = 8, .activate = 6 },
- [SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH] = {
- .offset = 0x9f, .size = 1, .activate = 10 },
+ [SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH] = {
+ .offset = 0x9f, .size = 1, .activate = 10 },
- [SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE] = {
- .offset = 0xa0, .size = 1, .activate = 10 },
+ [SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE] = {
+ .offset = 0xa0, .size = 1, .activate = 10 },
- [SCARLETT2_CONFIG_TALKBACK_MAP] = {
- .offset = 0xb0, .size = 16, .activate = 10 },
+ [SCARLETT2_CONFIG_TALKBACK_MAP] = {
+ .offset = 0xb0, .size = 16, .activate = 10 },
+ },
/* Clarett USB and Clarett+ devices: 2Pre, 4Pre, 8Pre */
-}, {
- [SCARLETT2_CONFIG_DIM_MUTE] = {
- .offset = 0x31, .size = 8, .activate = 2 },
+}, [SCARLETT2_CONFIG_SET_CLARETT] = {
+ .items = {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
- [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
- .offset = 0x34, .size = 16, .activate = 1 },
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
- [SCARLETT2_CONFIG_MUTE_SWITCH] = {
- .offset = 0x5c, .size = 8, .activate = 1 },
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
- [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
- .offset = 0x66, .size = 8, .activate = 3 },
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x7c, .size = 8, .activate = 7 },
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
- [SCARLETT2_CONFIG_AIR_SWITCH] = {
- .offset = 0x95, .size = 8, .activate = 8 },
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x95, .size = 8, .activate = 8 },
- [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
- .offset = 0x8d, .size = 8, .activate = 6 },
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x8d, .size = 8, .activate = 6 },
+ }
} };
/* proprietary request/response format */
@@ -1514,7 +1525,7 @@ static int scarlett2_has_config_item(
{
const struct scarlett2_device_info *info = private->info;
const struct scarlett2_config *config_item =
- &scarlett2_config_items[info->config_set][config_item_num];
+ &scarlett2_config_sets[info->config_set].items[config_item_num];
return !!config_item->offset;
}
@@ -1527,7 +1538,7 @@ static int scarlett2_usb_get_config(
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
const struct scarlett2_config *config_item =
- &scarlett2_config_items[info->config_set][config_item_num];
+ &scarlett2_config_sets[info->config_set].items[config_item_num];
int size, err, i;
u8 *buf_8;
u8 value;
@@ -1589,7 +1600,7 @@ static int scarlett2_usb_set_config(
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
const struct scarlett2_config *config_item =
- &scarlett2_config_items[info->config_set][config_item_num];
+ &scarlett2_config_sets[info->config_set].items[config_item_num];
struct {
__le32 offset;
__le32 bytes;
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 07/23] ALSA: scarlett2: Remove scarlett2_config_sets array
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (5 preceding siblings ...)
2023-12-24 19:22 ` [PATCH 06/23] ALSA: scarlett2: Add config set struct Geoffrey D. Bennett
@ 2023-12-24 19:23 ` Geoffrey D. Bennett
2023-12-24 19:25 ` [PATCH 08/23] ALSA: scarlett2: Add check for config_item presence Geoffrey D. Bennett
` (16 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:23 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Replace array index into config sets with a pointer to a config set.
Copy the config_set pointer to the scarlett2_data struct.
This simplifies both the definition and use of the config sets.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 361 +++++++++++++++++-------------------
1 file changed, 173 insertions(+), 188 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 6884b41b6dd6..bff777a93d65 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -219,17 +219,6 @@ 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 different sets of configuration parameters across the
- * devices, dependent on series and model.
- */
-enum {
- SCARLETT2_CONFIG_SET_GEN_2,
- SCARLETT2_CONFIG_SET_GEN_3A,
- SCARLETT2_CONFIG_SET_GEN_3B,
- SCARLETT2_CONFIG_SET_CLARETT,
- SCARLETT2_CONFIG_SET_COUNT
-};
-
/* Hardware port types:
* - None (no input to mux)
* - Analogue I/O
@@ -274,6 +263,161 @@ static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
"Mute Playback Switch", "Dim Playback Switch"
};
+/* Configuration parameters that can be read and written */
+enum {
+ SCARLETT2_CONFIG_DIM_MUTE,
+ SCARLETT2_CONFIG_LINE_OUT_VOLUME,
+ SCARLETT2_CONFIG_MUTE_SWITCH,
+ SCARLETT2_CONFIG_SW_HW_SWITCH,
+ SCARLETT2_CONFIG_LEVEL_SWITCH,
+ SCARLETT2_CONFIG_PAD_SWITCH,
+ SCARLETT2_CONFIG_MSD_SWITCH,
+ SCARLETT2_CONFIG_AIR_SWITCH,
+ SCARLETT2_CONFIG_STANDALONE_SWITCH,
+ SCARLETT2_CONFIG_PHANTOM_SWITCH,
+ SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
+ SCARLETT2_CONFIG_DIRECT_MONITOR,
+ SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH,
+ SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
+ SCARLETT2_CONFIG_TALKBACK_MAP,
+ SCARLETT2_CONFIG_COUNT
+};
+
+/* Location, size, and activation command number for the configuration
+ * parameters. Size is in bits and may be 1, 8, or 16.
+ */
+struct scarlett2_config {
+ u8 offset;
+ u8 size;
+ u8 activate;
+};
+
+struct scarlett2_config_set {
+ const struct scarlett2_config items[SCARLETT2_CONFIG_COUNT];
+};
+
+/* Gen 2 devices: 6i6, 18i8, 18i20 */
+static const struct scarlett2_config_set scarlett2_config_set_gen2 = {
+ .items = {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
+
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
+
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
+
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
+
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x8d, .size = 8, .activate = 6 },
+ }
+};
+
+/* Gen 3 devices without a mixer (Solo and 2i2) */
+static const struct scarlett2_config_set scarlett2_config_set_gen3a = {
+ .items = {
+ [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 */
+static const struct scarlett2_config_set scarlett2_config_set_gen3b = {
+ .items = {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
+
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
+
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
+
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
+
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x8c, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x95, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
+ .offset = 0x9c, .size = 1, .activate = 8 },
+
+ [SCARLETT2_CONFIG_MSD_SWITCH] = {
+ .offset = 0x9d, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
+ .offset = 0x9e, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH] = {
+ .offset = 0x9f, .size = 1, .activate = 10 },
+
+ [SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE] = {
+ .offset = 0xa0, .size = 1, .activate = 10 },
+
+ [SCARLETT2_CONFIG_TALKBACK_MAP] = {
+ .offset = 0xb0, .size = 16, .activate = 10 },
+ }
+};
+
+/* Clarett USB and Clarett+ devices: 2Pre, 4Pre, 8Pre */
+static const struct scarlett2_config_set scarlett2_config_set_clarett = {
+ .items = {
+ [SCARLETT2_CONFIG_DIM_MUTE] = {
+ .offset = 0x31, .size = 8, .activate = 2 },
+
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
+
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
+
+ [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
+ .offset = 0x66, .size = 8, .activate = 3 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
+
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x95, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x8d, .size = 8, .activate = 6 },
+ }
+};
+
/* Description of each hardware port type:
* - id: hardware ID of this port type
* - src_descr: printf format string for mux input selections
@@ -356,7 +500,7 @@ struct scarlett2_meter_entry {
struct scarlett2_device_info {
/* which set of configuration parameters the device uses */
- u8 config_set;
+ const struct scarlett2_config_set *config_set;
/* line out hw volume is sw controlled */
u8 line_out_hw_vol;
@@ -429,6 +573,7 @@ struct scarlett2_data {
u8 flash_write_state;
struct delayed_work work;
const struct scarlett2_device_info *info;
+ const struct scarlett2_config_set *config_set;
const char *series_name;
__u8 bInterfaceNumber;
__u8 bEndpointAddress;
@@ -485,7 +630,7 @@ struct scarlett2_data {
/*** Model-specific data ***/
static const struct scarlett2_device_info s6i6_gen2_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_2,
+ .config_set = &scarlett2_config_set_gen2,
.level_input_count = 2,
.pad_input_count = 2,
@@ -535,7 +680,7 @@ static const struct scarlett2_device_info s6i6_gen2_info = {
};
static const struct scarlett2_device_info s18i8_gen2_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_2,
+ .config_set = &scarlett2_config_set_gen2,
.level_input_count = 2,
.pad_input_count = 4,
@@ -588,7 +733,7 @@ static const struct scarlett2_device_info s18i8_gen2_info = {
};
static const struct scarlett2_device_info s18i20_gen2_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_2,
+ .config_set = &scarlett2_config_set_gen2,
.line_out_hw_vol = 1,
.line_out_descrs = {
@@ -646,7 +791,7 @@ static const struct scarlett2_device_info s18i20_gen2_info = {
};
static const struct scarlett2_device_info solo_gen3_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_3A,
+ .config_set = &scarlett2_config_set_gen3a,
.level_input_count = 1,
.level_input_first = 1,
.air_input_count = 1,
@@ -656,7 +801,7 @@ static const struct scarlett2_device_info solo_gen3_info = {
};
static const struct scarlett2_device_info s2i2_gen3_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_3A,
+ .config_set = &scarlett2_config_set_gen3a,
.level_input_count = 2,
.air_input_count = 2,
.phantom_count = 1,
@@ -665,7 +810,7 @@ static const struct scarlett2_device_info s2i2_gen3_info = {
};
static const struct scarlett2_device_info s4i4_gen3_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_3B,
+ .config_set = &scarlett2_config_set_gen3b,
.level_input_count = 2,
.pad_input_count = 2,
.air_input_count = 2,
@@ -714,7 +859,7 @@ static const struct scarlett2_device_info s4i4_gen3_info = {
};
static const struct scarlett2_device_info s8i6_gen3_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_3B,
+ .config_set = &scarlett2_config_set_gen3b,
.level_input_count = 2,
.pad_input_count = 2,
.air_input_count = 2,
@@ -772,7 +917,7 @@ static const struct scarlett2_device_info s8i6_gen3_info = {
};
static const struct scarlett2_device_info s18i8_gen3_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_3B,
+ .config_set = &scarlett2_config_set_gen3b,
.line_out_hw_vol = 1,
.has_speaker_switching = 1,
.level_input_count = 2,
@@ -852,7 +997,7 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
};
static const struct scarlett2_device_info s18i20_gen3_info = {
- .config_set = SCARLETT2_CONFIG_SET_GEN_3B,
+ .config_set = &scarlett2_config_set_gen3b,
.line_out_hw_vol = 1,
.has_speaker_switching = 1,
.has_talkback = 1,
@@ -923,7 +1068,7 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
};
static const struct scarlett2_device_info clarett_2pre_info = {
- .config_set = SCARLETT2_CONFIG_SET_CLARETT,
+ .config_set = &scarlett2_config_set_clarett,
.line_out_hw_vol = 1,
.level_input_count = 2,
.air_input_count = 2,
@@ -971,7 +1116,7 @@ static const struct scarlett2_device_info clarett_2pre_info = {
};
static const struct scarlett2_device_info clarett_4pre_info = {
- .config_set = SCARLETT2_CONFIG_SET_CLARETT,
+ .config_set = &scarlett2_config_set_clarett,
.line_out_hw_vol = 1,
.level_input_count = 2,
.air_input_count = 4,
@@ -1024,7 +1169,7 @@ static const struct scarlett2_device_info clarett_4pre_info = {
};
static const struct scarlett2_device_info clarett_8pre_info = {
- .config_set = SCARLETT2_CONFIG_SET_CLARETT,
+ .config_set = &scarlett2_config_set_clarett,
.line_out_hw_vol = 1,
.level_input_count = 2,
.air_input_count = 8,
@@ -1197,161 +1342,6 @@ struct scarlett2_usb_volume_status {
s16 master_vol;
} __packed;
-/* Configuration parameters that can be read and written */
-enum {
- SCARLETT2_CONFIG_DIM_MUTE,
- SCARLETT2_CONFIG_LINE_OUT_VOLUME,
- SCARLETT2_CONFIG_MUTE_SWITCH,
- SCARLETT2_CONFIG_SW_HW_SWITCH,
- SCARLETT2_CONFIG_LEVEL_SWITCH,
- SCARLETT2_CONFIG_PAD_SWITCH,
- SCARLETT2_CONFIG_MSD_SWITCH,
- SCARLETT2_CONFIG_AIR_SWITCH,
- SCARLETT2_CONFIG_STANDALONE_SWITCH,
- SCARLETT2_CONFIG_PHANTOM_SWITCH,
- SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
- SCARLETT2_CONFIG_DIRECT_MONITOR,
- SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH,
- SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE,
- SCARLETT2_CONFIG_TALKBACK_MAP,
- SCARLETT2_CONFIG_COUNT
-};
-
-/* Location, size, and activation command number for the configuration
- * parameters. Size is in bits and may be 1, 8, or 16.
- */
-struct scarlett2_config {
- u8 offset;
- u8 size;
- u8 activate;
-};
-
-struct scarlett2_config_set {
- const struct scarlett2_config items[SCARLETT2_CONFIG_COUNT];
-};
-
-static const struct scarlett2_config_set
- scarlett2_config_sets[SCARLETT2_CONFIG_SET_COUNT] =
-
-/* Gen 2 devices: 6i6, 18i8, 18i20 */
-{ [SCARLETT2_CONFIG_SET_GEN_2] = {
- .items = {
- [SCARLETT2_CONFIG_DIM_MUTE] = {
- .offset = 0x31, .size = 8, .activate = 2 },
-
- [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
- .offset = 0x34, .size = 16, .activate = 1 },
-
- [SCARLETT2_CONFIG_MUTE_SWITCH] = {
- .offset = 0x5c, .size = 8, .activate = 1 },
-
- [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
- .offset = 0x66, .size = 8, .activate = 3 },
-
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x7c, .size = 8, .activate = 7 },
-
- [SCARLETT2_CONFIG_PAD_SWITCH] = {
- .offset = 0x84, .size = 8, .activate = 8 },
-
- [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
- .offset = 0x8d, .size = 8, .activate = 6 },
- },
-
-/* Gen 3 devices without a mixer (Solo and 2i2) */
-}, [SCARLETT2_CONFIG_SET_GEN_3A] = {
- .items = {
- [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_SET_GEN_3B] = {
- .items = {
- [SCARLETT2_CONFIG_DIM_MUTE] = {
- .offset = 0x31, .size = 8, .activate = 2 },
-
- [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
- .offset = 0x34, .size = 16, .activate = 1 },
-
- [SCARLETT2_CONFIG_MUTE_SWITCH] = {
- .offset = 0x5c, .size = 8, .activate = 1 },
-
- [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
- .offset = 0x66, .size = 8, .activate = 3 },
-
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x7c, .size = 8, .activate = 7 },
-
- [SCARLETT2_CONFIG_PAD_SWITCH] = {
- .offset = 0x84, .size = 8, .activate = 8 },
-
- [SCARLETT2_CONFIG_AIR_SWITCH] = {
- .offset = 0x8c, .size = 8, .activate = 8 },
-
- [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
- .offset = 0x95, .size = 8, .activate = 6 },
-
- [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
- .offset = 0x9c, .size = 1, .activate = 8 },
-
- [SCARLETT2_CONFIG_MSD_SWITCH] = {
- .offset = 0x9d, .size = 8, .activate = 6 },
-
- [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
- .offset = 0x9e, .size = 8, .activate = 6 },
-
- [SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH] = {
- .offset = 0x9f, .size = 1, .activate = 10 },
-
- [SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE] = {
- .offset = 0xa0, .size = 1, .activate = 10 },
-
- [SCARLETT2_CONFIG_TALKBACK_MAP] = {
- .offset = 0xb0, .size = 16, .activate = 10 },
- },
-
-/* Clarett USB and Clarett+ devices: 2Pre, 4Pre, 8Pre */
-}, [SCARLETT2_CONFIG_SET_CLARETT] = {
- .items = {
- [SCARLETT2_CONFIG_DIM_MUTE] = {
- .offset = 0x31, .size = 8, .activate = 2 },
-
- [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
- .offset = 0x34, .size = 16, .activate = 1 },
-
- [SCARLETT2_CONFIG_MUTE_SWITCH] = {
- .offset = 0x5c, .size = 8, .activate = 1 },
-
- [SCARLETT2_CONFIG_SW_HW_SWITCH] = {
- .offset = 0x66, .size = 8, .activate = 3 },
-
- [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
- .offset = 0x7c, .size = 8, .activate = 7 },
-
- [SCARLETT2_CONFIG_AIR_SWITCH] = {
- .offset = 0x95, .size = 8, .activate = 8 },
-
- [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
- .offset = 0x8d, .size = 8, .activate = 6 },
- }
-} };
-
/* proprietary request/response format */
struct scarlett2_usb_packet {
__le32 cmd;
@@ -1523,11 +1513,7 @@ static int scarlett2_usb_get(
static int scarlett2_has_config_item(
struct scarlett2_data *private, int config_item_num)
{
- const struct scarlett2_device_info *info = private->info;
- const struct scarlett2_config *config_item =
- &scarlett2_config_sets[info->config_set].items[config_item_num];
-
- return !!config_item->offset;
+ return !!private->config_set->items[config_item_num].offset;
}
/* Send a USB message to get configuration parameters; result placed in *buf */
@@ -1536,9 +1522,8 @@ static int scarlett2_usb_get_config(
int config_item_num, int count, void *buf)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
const struct scarlett2_config *config_item =
- &scarlett2_config_sets[info->config_set].items[config_item_num];
+ &private->config_set->items[config_item_num];
int size, err, i;
u8 *buf_8;
u8 value;
@@ -1598,9 +1583,8 @@ static int scarlett2_usb_set_config(
int config_item_num, int index, int value)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
const struct scarlett2_config *config_item =
- &scarlett2_config_sets[info->config_set].items[config_item_num];
+ &private->config_set->items[config_item_num];
struct {
__le32 offset;
__le32 bytes;
@@ -4365,6 +4349,7 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
mixer->private_suspend = scarlett2_private_suspend;
private->info = entry->info;
+ private->config_set = entry->info->config_set;
private->series_name = entry->series_name;
scarlett2_count_mux_io(private);
private->scarlett2_seq = 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 08/23] ALSA: scarlett2: Add check for config_item presence
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (6 preceding siblings ...)
2023-12-24 19:23 ` [PATCH 07/23] ALSA: scarlett2: Remove scarlett2_config_sets array Geoffrey D. Bennett
@ 2023-12-24 19:25 ` Geoffrey D. Bennett
2023-12-24 19:26 ` [PATCH 09/23] ALSA: scarlett2: Refactor scarlett2_usb_set_config() Geoffrey D. Bennett
` (15 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:25 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Update scarlett2_usb_get_config() and scarlett2_usb_set_config() to
make sure that the config_item_num is valid for the device.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index bff777a93d65..4849dfeea429 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1528,6 +1528,12 @@ static int scarlett2_usb_get_config(
u8 *buf_8;
u8 value;
+ /* Check that the configuration item is present in the
+ * configuration set used by this device
+ */
+ if (!config_item->offset)
+ return -EFAULT;
+
/* For byte-sized parameters, retrieve directly into buf */
if (config_item->size >= 8) {
size = config_item->size / 8 * count;
@@ -1594,6 +1600,12 @@ static int scarlett2_usb_set_config(
int offset, size;
int err;
+ /* Check that the configuration item is present in the
+ * configuration set used by this device
+ */
+ if (!config_item->offset)
+ return -EFAULT;
+
/* Cancel any pending NVRAM save */
cancel_delayed_work_sync(&private->work);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 09/23] ALSA: scarlett2: Refactor scarlett2_usb_set_config()
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (7 preceding siblings ...)
2023-12-24 19:25 ` [PATCH 08/23] ALSA: scarlett2: Add check for config_item presence Geoffrey D. Bennett
@ 2023-12-24 19:26 ` Geoffrey D. Bennett
2023-12-24 19:27 ` [PATCH 10/23] ALSA: scarlett2: Refactor scarlett2_config_save() Geoffrey D. Bennett
` (14 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:26 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Pull out common code from scarlett2_usb_set_config() and create
scarlett2_usb_set_data() and scarlett2_usb_activate_config().
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 57 ++++++++++++++++++++++++++-----------
1 file changed, 41 insertions(+), 16 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 4849dfeea429..bbc60b94b7bc 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1583,20 +1583,52 @@ static void scarlett2_config_save_work(struct work_struct *work)
scarlett2_config_save(private->mixer);
}
-/* Send a USB message to set a SCARLETT2_CONFIG_* parameter */
-static int scarlett2_usb_set_config(
+/* Send a SCARLETT2_USB_SET_DATA command.
+ * offset: location in the device's data space
+ * size: size in bytes of the value (1, 2, 4)
+ */
+static int scarlett2_usb_set_data(
struct usb_mixer_interface *mixer,
- int config_item_num, int index, int value)
+ int offset, int size, int value)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_config *config_item =
- &private->config_set->items[config_item_num];
struct {
__le32 offset;
- __le32 bytes;
+ __le32 size;
__le32 value;
} __packed req;
- __le32 req2;
+
+ req.offset = cpu_to_le32(offset);
+ req.size = cpu_to_le32(size);
+ req.value = cpu_to_le32(value);
+ return scarlett2_usb(private->mixer, SCARLETT2_USB_SET_DATA,
+ &req, sizeof(u32) * 2 + size, NULL, 0);
+}
+
+/* Send a SCARLETT2_USB_DATA_CMD command.
+ * Configuration changes require activation with this after they have
+ * been uploaded by a previous SCARLETT2_USB_SET_DATA.
+ * The value for activate needed is determined by the configuration
+ * item.
+ */
+static int scarlett2_usb_activate_config(
+ struct usb_mixer_interface *mixer, int activate)
+{
+ __le32 req;
+
+ req = cpu_to_le32(activate);
+ return scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
+ &req, sizeof(req), NULL, 0);
+}
+
+/* Send USB messages to set a SCARLETT2_CONFIG_* parameter */
+static int scarlett2_usb_set_config(
+ struct usb_mixer_interface *mixer,
+ int config_item_num, int index, int value)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_config *config_item =
+ &private->config_set->items[config_item_num];
int offset, size;
int err;
@@ -1638,19 +1670,12 @@ static int scarlett2_usb_set_config(
}
/* Send the configuration parameter data */
- req.offset = cpu_to_le32(offset);
- req.bytes = cpu_to_le32(size);
- req.value = cpu_to_le32(value);
- err = scarlett2_usb(mixer, SCARLETT2_USB_SET_DATA,
- &req, sizeof(u32) * 2 + size,
- NULL, 0);
+ err = scarlett2_usb_set_data(mixer, offset, size, value);
if (err < 0)
return err;
/* Activate the change */
- req2 = cpu_to_le32(config_item->activate);
- err = scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
- &req2, sizeof(req2), NULL, 0);
+ err = scarlett2_usb_activate_config(mixer, config_item->activate);
if (err < 0)
return err;
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 10/23] ALSA: scarlett2: Refactor scarlett2_config_save()
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (8 preceding siblings ...)
2023-12-24 19:26 ` [PATCH 09/23] ALSA: scarlett2: Refactor scarlett2_usb_set_config() Geoffrey D. Bennett
@ 2023-12-24 19:27 ` Geoffrey D. Bennett
2023-12-24 19:27 ` [PATCH 11/23] ALSA: scarlett2: Formatting fixes Geoffrey D. Bennett
` (13 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Use the new scarlett2_usb_activate_config() helper function rather
than preparing the request manually and calling scarlett2_usb().
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 40 ++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index bbc60b94b7bc..f15ee9e6c2eb 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1562,27 +1562,6 @@ static int scarlett2_usb_get_config(
return 0;
}
-/* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
-static void scarlett2_config_save(struct usb_mixer_interface *mixer)
-{
- __le32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE);
-
- int err = scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
- &req, sizeof(u32),
- NULL, 0);
- if (err < 0)
- usb_audio_err(mixer->chip, "config save failed: %d\n", err);
-}
-
-/* Delayed work to save config */
-static void scarlett2_config_save_work(struct work_struct *work)
-{
- struct scarlett2_data *private =
- container_of(work, struct scarlett2_data, work.work);
-
- scarlett2_config_save(private->mixer);
-}
-
/* Send a SCARLETT2_USB_SET_DATA command.
* offset: location in the device's data space
* size: size in bytes of the value (1, 2, 4)
@@ -1686,6 +1665,25 @@ static int scarlett2_usb_set_config(
return 0;
}
+/* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
+static void scarlett2_config_save(struct usb_mixer_interface *mixer)
+{
+ int err;
+
+ err = scarlett2_usb_activate_config(mixer, SCARLETT2_USB_CONFIG_SAVE);
+ if (err < 0)
+ usb_audio_err(mixer->chip, "config save failed: %d\n", err);
+}
+
+/* Delayed work to save config */
+static void scarlett2_config_save_work(struct work_struct *work)
+{
+ struct scarlett2_data *private =
+ container_of(work, struct scarlett2_data, work.work);
+
+ scarlett2_config_save(private->mixer);
+}
+
/* Send a USB message to get sync status; result placed in *sync */
static int scarlett2_usb_get_sync_status(
struct usb_mixer_interface *mixer,
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 11/23] ALSA: scarlett2: Formatting fixes
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (9 preceding siblings ...)
2023-12-24 19:27 ` [PATCH 10/23] ALSA: scarlett2: Refactor scarlett2_config_save() Geoffrey D. Bennett
@ 2023-12-24 19:27 ` Geoffrey D. Bennett
2023-12-24 19:27 ` [PATCH 12/23] ALSA: scarlett2: Parameterise notifications Geoffrey D. Bennett
` (12 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Add missing blank line before comment.
For consistency with other functions that have few parameters, move
the parameters onto the same line as the function name.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index f15ee9e6c2eb..0fd919490cc6 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -2149,6 +2149,7 @@ static int scarlett2_add_firmware_version_ctl(
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
@@ -3373,8 +3374,7 @@ static const struct snd_kcontrol_new scarlett2_speaker_switch_enum_ctl = {
.put = scarlett2_speaker_switch_enum_ctl_put,
};
-static int scarlett2_add_speaker_switch_ctl(
- struct usb_mixer_interface *mixer)
+static int scarlett2_add_speaker_switch_ctl(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
@@ -3542,8 +3542,7 @@ static const struct snd_kcontrol_new scarlett2_talkback_map_ctl = {
.put = scarlett2_talkback_map_ctl_put,
};
-static int scarlett2_add_talkback_ctls(
- struct usb_mixer_interface *mixer)
+static int scarlett2_add_talkback_ctls(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
@@ -4611,8 +4610,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
}
/* Notify on sync change */
-static void scarlett2_notify_sync(
- struct usb_mixer_interface *mixer)
+static void scarlett2_notify_sync(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
@@ -4623,8 +4621,7 @@ static void scarlett2_notify_sync(
}
/* Notify on monitor change */
-static void scarlett2_notify_monitor(
- struct usb_mixer_interface *mixer)
+static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
@@ -4650,8 +4647,7 @@ static void scarlett2_notify_monitor(
}
/* Notify on dim/mute change */
-static void scarlett2_notify_dim_mute(
- struct usb_mixer_interface *mixer)
+static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
@@ -4677,8 +4673,7 @@ static void scarlett2_notify_dim_mute(
}
/* Notify on "input other" change (level/pad/air) */
-static void scarlett2_notify_input_other(
- struct usb_mixer_interface *mixer)
+static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
@@ -4704,8 +4699,7 @@ static void scarlett2_notify_input_other(
/* Notify on "monitor other" change (direct monitor, speaker
* switching, talkback)
*/
-static void scarlett2_notify_monitor_other(
- struct usb_mixer_interface *mixer)
+static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 12/23] ALSA: scarlett2: Parameterise notifications
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (10 preceding siblings ...)
2023-12-24 19:27 ` [PATCH 11/23] ALSA: scarlett2: Formatting fixes Geoffrey D. Bennett
@ 2023-12-24 19:27 ` Geoffrey D. Bennett
2023-12-24 19:28 ` [PATCH 13/23] ALSA: scarlett2: Change num_mux_* from int to u8 Geoffrey D. Bennett
` (11 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:27 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
The notification values were previously #define'd, and checked with a
series of if() statements calling functions. Replace with an array of
masks/callback function pointers, and a pointer to that array in the
scarlett2_config_set definitions.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 62 +++++++++++++++++++++++++++----------
1 file changed, 45 insertions(+), 17 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 0fd919490cc6..64476922eee8 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -263,6 +263,29 @@ static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = {
"Mute Playback Switch", "Dim Playback Switch"
};
+/* Notification callback functions */
+struct scarlett2_notification {
+ u32 mask;
+ void (*func)(struct usb_mixer_interface *mixer);
+};
+
+static void scarlett2_notify_sync(struct usb_mixer_interface *mixer);
+static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer);
+static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer);
+static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer);
+static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer);
+
+/* Array of notification callback functions */
+static const struct scarlett2_notification scarlett2_notifications[] = {
+ { 0x00000001, NULL }, /* ack, gets ignored */
+ { 0x00000008, scarlett2_notify_sync },
+ { 0x00200000, scarlett2_notify_dim_mute },
+ { 0x00400000, scarlett2_notify_monitor },
+ { 0x00800000, scarlett2_notify_input_other },
+ { 0x01000000, scarlett2_notify_monitor_other },
+ { 0, NULL }
+};
+
/* Configuration parameters that can be read and written */
enum {
SCARLETT2_CONFIG_DIM_MUTE,
@@ -293,11 +316,13 @@ struct scarlett2_config {
};
struct scarlett2_config_set {
+ const struct scarlett2_notification *notifications;
const struct scarlett2_config items[SCARLETT2_CONFIG_COUNT];
};
/* Gen 2 devices: 6i6, 18i8, 18i20 */
static const struct scarlett2_config_set scarlett2_config_set_gen2 = {
+ .notifications = scarlett2_notifications,
.items = {
[SCARLETT2_CONFIG_DIM_MUTE] = {
.offset = 0x31, .size = 8, .activate = 2 },
@@ -324,6 +349,7 @@ static const struct scarlett2_config_set scarlett2_config_set_gen2 = {
/* Gen 3 devices without a mixer (Solo and 2i2) */
static const struct scarlett2_config_set scarlett2_config_set_gen3a = {
+ .notifications = scarlett2_notifications,
.items = {
[SCARLETT2_CONFIG_MSD_SWITCH] = {
.offset = 0x04, .size = 8, .activate = 6 },
@@ -347,6 +373,7 @@ static const struct scarlett2_config_set scarlett2_config_set_gen3a = {
/* Gen 3 devices: 4i4, 8i6, 18i8, 18i20 */
static const struct scarlett2_config_set scarlett2_config_set_gen3b = {
+ .notifications = scarlett2_notifications,
.items = {
[SCARLETT2_CONFIG_DIM_MUTE] = {
.offset = 0x31, .size = 8, .activate = 2 },
@@ -394,6 +421,7 @@ static const struct scarlett2_config_set scarlett2_config_set_gen3b = {
/* Clarett USB and Clarett+ devices: 2Pre, 4Pre, 8Pre */
static const struct scarlett2_config_set scarlett2_config_set_clarett = {
+ .notifications = scarlett2_notifications,
.items = {
[SCARLETT2_CONFIG_DIM_MUTE] = {
.offset = 0x31, .size = 8, .activate = 2 },
@@ -1274,13 +1302,6 @@ static int scarlett2_get_port_start_num(
/*** USB Interactions ***/
-/* Notifications from the interface */
-#define SCARLETT2_USB_NOTIFY_SYNC 0x00000008
-#define SCARLETT2_USB_NOTIFY_DIM_MUTE 0x00200000
-#define SCARLETT2_USB_NOTIFY_MONITOR 0x00400000
-#define SCARLETT2_USB_NOTIFY_INPUT_OTHER 0x00800000
-#define SCARLETT2_USB_NOTIFY_MONITOR_OTHER 0x01000000
-
/* Commands for sending/receiving requests/responses */
#define SCARLETT2_USB_CMD_INIT 0
#define SCARLETT2_USB_CMD_REQ 2
@@ -4745,21 +4766,28 @@ static void scarlett2_notify(struct urb *urb)
int len = urb->actual_length;
int ustatus = urb->status;
u32 data;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_notification *notifications =
+ private->config_set->notifications;
if (ustatus != 0 || len != 8)
goto requeue;
data = le32_to_cpu(*(__le32 *)urb->transfer_buffer);
- if (data & SCARLETT2_USB_NOTIFY_SYNC)
- scarlett2_notify_sync(mixer);
- if (data & SCARLETT2_USB_NOTIFY_MONITOR)
- scarlett2_notify_monitor(mixer);
- if (data & SCARLETT2_USB_NOTIFY_DIM_MUTE)
- scarlett2_notify_dim_mute(mixer);
- if (data & SCARLETT2_USB_NOTIFY_INPUT_OTHER)
- scarlett2_notify_input_other(mixer);
- if (data & SCARLETT2_USB_NOTIFY_MONITOR_OTHER)
- scarlett2_notify_monitor_other(mixer);
+
+ while (data && notifications->mask) {
+ if (data & notifications->mask) {
+ data &= ~notifications->mask;
+ if (notifications->func)
+ notifications->func(mixer);
+ }
+ notifications++;
+ }
+
+ if (data)
+ usb_audio_warn(mixer->chip,
+ "%s: Unhandled notification: 0x%08x\n",
+ __func__, data);
requeue:
if (ustatus != -ENOENT &&
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 13/23] ALSA: scarlett2: Change num_mux_* from int to u8
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (11 preceding siblings ...)
2023-12-24 19:27 ` [PATCH 12/23] ALSA: scarlett2: Parameterise notifications Geoffrey D. Bennett
@ 2023-12-24 19:28 ` Geoffrey D. Bennett
2023-12-24 19:28 ` [PATCH 14/23] ALSA: scarlett2: Refactor common port_count lookups Geoffrey D. Bennett
` (10 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:28 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
num_mux_srcs and num_mux_dsts will fit into a u8, so change the type.
More similar counts are coming soon.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 64476922eee8..341f23d448bc 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -607,8 +607,8 @@ struct scarlett2_data {
__u8 bEndpointAddress;
__u16 wMaxPacketSize;
__u8 bInterval;
- int num_mux_srcs;
- int num_mux_dsts;
+ u8 num_mux_srcs;
+ u8 num_mux_dsts;
u32 firmware_version;
u8 flash_segment_nums[SCARLETT2_SEGMENT_ID_COUNT];
u8 flash_segment_blocks[SCARLETT2_SEGMENT_ID_COUNT];
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 14/23] ALSA: scarlett2: Refactor common port_count lookups
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (12 preceding siblings ...)
2023-12-24 19:28 ` [PATCH 13/23] ALSA: scarlett2: Change num_mux_* from int to u8 Geoffrey D. Bennett
@ 2023-12-24 19:28 ` Geoffrey D. Bennett
2023-12-24 19:28 ` [PATCH 15/23] ALSA: scarlett2: Remove struct scarlett2_usb_volume_status Geoffrey D. Bennett
` (9 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:28 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Rather than looking up the analogue and mixer I/O counts repeatedly in
info->port_count[SCARLETT2_PORT_TYPE_*][SCARLETT2_PORT_*], save those
numbers in private variables.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 107 ++++++++++++------------------------
1 file changed, 35 insertions(+), 72 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 341f23d448bc..898cf2bd9655 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -609,6 +609,9 @@ struct scarlett2_data {
__u8 bInterval;
u8 num_mux_srcs;
u8 num_mux_dsts;
+ u8 num_mix_in;
+ u8 num_mix_out;
+ u8 num_line_out;
u32 firmware_version;
u8 flash_segment_nums[SCARLETT2_SEGMENT_ID_COUNT];
u8 flash_segment_blocks[SCARLETT2_SEGMENT_ID_COUNT];
@@ -1744,10 +1747,8 @@ static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
int mix_num)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
- int num_mixer_in =
- info->port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
+ int num_mixer_in = private->num_mix_in;
int err, i, j, k;
struct {
@@ -1787,7 +1788,6 @@ static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
int mix_num)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
struct {
__le16 mix_num;
@@ -1795,8 +1795,7 @@ static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
} __packed req;
int i, j;
- int num_mixer_in =
- info->port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
+ int num_mixer_in = private->num_mix_in;
req.mix_num = cpu_to_le16(mix_num);
@@ -1907,9 +1906,6 @@ static void scarlett2_usb_populate_mux(struct scarlett2_data *private,
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
@@ -1938,7 +1934,7 @@ static void scarlett2_update_meter_level_map(struct scarlett2_data *private)
/* convert mux_idx using line_out_unmap[] */
int map_mux_idx = (
info->line_out_remap_enable &&
- mux_idx < line_out_count
+ mux_idx < private->num_line_out
) ? info->line_out_unmap[mux_idx]
: mux_idx;
@@ -2249,10 +2245,7 @@ static int scarlett2_update_volumes(struct usb_mixer_interface *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;
struct scarlett2_usb_volume_status volume_status;
- int num_line_out =
- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int err, i;
int mute;
@@ -2272,7 +2265,7 @@ static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
mute = private->dim_mute[SCARLETT2_BUTTON_MUTE];
- for (i = 0; i < num_line_out; i++)
+ for (i = 0; i < private->num_line_out; i++)
if (private->vol_sw_hw_switch[i]) {
private->vol[i] = private->master_vol;
private->mute_switch[i] = mute;
@@ -2324,14 +2317,11 @@ 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)
+ if (index >= private->num_line_out)
return index;
return info->line_out_remap[index];
@@ -3104,10 +3094,6 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
private->speaker_switching_switch = monitor_other_switch[0] + 1;
if (info->has_talkback) {
- const int (*port_count)[SCARLETT2_PORT_DIRNS] =
- info->port_count;
- int num_mixes =
- port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
u16 bitmap;
int i;
@@ -3121,7 +3107,7 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
1, &bitmap);
if (err < 0)
return err;
- for (i = 0; i < num_mixes; i++, bitmap >>= 1)
+ for (i = 0; i < private->num_mix_out; i++, bitmap >>= 1)
private->talkback_map[i] = bitmap & 1;
}
@@ -3518,10 +3504,6 @@ static int scarlett2_talkback_map_ctl_put(
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 int (*port_count)[SCARLETT2_PORT_DIRNS] =
- private->info->port_count;
- int num_mixes = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
-
int index = elem->control;
int oval, val, err = 0, i;
u16 bitmap = 0;
@@ -3541,7 +3523,7 @@ static int scarlett2_talkback_map_ctl_put(
private->talkback_map[index] = val;
- for (i = 0; i < num_mixes; i++)
+ for (i = 0; i < private->num_mix_out; i++)
bitmap |= private->talkback_map[i] << i;
/* Send updated bitmap to the device */
@@ -3567,8 +3549,6 @@ static int scarlett2_add_talkback_ctls(struct usb_mixer_interface *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 num_mixes = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
int err, i;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
@@ -3582,7 +3562,7 @@ static int scarlett2_add_talkback_ctls(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- for (i = 0; i < num_mixes; i++) {
+ for (i = 0; i < private->num_mix_out; i++) {
snprintf(s, sizeof(s),
"Talkback Mix %c Playback Switch", i + 'A');
err = scarlett2_add_new_ctl(mixer, &scarlett2_talkback_map_ctl,
@@ -3629,11 +3609,6 @@ static int scarlett2_dim_mute_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 num_line_out =
- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
-
int index = elem->control;
int oval, val, err = 0, i;
@@ -3659,7 +3634,7 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl,
err = 1;
if (index == SCARLETT2_BUTTON_MUTE)
- for (i = 0; i < num_line_out; i++) {
+ for (i = 0; i < private->num_line_out; i++) {
int line_index = line_out_remap(private, i);
if (private->vol_sw_hw_switch[line_index]) {
@@ -3689,9 +3664,6 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *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 num_line_out =
- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int err, i;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
@@ -3706,7 +3678,7 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
}
/* Add volume controls */
- for (i = 0; i < num_line_out; i++) {
+ for (i = 0; i < private->num_line_out; i++) {
int index = line_out_remap(private, i);
/* Fader */
@@ -3883,9 +3855,7 @@ static int scarlett2_mixer_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 oval, val, num_mixer_in, mix_num, err = 0;
+ int oval, val, mix_num, err = 0;
int index = elem->control;
mutex_lock(&private->data_mutex);
@@ -3898,8 +3868,7 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl,
oval = private->mix[index];
val = clamp(ucontrol->value.integer.value[0],
0L, (long)SCARLETT2_MIXER_MAX_VALUE);
- num_mixer_in = port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
- mix_num = index / num_mixer_in;
+ mix_num = index / private->num_mix_in;
if (oval == val)
goto unlock;
@@ -3935,19 +3904,12 @@ static const struct snd_kcontrol_new scarlett2_mixer_ctl = {
static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *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 err, i, j;
int index;
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
- int num_inputs =
- port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
- int num_outputs =
- port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
-
- for (i = 0, index = 0; i < num_outputs; i++)
- for (j = 0; j < num_inputs; j++, index++) {
+ for (i = 0, index = 0; i < private->num_mix_out; i++)
+ for (j = 0; j < private->num_mix_in; j++, index++) {
snprintf(s, sizeof(s),
"Mix %c Input %02d Playback Volume",
'A' + i, j + 1);
@@ -4336,12 +4298,13 @@ static void scarlett2_private_suspend(struct usb_mixer_interface *mixer)
/*** Initialisation ***/
-static void scarlett2_count_mux_io(struct scarlett2_data *private)
+static void scarlett2_count_io(struct scarlett2_data *private)
{
const struct scarlett2_device_info *info = private->info;
const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
int port_type, srcs = 0, dsts = 0;
+ /* Count the number of mux sources and destinations */
for (port_type = 0;
port_type < SCARLETT2_PORT_TYPE_COUNT;
port_type++) {
@@ -4351,6 +4314,17 @@ static void scarlett2_count_mux_io(struct scarlett2_data *private)
private->num_mux_srcs = srcs;
private->num_mux_dsts = dsts;
+
+ /* Mixer inputs are mux outputs and vice versa */
+ private->num_mix_in =
+ port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_OUT];
+
+ private->num_mix_out =
+ port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
+
+ /* Number of analogue line outputs */
+ private->num_line_out =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
}
/* Look through the interface descriptors for the Focusrite Control
@@ -4406,7 +4380,7 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer,
private->info = entry->info;
private->config_set = entry->info->config_set;
private->series_name = entry->series_name;
- scarlett2_count_mux_io(private);
+ scarlett2_count_io(private);
private->scarlett2_seq = 0;
private->mixer = mixer;
@@ -4544,11 +4518,6 @@ static int scarlett2_read_configs(struct usb_mixer_interface *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 num_line_out =
- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
- int num_mixer_out =
- port_count[SCARLETT2_PORT_TYPE_MIX][SCARLETT2_PORT_IN];
struct scarlett2_usb_volume_status volume_status;
int err, i;
@@ -4601,7 +4570,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
volume_status.master_vol + SCARLETT2_VOLUME_BIAS,
0, SCARLETT2_VOLUME_BIAS);
- for (i = 0; i < num_line_out; i++) {
+ for (i = 0; i < private->num_line_out; i++) {
int volume, mute;
private->vol_sw_hw_switch[i] =
@@ -4621,7 +4590,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
private->mute_switch[i] = mute;
}
- for (i = 0; i < num_mixer_out; i++) {
+ for (i = 0; i < private->num_mix_out; i++) {
err = scarlett2_usb_get_mix(mixer, i);
if (err < 0)
return err;
@@ -4647,9 +4616,6 @@ static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer)
struct snd_card *card = mixer->chip->card;
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 num_line_out =
- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int i;
/* if line_out_hw_vol is 0, there are no controls to update */
@@ -4661,7 +4627,7 @@ static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer)
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->master_vol_ctl->id);
- for (i = 0; i < num_line_out; i++)
+ for (i = 0; i < private->num_line_out; i++)
if (private->vol_sw_hw_switch[line_out_remap(private, i)])
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->vol_ctls[i]->id);
@@ -4673,9 +4639,6 @@ static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
struct snd_card *card = mixer->chip->card;
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 num_line_out =
- port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int i;
private->vol_updated = 1;
@@ -4687,7 +4650,7 @@ static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->dim_mute_ctls[i]->id);
- for (i = 0; i < num_line_out; i++)
+ for (i = 0; i < private->num_line_out; i++)
if (private->vol_sw_hw_switch[line_out_remap(private, i)])
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->mute_ctls[i]->id);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 15/23] ALSA: scarlett2: Remove struct scarlett2_usb_volume_status
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (13 preceding siblings ...)
2023-12-24 19:28 ` [PATCH 14/23] ALSA: scarlett2: Refactor common port_count lookups Geoffrey D. Bennett
@ 2023-12-24 19:28 ` Geoffrey D. Bennett
2023-12-24 19:29 ` [PATCH 16/23] ALSA: scarlett2: Split dim_mute_update from vol_updated Geoffrey D. Bennett
` (8 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:28 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
The struct scarlett2_usb_volume_status matched the config space layout
of a few volume controls that could be read together and were in fixed
locations between Gen 2 and Gen 3 devices.
Gen 4 devices have removed, moved, and new related controls, so this
needs to be cleaned up. By adding SCARLETT2_CONFIG_MASTER_VOLUME (the
only config item that didn't already have its own entry, because it is
read-only), we can remove:
- struct scarlett2_usb_volume_state,
- #define SCARLETT2_USB_VOLUME_STATUS_OFFSET, and
- scarlett2_usb_get_volume_status()
and replace with calls to scarlett2_usb_get_config().
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 130 +++++++++++++++++-------------------
1 file changed, 61 insertions(+), 69 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 898cf2bd9655..b3f76476ce52 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -292,6 +292,7 @@ enum {
SCARLETT2_CONFIG_LINE_OUT_VOLUME,
SCARLETT2_CONFIG_MUTE_SWITCH,
SCARLETT2_CONFIG_SW_HW_SWITCH,
+ SCARLETT2_CONFIG_MASTER_VOLUME,
SCARLETT2_CONFIG_LEVEL_SWITCH,
SCARLETT2_CONFIG_PAD_SWITCH,
SCARLETT2_CONFIG_MSD_SWITCH,
@@ -336,6 +337,9 @@ static const struct scarlett2_config_set scarlett2_config_set_gen2 = {
[SCARLETT2_CONFIG_SW_HW_SWITCH] = {
.offset = 0x66, .size = 8, .activate = 3 },
+ [SCARLETT2_CONFIG_MASTER_VOLUME] = {
+ .offset = 0x76, .size = 16 },
+
[SCARLETT2_CONFIG_LEVEL_SWITCH] = {
.offset = 0x7c, .size = 8, .activate = 7 },
@@ -387,6 +391,9 @@ static const struct scarlett2_config_set scarlett2_config_set_gen3b = {
[SCARLETT2_CONFIG_SW_HW_SWITCH] = {
.offset = 0x66, .size = 8, .activate = 3 },
+ [SCARLETT2_CONFIG_MASTER_VOLUME] = {
+ .offset = 0x76, .size = 16 },
+
[SCARLETT2_CONFIG_LEVEL_SWITCH] = {
.offset = 0x7c, .size = 8, .activate = 7 },
@@ -435,6 +442,9 @@ static const struct scarlett2_config_set scarlett2_config_set_clarett = {
[SCARLETT2_CONFIG_SW_HW_SWITCH] = {
.offset = 0x66, .size = 8, .activate = 3 },
+ [SCARLETT2_CONFIG_MASTER_VOLUME] = {
+ .offset = 0x76, .size = 16 },
+
[SCARLETT2_CONFIG_LEVEL_SWITCH] = {
.offset = 0x7c, .size = 8, .activate = 7 },
@@ -1330,7 +1340,6 @@ static int scarlett2_get_port_start_num(
#define SCARLETT2_USB_CONFIG_SAVE 6
-#define SCARLETT2_USB_VOLUME_STATUS_OFFSET 0x31
#define SCARLETT2_USB_METER_LEVELS_GET_MAGIC 1
#define SCARLETT2_FLASH_BLOCK_SIZE 4096
@@ -1341,31 +1350,6 @@ static int scarlett2_get_port_start_num(
#define SCARLETT2_SEGMENT_SETTINGS_NAME "App_Settings"
#define SCARLETT2_SEGMENT_FIRMWARE_NAME "App_Upgrade"
-/* volume status is read together (matches scarlett2_config_items[1]) */
-struct scarlett2_usb_volume_status {
- /* dim/mute buttons */
- u8 dim_mute[SCARLETT2_DIM_MUTE_COUNT];
-
- u8 pad1;
-
- /* software volume setting */
- s16 sw_vol[SCARLETT2_ANALOGUE_MAX];
-
- /* actual volume of output inc. dim (-18dB) */
- s16 hw_vol[SCARLETT2_ANALOGUE_MAX];
-
- /* internal mute buttons */
- u8 mute_switch[SCARLETT2_ANALOGUE_MAX];
-
- /* sw (0) or hw (1) controlled */
- u8 sw_hw_switch[SCARLETT2_ANALOGUE_MAX];
-
- u8 pad3[6];
-
- /* front panel volume knob */
- s16 master_vol;
-} __packed;
-
/* proprietary request/response format */
struct scarlett2_usb_packet {
__le32 cmd;
@@ -1725,15 +1709,6 @@ static int scarlett2_usb_get_sync_status(
return 0;
}
-/* Send a USB message to get volume status; result placed in *buf */
-static int scarlett2_usb_get_volume_status(
- struct usb_mixer_interface *mixer,
- struct scarlett2_usb_volume_status *buf)
-{
- return scarlett2_usb_get(mixer, SCARLETT2_USB_VOLUME_STATUS_OFFSET,
- buf, sizeof(*buf));
-}
-
/* Return true if the device has a mixer that we can control */
static int scarlett2_has_mixer(struct scarlett2_data *private)
{
@@ -2245,23 +2220,32 @@ static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- struct scarlett2_usb_volume_status volume_status;
+ s16 vol;
int err, i;
int mute;
private->vol_updated = 0;
- err = scarlett2_usb_get_volume_status(mixer, &volume_status);
+ if (!info->line_out_hw_vol)
+ return 0;
+
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_MASTER_VOLUME,
+ 1, &vol);
if (err < 0)
return err;
- private->master_vol = clamp(
- volume_status.master_vol + SCARLETT2_VOLUME_BIAS,
- 0, SCARLETT2_VOLUME_BIAS);
+ private->master_vol = clamp(vol + SCARLETT2_VOLUME_BIAS,
+ 0, SCARLETT2_VOLUME_BIAS);
- if (info->line_out_hw_vol)
- for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
- private->dim_mute[i] = !!volume_status.dim_mute[i];
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_DIM_MUTE,
+ SCARLETT2_DIM_MUTE_COUNT, private->dim_mute);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
+ private->dim_mute[i] = !!private->dim_mute[i];
mute = private->dim_mute[SCARLETT2_BUTTON_MUTE];
@@ -4518,8 +4502,8 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- struct scarlett2_usb_volume_status volume_status;
int err, i;
+ s16 sw_vol[SCARLETT2_ANALOGUE_MAX];
if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_MSD_SWITCH)) {
err = scarlett2_usb_get_config(
@@ -4558,38 +4542,46 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- err = scarlett2_usb_get_volume_status(mixer, &volume_status);
+ /* read SW line out volume */
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_LINE_OUT_VOLUME,
+ private->num_line_out, &sw_vol);
if (err < 0)
return err;
- if (info->line_out_hw_vol)
- for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
- private->dim_mute[i] = !!volume_status.dim_mute[i];
+ for (i = 0; i < private->num_line_out; i++)
+ private->vol[i] = clamp(
+ sw_vol[i] + SCARLETT2_VOLUME_BIAS,
+ 0, SCARLETT2_VOLUME_BIAS);
+
+ /* read SW mute */
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_MUTE_SWITCH,
+ private->num_line_out, &private->mute_switch);
+ if (err < 0)
+ return err;
- private->master_vol = clamp(
- volume_status.master_vol + SCARLETT2_VOLUME_BIAS,
- 0, SCARLETT2_VOLUME_BIAS);
+ for (i = 0; i < private->num_line_out; i++)
+ private->mute_switch[i] =
+ !!private->mute_switch[i];
- for (i = 0; i < private->num_line_out; i++) {
- int volume, mute;
-
- private->vol_sw_hw_switch[i] =
- info->line_out_hw_vol
- && volume_status.sw_hw_switch[i];
-
- volume = private->vol_sw_hw_switch[i]
- ? volume_status.master_vol
- : volume_status.sw_vol[i];
- volume = clamp(volume + SCARLETT2_VOLUME_BIAS,
- 0, SCARLETT2_VOLUME_BIAS);
- private->vol[i] = volume;
-
- mute = private->vol_sw_hw_switch[i]
- ? private->dim_mute[SCARLETT2_BUTTON_MUTE]
- : volume_status.mute_switch[i];
- private->mute_switch[i] = mute;
+ /* read SW/HW switches */
+ if (info->line_out_hw_vol) {
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_SW_HW_SWITCH,
+ private->num_line_out, &private->vol_sw_hw_switch);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < private->num_line_out; i++)
+ private->vol_sw_hw_switch[i] =
+ !!private->vol_sw_hw_switch[i];
}
+ err = scarlett2_update_volumes(mixer);
+ if (err < 0)
+ return err;
+
for (i = 0; i < private->num_mix_out; i++) {
err = scarlett2_usb_get_mix(mixer, i);
if (err < 0)
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 16/23] ALSA: scarlett2: Split dim_mute_update from vol_updated
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (14 preceding siblings ...)
2023-12-24 19:28 ` [PATCH 15/23] ALSA: scarlett2: Remove struct scarlett2_usb_volume_status Geoffrey D. Bennett
@ 2023-12-24 19:29 ` Geoffrey D. Bennett
2023-12-24 19:29 ` [PATCH 17/23] ALSA: scarlett2: Remove line_out_hw_vol device info entry Geoffrey D. Bennett
` (7 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:29 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Scarlett Gen 2 and Gen 3 devices combine volume and dim/mute
notifications. The Scarlett 4i4 Gen 4 has volume change notification
but no dim/mute control so split dim_mute_update out from vol_update.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 63 ++++++++++++++++++++++++-------------
1 file changed, 42 insertions(+), 21 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index b3f76476ce52..1393b7da436d 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -628,6 +628,7 @@ struct scarlett2_data {
u16 scarlett2_seq;
u8 sync_updated;
u8 vol_updated;
+ u8 dim_mute_updated;
u8 input_other_updated;
u8 monitor_other_updated;
u8 mux_updated;
@@ -2222,7 +2223,6 @@ static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
const struct scarlett2_device_info *info = private->info;
s16 vol;
int err, i;
- int mute;
private->vol_updated = 0;
@@ -2238,22 +2238,9 @@ static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
private->master_vol = clamp(vol + SCARLETT2_VOLUME_BIAS,
0, SCARLETT2_VOLUME_BIAS);
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_DIM_MUTE,
- SCARLETT2_DIM_MUTE_COUNT, private->dim_mute);
- if (err < 0)
- return err;
-
- for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
- private->dim_mute[i] = !!private->dim_mute[i];
-
- mute = private->dim_mute[SCARLETT2_BUTTON_MUTE];
-
for (i = 0; i < private->num_line_out; i++)
- if (private->vol_sw_hw_switch[i]) {
+ if (private->vol_sw_hw_switch[i])
private->vol[i] = private->master_vol;
- private->mute_switch[i] = mute;
- }
return 0;
}
@@ -2401,6 +2388,36 @@ static const struct snd_kcontrol_new scarlett2_line_out_volume_ctl = {
/*** Mute Switch Controls ***/
+static int scarlett2_update_dim_mute(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int err, i;
+ u8 mute;
+
+ private->dim_mute_updated = 0;
+
+ if (!info->line_out_hw_vol)
+ return 0;
+
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_DIM_MUTE,
+ SCARLETT2_DIM_MUTE_COUNT, private->dim_mute);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
+ private->dim_mute[i] = !!private->dim_mute[i];
+
+ mute = private->dim_mute[SCARLETT2_BUTTON_MUTE];
+
+ for (i = 0; i < private->num_line_out; i++)
+ if (private->vol_sw_hw_switch[i])
+ private->mute_switch[i] = mute;
+
+ return 0;
+}
+
static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2417,8 +2434,8 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl,
goto unlock;
}
- if (private->vol_updated) {
- err = scarlett2_update_volumes(mixer);
+ if (private->dim_mute_updated) {
+ err = scarlett2_update_dim_mute(mixer);
if (err < 0)
goto unlock;
}
@@ -3575,8 +3592,8 @@ static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl,
goto unlock;
}
- if (private->vol_updated) {
- err = scarlett2_update_volumes(mixer);
+ if (private->dim_mute_updated) {
+ err = scarlett2_update_dim_mute(mixer);
if (err < 0)
goto unlock;
}
@@ -4582,6 +4599,10 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
+ err = scarlett2_update_dim_mute(mixer);
+ if (err < 0)
+ return err;
+
for (i = 0; i < private->num_mix_out; i++) {
err = scarlett2_usb_get_mix(mixer, i);
if (err < 0)
@@ -4633,11 +4654,11 @@ static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
const struct scarlett2_device_info *info = private->info;
int i;
- private->vol_updated = 1;
-
if (!info->line_out_hw_vol)
return;
+ private->dim_mute_updated = 1;
+
for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->dim_mute_ctls[i]->id);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 17/23] ALSA: scarlett2: Remove line_out_hw_vol device info entry
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (15 preceding siblings ...)
2023-12-24 19:29 ` [PATCH 16/23] ALSA: scarlett2: Split dim_mute_update from vol_updated Geoffrey D. Bennett
@ 2023-12-24 19:29 ` Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 18/23] ALSA: scarlett2: Allow for interfaces without per-channel volume Geoffrey D. Bennett
` (6 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:29 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
By splitting config set gen2 into gen2a/b (for 6i6/18i8 vs 18i20), and
gen3b into gen3b/c (for 4i4/8i6 vs 18i8/18i20), we can use
scarlett2_has_config_item() instead of the per-device line_out_hw_vol.
As Gen 4 has a master volume control but no SW/HW switches, check for
both SCARLETT2_CONFIG_MASTER_VOLUME and SCARLETT2_CONFIG_SW_HW_SWITCH
as needed, even though for Gen 2 and Gen 3 the former implies the
latter.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 145 ++++++++++++++++++++++++------------
1 file changed, 96 insertions(+), 49 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 1393b7da436d..e8a93fd339f7 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -321,8 +321,31 @@ struct scarlett2_config_set {
const struct scarlett2_config items[SCARLETT2_CONFIG_COUNT];
};
-/* Gen 2 devices: 6i6, 18i8, 18i20 */
-static const struct scarlett2_config_set scarlett2_config_set_gen2 = {
+/* Gen 2 devices without SW/HW volume switch: 6i6, 18i8 */
+
+static const struct scarlett2_config_set scarlett2_config_set_gen2a = {
+ .notifications = scarlett2_notifications,
+ .items = {
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
+
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
+
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x8d, .size = 8, .activate = 6 },
+ }
+};
+
+/* Gen 2 devices with SW/HW volume switch: 18i20 */
+
+static const struct scarlett2_config_set scarlett2_config_set_gen2b = {
.notifications = scarlett2_notifications,
.items = {
[SCARLETT2_CONFIG_DIM_MUTE] = {
@@ -375,8 +398,41 @@ static const struct scarlett2_config_set scarlett2_config_set_gen3a = {
}
};
-/* Gen 3 devices: 4i4, 8i6, 18i8, 18i20 */
+/* Gen 3 devices without SW/HW volume switch: 4i4, 8i6 */
static const struct scarlett2_config_set scarlett2_config_set_gen3b = {
+ .notifications = scarlett2_notifications,
+ .items = {
+ [SCARLETT2_CONFIG_LINE_OUT_VOLUME] = {
+ .offset = 0x34, .size = 16, .activate = 1 },
+
+ [SCARLETT2_CONFIG_MUTE_SWITCH] = {
+ .offset = 0x5c, .size = 8, .activate = 1 },
+
+ [SCARLETT2_CONFIG_LEVEL_SWITCH] = {
+ .offset = 0x7c, .size = 8, .activate = 7 },
+
+ [SCARLETT2_CONFIG_PAD_SWITCH] = {
+ .offset = 0x84, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_AIR_SWITCH] = {
+ .offset = 0x8c, .size = 8, .activate = 8 },
+
+ [SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
+ .offset = 0x95, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
+ .offset = 0x9c, .size = 1, .activate = 8 },
+
+ [SCARLETT2_CONFIG_MSD_SWITCH] = {
+ .offset = 0x9d, .size = 8, .activate = 6 },
+
+ [SCARLETT2_CONFIG_PHANTOM_PERSISTENCE] = {
+ .offset = 0x9e, .size = 8, .activate = 6 },
+ }
+};
+
+/* Gen 3 devices with SW/HW volume switch: 18i8, 18i20 */
+static const struct scarlett2_config_set scarlett2_config_set_gen3c = {
.notifications = scarlett2_notifications,
.items = {
[SCARLETT2_CONFIG_DIM_MUTE] = {
@@ -540,9 +596,6 @@ struct scarlett2_device_info {
/* which set of configuration parameters the device uses */
const struct scarlett2_config_set *config_set;
- /* line out hw volume is sw controlled */
- u8 line_out_hw_vol;
-
/* support for main/alt speaker switching */
u8 has_speaker_switching;
@@ -672,7 +725,7 @@ struct scarlett2_data {
/*** Model-specific data ***/
static const struct scarlett2_device_info s6i6_gen2_info = {
- .config_set = &scarlett2_config_set_gen2,
+ .config_set = &scarlett2_config_set_gen2a,
.level_input_count = 2,
.pad_input_count = 2,
@@ -722,7 +775,7 @@ static const struct scarlett2_device_info s6i6_gen2_info = {
};
static const struct scarlett2_device_info s18i8_gen2_info = {
- .config_set = &scarlett2_config_set_gen2,
+ .config_set = &scarlett2_config_set_gen2a,
.level_input_count = 2,
.pad_input_count = 4,
@@ -775,8 +828,7 @@ static const struct scarlett2_device_info s18i8_gen2_info = {
};
static const struct scarlett2_device_info s18i20_gen2_info = {
- .config_set = &scarlett2_config_set_gen2,
- .line_out_hw_vol = 1,
+ .config_set = &scarlett2_config_set_gen2b,
.line_out_descrs = {
"Monitor L",
@@ -959,8 +1011,7 @@ static const struct scarlett2_device_info s8i6_gen3_info = {
};
static const struct scarlett2_device_info s18i8_gen3_info = {
- .config_set = &scarlett2_config_set_gen3b,
- .line_out_hw_vol = 1,
+ .config_set = &scarlett2_config_set_gen3c,
.has_speaker_switching = 1,
.level_input_count = 2,
.pad_input_count = 4,
@@ -1039,8 +1090,7 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
};
static const struct scarlett2_device_info s18i20_gen3_info = {
- .config_set = &scarlett2_config_set_gen3b,
- .line_out_hw_vol = 1,
+ .config_set = &scarlett2_config_set_gen3c,
.has_speaker_switching = 1,
.has_talkback = 1,
.level_input_count = 2,
@@ -1111,7 +1161,6 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
static const struct scarlett2_device_info clarett_2pre_info = {
.config_set = &scarlett2_config_set_clarett,
- .line_out_hw_vol = 1,
.level_input_count = 2,
.air_input_count = 2,
@@ -1159,7 +1208,6 @@ static const struct scarlett2_device_info clarett_2pre_info = {
static const struct scarlett2_device_info clarett_4pre_info = {
.config_set = &scarlett2_config_set_clarett,
- .line_out_hw_vol = 1,
.level_input_count = 2,
.air_input_count = 4,
@@ -1212,7 +1260,6 @@ static const struct scarlett2_device_info clarett_4pre_info = {
static const struct scarlett2_device_info clarett_8pre_info = {
.config_set = &scarlett2_config_set_clarett,
- .line_out_hw_vol = 1,
.level_input_count = 2,
.air_input_count = 8,
@@ -2220,27 +2267,28 @@ static int scarlett2_add_sync_ctl(struct usb_mixer_interface *mixer)
static int scarlett2_update_volumes(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
s16 vol;
int err, i;
private->vol_updated = 0;
- if (!info->line_out_hw_vol)
- return 0;
-
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_MASTER_VOLUME,
- 1, &vol);
- if (err < 0)
- return err;
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_MASTER_VOLUME)) {
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_MASTER_VOLUME,
+ 1, &vol);
+ if (err < 0)
+ return err;
- private->master_vol = clamp(vol + SCARLETT2_VOLUME_BIAS,
- 0, SCARLETT2_VOLUME_BIAS);
+ private->master_vol = clamp(vol + SCARLETT2_VOLUME_BIAS,
+ 0, SCARLETT2_VOLUME_BIAS);
- for (i = 0; i < private->num_line_out; i++)
- if (private->vol_sw_hw_switch[i])
- private->vol[i] = private->master_vol;
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_SW_HW_SWITCH))
+ for (i = 0; i < private->num_line_out; i++)
+ if (private->vol_sw_hw_switch[i])
+ private->vol[i] = private->master_vol;
+ }
return 0;
}
@@ -2391,13 +2439,12 @@ static const struct snd_kcontrol_new scarlett2_line_out_volume_ctl = {
static int scarlett2_update_dim_mute(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
int err, i;
u8 mute;
private->dim_mute_updated = 0;
- if (!info->line_out_hw_vol)
+ if (!scarlett2_has_config_item(private, SCARLETT2_CONFIG_SW_HW_SWITCH))
return 0;
err = scarlett2_usb_get_config(
@@ -3669,7 +3716,8 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
char s[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
/* Add R/O HW volume control */
- if (info->line_out_hw_vol) {
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_MASTER_VOLUME)) {
snprintf(s, sizeof(s), "Master HW Playback Volume");
err = scarlett2_add_new_ctl(mixer,
&scarlett2_master_volume_ctl,
@@ -3708,14 +3756,16 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- /* Make the fader and mute controls read-only if the
- * SW/HW switch is set to HW
- */
- if (private->vol_sw_hw_switch[index])
- scarlett2_vol_ctl_set_writable(mixer, i, 0);
-
/* SW/HW Switch */
- if (info->line_out_hw_vol) {
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_SW_HW_SWITCH)) {
+
+ /* Make the fader and mute controls read-only if the
+ * SW/HW switch is set to HW
+ */
+ if (private->vol_sw_hw_switch[index])
+ scarlett2_vol_ctl_set_writable(mixer, i, 0);
+
snprintf(s, sizeof(s),
"Line Out %02d Volume Control Playback Enum",
i + 1);
@@ -3735,7 +3785,7 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
}
/* Add dim/mute controls */
- if (info->line_out_hw_vol)
+ if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_DIM_MUTE))
for (i = 0; i < SCARLETT2_DIM_MUTE_COUNT; i++) {
err = scarlett2_add_new_ctl(
mixer, &scarlett2_dim_mute_ctl,
@@ -4518,7 +4568,6 @@ static int scarlett2_get_flash_segment_nums(struct usb_mixer_interface *mixer)
static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
int err, i;
s16 sw_vol[SCARLETT2_ANALOGUE_MAX];
@@ -4583,7 +4632,8 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
!!private->mute_switch[i];
/* read SW/HW switches */
- if (info->line_out_hw_vol) {
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_SW_HW_SWITCH)) {
err = scarlett2_usb_get_config(
mixer, SCARLETT2_CONFIG_SW_HW_SWITCH,
private->num_line_out, &private->vol_sw_hw_switch);
@@ -4628,11 +4678,9 @@ static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
int i;
- /* if line_out_hw_vol is 0, there are no controls to update */
- if (!info->line_out_hw_vol)
+ if (!scarlett2_has_config_item(private, SCARLETT2_CONFIG_SW_HW_SWITCH))
return;
private->vol_updated = 1;
@@ -4651,10 +4699,9 @@ static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
int i;
- if (!info->line_out_hw_vol)
+ if (!scarlett2_has_config_item(private, SCARLETT2_CONFIG_SW_HW_SWITCH))
return;
private->dim_mute_updated = 1;
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 18/23] ALSA: scarlett2: Allow for interfaces without per-channel volume
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (16 preceding siblings ...)
2023-12-24 19:29 ` [PATCH 17/23] ALSA: scarlett2: Remove line_out_hw_vol device info entry Geoffrey D. Bennett
@ 2023-12-24 19:30 ` Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 19/23] ALSA: scarlett2: Add scarlett2_mixer_value_to_db() Geoffrey D. Bennett
` (5 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:30 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Currently-supported interfaces with a mixer have per-channel volume
controls, but this changes in Gen 4. Add a check so that the Playback
Volume and associated controls don't get created unless the
SCARLETT2_CONFIG_LINE_OUT_VOLUME config item is present.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 68 ++++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 28 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index e8a93fd339f7..24d7cc85cf04 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -3726,6 +3726,13 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer)
return err;
}
+ /* Remaining controls are only applicable if the device
+ * has per-channel line-out volume controls.
+ */
+ if (!scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_LINE_OUT_VOLUME))
+ return 0;
+
/* Add volume controls */
for (i = 0; i < private->num_line_out; i++) {
int index = line_out_remap(private, i);
@@ -4569,7 +4576,6 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
int err, i;
- s16 sw_vol[SCARLETT2_ANALOGUE_MAX];
if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_MSD_SWITCH)) {
err = scarlett2_usb_get_config(
@@ -4608,41 +4614,47 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- /* read SW line out volume */
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_LINE_OUT_VOLUME,
- private->num_line_out, &sw_vol);
- if (err < 0)
- return err;
-
- for (i = 0; i < private->num_line_out; i++)
- private->vol[i] = clamp(
- sw_vol[i] + SCARLETT2_VOLUME_BIAS,
- 0, SCARLETT2_VOLUME_BIAS);
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_LINE_OUT_VOLUME)) {
+ s16 sw_vol[SCARLETT2_ANALOGUE_MAX];
- /* read SW mute */
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_MUTE_SWITCH,
- private->num_line_out, &private->mute_switch);
- if (err < 0)
- return err;
+ /* read SW line out volume */
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_LINE_OUT_VOLUME,
+ private->num_line_out, &sw_vol);
+ if (err < 0)
+ return err;
- for (i = 0; i < private->num_line_out; i++)
- private->mute_switch[i] =
- !!private->mute_switch[i];
+ for (i = 0; i < private->num_line_out; i++)
+ private->vol[i] = clamp(
+ sw_vol[i] + SCARLETT2_VOLUME_BIAS,
+ 0, SCARLETT2_VOLUME_BIAS);
- /* read SW/HW switches */
- if (scarlett2_has_config_item(private,
- SCARLETT2_CONFIG_SW_HW_SWITCH)) {
+ /* read SW mute */
err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_SW_HW_SWITCH,
- private->num_line_out, &private->vol_sw_hw_switch);
+ mixer, SCARLETT2_CONFIG_MUTE_SWITCH,
+ private->num_line_out, &private->mute_switch);
if (err < 0)
return err;
for (i = 0; i < private->num_line_out; i++)
- private->vol_sw_hw_switch[i] =
- !!private->vol_sw_hw_switch[i];
+ private->mute_switch[i] =
+ !!private->mute_switch[i];
+
+ /* read SW/HW switches */
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_SW_HW_SWITCH)) {
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_SW_HW_SWITCH,
+ private->num_line_out,
+ &private->vol_sw_hw_switch);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < private->num_line_out; i++)
+ private->vol_sw_hw_switch[i] =
+ !!private->vol_sw_hw_switch[i];
+ }
}
err = scarlett2_update_volumes(mixer);
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 19/23] ALSA: scarlett2: Add scarlett2_mixer_value_to_db()
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (17 preceding siblings ...)
2023-12-24 19:30 ` [PATCH 18/23] ALSA: scarlett2: Allow for interfaces without per-channel volume Geoffrey D. Bennett
@ 2023-12-24 19:30 ` Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 20/23] ALSA: scarlett2: Add #define for SCARLETT2_MIX_MAX Geoffrey D. Bennett
` (4 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:30 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Refactor scarlett2_usb_get_mix(), moving the scarlett2_mixer_values[]
lookup into scarlett2_mixer_value_to_db().
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 24d7cc85cf04..efe95a25998b 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -1763,6 +1763,19 @@ static int scarlett2_has_mixer(struct scarlett2_data *private)
return !!private->info->mux_assignment[0][0].count;
}
+/* Map from mixer value to (db + 80) * 2
+ * (reverse of scarlett2_mixer_values[])
+ */
+static int scarlett2_mixer_value_to_db(int value)
+{
+ int i;
+
+ for (i = 0; i < SCARLETT2_MIXER_VALUE_COUNT; i++)
+ if (scarlett2_mixer_values[i] >= value)
+ return i;
+ return SCARLETT2_MIXER_MAX_VALUE;
+}
+
/* Send a USB message to get the volumes for all inputs of one mix
* and put the values into private->mix[]
*/
@@ -1772,7 +1785,7 @@ static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
struct scarlett2_data *private = mixer->private_data;
int num_mixer_in = private->num_mix_in;
- int err, i, j, k;
+ int err, i, j;
struct {
__le16 mix_num;
@@ -1790,16 +1803,9 @@ static int scarlett2_usb_get_mix(struct usb_mixer_interface *mixer,
if (err < 0)
return err;
- for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++) {
- u16 mixer_value = le16_to_cpu(data[i]);
-
- for (k = 0; k < SCARLETT2_MIXER_VALUE_COUNT; k++)
- if (scarlett2_mixer_values[k] >= mixer_value)
- break;
- if (k == SCARLETT2_MIXER_VALUE_COUNT)
- k = SCARLETT2_MIXER_MAX_VALUE;
- private->mix[j] = k;
- }
+ for (i = 0, j = mix_num * num_mixer_in; i < num_mixer_in; i++, j++)
+ private->mix[j] = scarlett2_mixer_value_to_db(
+ le16_to_cpu(data[i]));
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 20/23] ALSA: scarlett2: Add #define for SCARLETT2_MIX_MAX
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (18 preceding siblings ...)
2023-12-24 19:30 ` [PATCH 19/23] ALSA: scarlett2: Add scarlett2_mixer_value_to_db() Geoffrey D. Bennett
@ 2023-12-24 19:30 ` Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 21/23] ALSA: scarlett2: Rename db_scale_scarlett2_gain to volume Geoffrey D. Bennett
` (3 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:30 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Add a #define for SCARLETT2_MIX_MAX (max of mixer inputs * outputs) as
that will be used again soon.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index efe95a25998b..186d6d04381c 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -208,6 +208,9 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
/* Maximum number of outputs from the mixer */
#define SCARLETT2_OUTPUT_MIX_MAX 12
+/* Maximum number of mixer gain controls */
+#define SCARLETT2_MIX_MAX (SCARLETT2_INPUT_MIX_MAX * SCARLETT2_OUTPUT_MIX_MAX)
+
/* Maximum size of the data in the USB mux assignment message:
* 20 inputs, 20 outputs, 25 matrix inputs, 12 spare
*/
@@ -719,7 +722,7 @@ struct scarlett2_data {
struct snd_kcontrol *speaker_switching_ctl;
struct snd_kcontrol *talkback_ctl;
u8 mux[SCARLETT2_MUX_MAX];
- u8 mix[SCARLETT2_INPUT_MIX_MAX * SCARLETT2_OUTPUT_MIX_MAX];
+ u8 mix[SCARLETT2_MIX_MAX];
};
/*** Model-specific data ***/
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 21/23] ALSA: scarlett2: Rename db_scale_scarlett2_gain to volume
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (19 preceding siblings ...)
2023-12-24 19:30 ` [PATCH 20/23] ALSA: scarlett2: Add #define for SCARLETT2_MIX_MAX Geoffrey D. Bennett
@ 2023-12-24 19:30 ` Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 22/23] ALSA: scarlett2: Split input_other into level/pad/air/phantom Geoffrey D. Bennett
` (2 subsequent siblings)
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:30 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
db_scale_scarlett2_gain is the TLV for the output volume controls.
Gen 4 has software-controllable input gain controls, so rename this to
db_scale_scarlett2_volume so we can use that name for the inputs.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 186d6d04381c..a9bbad29ad4f 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -2417,7 +2417,7 @@ static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl,
}
static const DECLARE_TLV_DB_MINMAX(
- db_scale_scarlett2_gain, -SCARLETT2_VOLUME_BIAS * 100, 0
+ db_scale_scarlett2_volume, -SCARLETT2_VOLUME_BIAS * 100, 0
);
static const struct snd_kcontrol_new scarlett2_master_volume_ctl = {
@@ -2428,7 +2428,7 @@ static const struct snd_kcontrol_new scarlett2_master_volume_ctl = {
.info = scarlett2_volume_ctl_info,
.get = scarlett2_master_volume_ctl_get,
.private_value = 0, /* max value */
- .tlv = { .p = db_scale_scarlett2_gain }
+ .tlv = { .p = db_scale_scarlett2_volume }
};
static const struct snd_kcontrol_new scarlett2_line_out_volume_ctl = {
@@ -2440,7 +2440,7 @@ static const struct snd_kcontrol_new scarlett2_line_out_volume_ctl = {
.get = scarlett2_volume_ctl_get,
.put = scarlett2_volume_ctl_put,
.private_value = 0, /* max value */
- .tlv = { .p = db_scale_scarlett2_gain }
+ .tlv = { .p = db_scale_scarlett2_volume }
};
/*** Mute Switch Controls ***/
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 22/23] ALSA: scarlett2: Split input_other into level/pad/air/phantom
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (20 preceding siblings ...)
2023-12-24 19:30 ` [PATCH 21/23] ALSA: scarlett2: Rename db_scale_scarlett2_gain to volume Geoffrey D. Bennett
@ 2023-12-24 19:30 ` Geoffrey D. Bennett
2023-12-24 19:31 ` [PATCH 23/23] ALSA: scarlett2: Split direct_monitor out from monitor_other Geoffrey D. Bennett
2023-12-29 15:06 ` [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Takashi Iwai
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:30 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
Gen 2/3 devices have a single notification value for "input other"
changes. Gen 4 has separate notification values for level, pad, air,
and phantom power changes. Therefore, split the input_other_updated
field and the scarlett2_update_input_other() function into the four
components so that they can be handled separately later.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 198 +++++++++++++++++++++++++-----------
1 file changed, 140 insertions(+), 58 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index a9bbad29ad4f..14597428ed05 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -685,7 +685,10 @@ struct scarlett2_data {
u8 sync_updated;
u8 vol_updated;
u8 dim_mute_updated;
- u8 input_other_updated;
+ u8 input_level_updated;
+ u8 input_pad_updated;
+ u8 input_air_updated;
+ u8 input_phantom_updated;
u8 monitor_other_updated;
u8 mux_updated;
u8 speaker_switching_switched;
@@ -2687,57 +2690,20 @@ static const struct snd_kcontrol_new scarlett2_sw_hw_enum_ctl = {
/*** Line Level/Instrument Level Switch Controls ***/
-static int scarlett2_update_input_other(struct usb_mixer_interface *mixer)
+static int scarlett2_update_input_level(struct usb_mixer_interface *mixer)
{
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
- private->input_other_updated = 0;
+ private->input_level_updated = 0;
- if (info->level_input_count) {
- int err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_LEVEL_SWITCH,
- info->level_input_count + info->level_input_first,
- private->level_switch);
- if (err < 0)
- return err;
- }
-
- if (info->pad_input_count) {
- int err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_PAD_SWITCH,
- info->pad_input_count, private->pad_switch);
- if (err < 0)
- return err;
- }
-
- if (info->air_input_count) {
- int err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_AIR_SWITCH,
- info->air_input_count, private->air_switch);
- if (err < 0)
- return err;
- }
-
- if (info->phantom_count) {
- int err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_PHANTOM_SWITCH,
- info->phantom_count, private->phantom_switch);
- if (err < 0)
- return err;
-
- if (scarlett2_has_config_item(
- private,
- SCARLETT2_CONFIG_PHANTOM_PERSISTENCE)) {
- err = scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
- 1, &private->phantom_persistence);
- if (err < 0)
- return err;
- }
- }
+ if (!info->level_input_count)
+ return 0;
- return 0;
+ return scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_LEVEL_SWITCH,
+ info->level_input_count + info->level_input_first,
+ private->level_switch);
}
static int scarlett2_level_enum_ctl_info(struct snd_kcontrol *kctl,
@@ -2768,8 +2734,8 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl,
goto unlock;
}
- if (private->input_other_updated) {
- err = scarlett2_update_input_other(mixer);
+ if (private->input_level_updated) {
+ err = scarlett2_update_input_level(mixer);
if (err < 0)
goto unlock;
}
@@ -2827,6 +2793,21 @@ static const struct snd_kcontrol_new scarlett2_level_enum_ctl = {
/*** Pad Switch Controls ***/
+static int scarlett2_update_input_pad(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ private->input_pad_updated = 0;
+
+ if (!info->pad_input_count)
+ return 0;
+
+ return scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PAD_SWITCH,
+ info->pad_input_count, private->pad_switch);
+}
+
static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2842,8 +2823,8 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl,
goto unlock;
}
- if (private->input_other_updated) {
- err = scarlett2_update_input_other(mixer);
+ if (private->input_pad_updated) {
+ err = scarlett2_update_input_pad(mixer);
if (err < 0)
goto unlock;
}
@@ -2901,6 +2882,21 @@ static const struct snd_kcontrol_new scarlett2_pad_ctl = {
/*** Air Switch Controls ***/
+static int scarlett2_update_input_air(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+
+ private->input_air_updated = 0;
+
+ if (!info->air_input_count)
+ return 0;
+
+ return scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_AIR_SWITCH,
+ info->air_input_count, private->air_switch);
+}
+
static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2916,8 +2912,8 @@ static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl,
goto unlock;
}
- if (private->input_other_updated) {
- err = scarlett2_update_input_other(mixer);
+ if (private->input_air_updated) {
+ err = scarlett2_update_input_air(mixer);
if (err < 0)
goto unlock;
}
@@ -2974,6 +2970,35 @@ static const struct snd_kcontrol_new scarlett2_air_ctl = {
/*** Phantom Switch Controls ***/
+static int scarlett2_update_input_phantom(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int err;
+
+ private->input_phantom_updated = 0;
+
+ if (!info->phantom_count)
+ return 0;
+
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PHANTOM_SWITCH,
+ info->phantom_count, private->phantom_switch);
+ if (err < 0)
+ return err;
+
+ if (scarlett2_has_config_item(private,
+ SCARLETT2_CONFIG_PHANTOM_PERSISTENCE)) {
+ err = scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE,
+ 1, &private->phantom_persistence);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2989,8 +3014,8 @@ static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl,
goto unlock;
}
- if (private->input_other_updated) {
- err = scarlett2_update_input_other(mixer);
+ if (private->input_phantom_updated) {
+ err = scarlett2_update_input_phantom(mixer);
if (err < 0)
goto unlock;
}
@@ -4598,7 +4623,19 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
return 0;
}
- err = scarlett2_update_input_other(mixer);
+ err = scarlett2_update_input_level(mixer);
+ if (err < 0)
+ return err;
+
+ err = scarlett2_update_input_pad(mixer);
+ if (err < 0)
+ return err;
+
+ err = scarlett2_update_input_air(mixer);
+ if (err < 0)
+ return err;
+
+ err = scarlett2_update_input_phantom(mixer);
if (err < 0)
return err;
@@ -4737,30 +4774,75 @@ static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer)
&private->mute_ctls[i]->id);
}
-/* Notify on "input other" change (level/pad/air) */
-static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer)
+/* Notify on input level switch change */
+static void scarlett2_notify_input_level(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
int i;
- private->input_other_updated = 1;
+ private->input_level_updated = 1;
for (i = 0; i < info->level_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->level_ctls[i]->id);
+}
+
+/* Notify on input pad switch change */
+static void scarlett2_notify_input_pad(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int i;
+
+ private->input_pad_updated = 1;
+
for (i = 0; i < info->pad_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->pad_ctls[i]->id);
+}
+
+/* Notify on input air switch change */
+static void scarlett2_notify_input_air(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int i;
+
+ private->input_air_updated = 1;
+
for (i = 0; i < info->air_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->air_ctls[i]->id);
+}
+
+/* Notify on input phantom switch change */
+static void scarlett2_notify_input_phantom(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ int i;
+
+ private->input_phantom_updated = 1;
+
for (i = 0; i < info->phantom_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->phantom_ctls[i]->id);
}
+/* Notify on "input other" change (level/pad/air/phantom) */
+static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer)
+{
+ scarlett2_notify_input_level(mixer);
+ scarlett2_notify_input_pad(mixer);
+ scarlett2_notify_input_air(mixer);
+ scarlett2_notify_input_phantom(mixer);
+}
+
/* Notify on "monitor other" change (direct monitor, speaker
* switching, talkback)
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 23/23] ALSA: scarlett2: Split direct_monitor out from monitor_other
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (21 preceding siblings ...)
2023-12-24 19:30 ` [PATCH 22/23] ALSA: scarlett2: Split input_other into level/pad/air/phantom Geoffrey D. Bennett
@ 2023-12-24 19:31 ` Geoffrey D. Bennett
2023-12-29 15:06 ` [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Takashi Iwai
23 siblings, 0 replies; 25+ messages in thread
From: Geoffrey D. Bennett @ 2023-12-24 19:31 UTC (permalink / raw)
To: Takashi Iwai; +Cc: Takashi Iwai, alsa-devel, linux-sound
The notification value for monitor_other on the large interfaces is
the same as the notification value for direct_monitor on the 3rd Gen
small interfaces. Add a separate scarlett3a_notifications array and
split out the direct_monitor handling.
Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
---
sound/usb/mixer_scarlett2.c | 289 ++++++++++++++++++++----------------
1 file changed, 158 insertions(+), 131 deletions(-)
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index 14597428ed05..e25f004e50e4 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -277,8 +277,10 @@ static void scarlett2_notify_dim_mute(struct usb_mixer_interface *mixer);
static void scarlett2_notify_monitor(struct usb_mixer_interface *mixer);
static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer);
static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer);
+static void scarlett2_notify_direct_monitor(struct usb_mixer_interface *mixer);
+
+/* Arrays of notification callback functions */
-/* Array of notification callback functions */
static const struct scarlett2_notification scarlett2_notifications[] = {
{ 0x00000001, NULL }, /* ack, gets ignored */
{ 0x00000008, scarlett2_notify_sync },
@@ -289,6 +291,13 @@ static const struct scarlett2_notification scarlett2_notifications[] = {
{ 0, NULL }
};
+static const struct scarlett2_notification scarlett3a_notifications[] = {
+ { 0x00000001, NULL }, /* ack, gets ignored */
+ { 0x00800000, scarlett2_notify_input_other },
+ { 0x01000000, scarlett2_notify_direct_monitor },
+ { 0, NULL }
+};
+
/* Configuration parameters that can be read and written */
enum {
SCARLETT2_CONFIG_DIM_MUTE,
@@ -379,7 +388,7 @@ static const struct scarlett2_config_set scarlett2_config_set_gen2b = {
/* Gen 3 devices without a mixer (Solo and 2i2) */
static const struct scarlett2_config_set scarlett2_config_set_gen3a = {
- .notifications = scarlett2_notifications,
+ .notifications = scarlett3a_notifications,
.items = {
[SCARLETT2_CONFIG_MSD_SWITCH] = {
.offset = 0x04, .size = 8, .activate = 6 },
@@ -690,6 +699,7 @@ struct scarlett2_data {
u8 input_air_updated;
u8 input_phantom_updated;
u8 monitor_other_updated;
+ u8 direct_monitor_updated;
u8 mux_updated;
u8 speaker_switching_switched;
u8 sync;
@@ -3127,7 +3137,7 @@ static const struct snd_kcontrol_new scarlett2_phantom_persistence_ctl = {
.put = scarlett2_phantom_persistence_ctl_put,
};
-/*** Direct Monitor Control ***/
+/*** Speaker Switching Control ***/
static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
{
@@ -3147,11 +3157,6 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
private->monitor_other_updated = 0;
- if (info->direct_monitor)
- return scarlett2_usb_get_config(
- mixer, SCARLETT2_CONFIG_DIRECT_MONITOR,
- 1, &private->direct_monitor_switch);
-
/* if it doesn't do speaker switching then it also doesn't do
* talkback
*/
@@ -3196,119 +3201,6 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
return 0;
}
-static int scarlett2_direct_monitor_ctl_get(
- struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *elem = kctl->private_data;
- struct usb_mixer_interface *mixer = elem->head.mixer;
- struct scarlett2_data *private = elem->head.mixer->private_data;
- int err = 0;
-
- mutex_lock(&private->data_mutex);
-
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
-
- if (private->monitor_other_updated) {
- err = scarlett2_update_monitor_other(mixer);
- if (err < 0)
- goto unlock;
- }
- ucontrol->value.enumerated.item[0] = private->direct_monitor_switch;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
-}
-
-static int scarlett2_direct_monitor_ctl_put(
- struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
-{
- struct usb_mixer_elem_info *elem = kctl->private_data;
- struct usb_mixer_interface *mixer = elem->head.mixer;
- struct scarlett2_data *private = mixer->private_data;
-
- int index = elem->control;
- int oval, val, err = 0;
-
- mutex_lock(&private->data_mutex);
-
- if (private->hwdep_in_use) {
- err = -EBUSY;
- goto unlock;
- }
-
- oval = private->direct_monitor_switch;
- val = min(ucontrol->value.enumerated.item[0], 2U);
-
- if (oval == val)
- goto unlock;
-
- private->direct_monitor_switch = val;
-
- /* Send switch change to the device */
- err = scarlett2_usb_set_config(
- mixer, SCARLETT2_CONFIG_DIRECT_MONITOR, index, val);
- if (err == 0)
- err = 1;
-
-unlock:
- mutex_unlock(&private->data_mutex);
- return err;
-}
-
-static int scarlett2_direct_monitor_stereo_enum_ctl_info(
- struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
-{
- static const char *const values[3] = {
- "Off", "Mono", "Stereo"
- };
-
- return snd_ctl_enum_info(uinfo, 1, 3, values);
-}
-
-/* Direct Monitor for Solo is mono-only and only needs a boolean control
- * Direct Monitor for 2i2 is selectable between Off/Mono/Stereo
- */
-static const struct snd_kcontrol_new scarlett2_direct_monitor_ctl[2] = {
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "",
- .info = snd_ctl_boolean_mono_info,
- .get = scarlett2_direct_monitor_ctl_get,
- .put = scarlett2_direct_monitor_ctl_put,
- },
- {
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "",
- .info = scarlett2_direct_monitor_stereo_enum_ctl_info,
- .get = scarlett2_direct_monitor_ctl_get,
- .put = scarlett2_direct_monitor_ctl_put,
- }
-};
-
-static int scarlett2_add_direct_monitor_ctl(struct usb_mixer_interface *mixer)
-{
- struct scarlett2_data *private = mixer->private_data;
- const struct scarlett2_device_info *info = private->info;
- const char *s;
-
- if (!info->direct_monitor)
- return 0;
-
- s = info->direct_monitor == 1
- ? "Direct Monitor Playback Switch"
- : "Direct Monitor Playback Enum";
-
- return scarlett2_add_new_ctl(
- mixer, &scarlett2_direct_monitor_ctl[info->direct_monitor - 1],
- 0, 1, s, &private->direct_monitor_ctl);
-}
-
-/*** Speaker Switching Control ***/
-
static int scarlett2_speaker_switch_enum_ctl_info(
struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
{
@@ -4014,6 +3906,133 @@ static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *mixer)
return 0;
}
+/*** Direct Monitor Control ***/
+
+static int scarlett2_update_direct_monitor(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+
+ private->direct_monitor_updated = 0;
+
+ if (!private->info->direct_monitor)
+ return 0;
+
+ return scarlett2_usb_get_config(
+ mixer, SCARLETT2_CONFIG_DIRECT_MONITOR,
+ 1, &private->direct_monitor_switch);
+}
+
+static int scarlett2_direct_monitor_ctl_get(
+ struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kctl->private_data;
+ struct usb_mixer_interface *mixer = elem->head.mixer;
+ struct scarlett2_data *private = elem->head.mixer->private_data;
+ int err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ if (private->hwdep_in_use) {
+ err = -EBUSY;
+ goto unlock;
+ }
+
+ if (private->direct_monitor_updated) {
+ err = scarlett2_update_direct_monitor(mixer);
+ if (err < 0)
+ goto unlock;
+ }
+ ucontrol->value.enumerated.item[0] = private->direct_monitor_switch;
+
+unlock:
+ mutex_unlock(&private->data_mutex);
+ return err;
+}
+
+static int scarlett2_direct_monitor_ctl_put(
+ struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
+{
+ struct usb_mixer_elem_info *elem = kctl->private_data;
+ struct usb_mixer_interface *mixer = elem->head.mixer;
+ struct scarlett2_data *private = mixer->private_data;
+
+ int index = elem->control;
+ int oval, val, err = 0;
+
+ mutex_lock(&private->data_mutex);
+
+ if (private->hwdep_in_use) {
+ err = -EBUSY;
+ goto unlock;
+ }
+
+ oval = private->direct_monitor_switch;
+ val = min(ucontrol->value.enumerated.item[0], 2U);
+
+ if (oval == val)
+ goto unlock;
+
+ private->direct_monitor_switch = val;
+
+ /* Send switch change to the device */
+ err = scarlett2_usb_set_config(
+ mixer, SCARLETT2_CONFIG_DIRECT_MONITOR, index, val);
+ if (err == 0)
+ err = 1;
+
+unlock:
+ mutex_unlock(&private->data_mutex);
+ return err;
+}
+
+static int scarlett2_direct_monitor_stereo_enum_ctl_info(
+ struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
+{
+ static const char *const values[3] = {
+ "Off", "Mono", "Stereo"
+ };
+
+ return snd_ctl_enum_info(uinfo, 1, 3, values);
+}
+
+/* Direct Monitor for Solo is mono-only and only needs a boolean control
+ * Direct Monitor for 2i2 is selectable between Off/Mono/Stereo
+ */
+static const struct snd_kcontrol_new scarlett2_direct_monitor_ctl[2] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = snd_ctl_boolean_mono_info,
+ .get = scarlett2_direct_monitor_ctl_get,
+ .put = scarlett2_direct_monitor_ctl_put,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "",
+ .info = scarlett2_direct_monitor_stereo_enum_ctl_info,
+ .get = scarlett2_direct_monitor_ctl_get,
+ .put = scarlett2_direct_monitor_ctl_put,
+ }
+};
+
+static int scarlett2_add_direct_monitor_ctl(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const char *s;
+
+ if (!info->direct_monitor)
+ return 0;
+
+ s = info->direct_monitor == 1
+ ? "Direct Monitor Playback Switch"
+ : "Direct Monitor Playback Enum";
+
+ return scarlett2_add_new_ctl(
+ mixer, &scarlett2_direct_monitor_ctl[info->direct_monitor - 1],
+ 0, 1, s, &private->direct_monitor_ctl);
+}
+
/*** Mux Source Selection Controls ***/
static int scarlett2_mux_src_enum_ctl_info(struct snd_kcontrol *kctl,
@@ -4639,7 +4658,7 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (err < 0)
return err;
- err = scarlett2_update_monitor_other(mixer);
+ err = scarlett2_update_direct_monitor(mixer);
if (err < 0)
return err;
@@ -4647,6 +4666,10 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (!scarlett2_has_mixer(private))
return 0;
+ err = scarlett2_update_monitor_other(mixer);
+ if (err < 0)
+ return err;
+
if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_STANDALONE_SWITCH)) {
err = scarlett2_usb_get_config(
@@ -4843,9 +4866,7 @@ static void scarlett2_notify_input_other(struct usb_mixer_interface *mixer)
scarlett2_notify_input_phantom(mixer);
}
-/* Notify on "monitor other" change (direct monitor, speaker
- * switching, talkback)
- */
+/* Notify on "monitor other" change (speaker switching, talkback) */
static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer)
{
struct snd_card *card = mixer->chip->card;
@@ -4854,12 +4875,6 @@ static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer)
private->monitor_other_updated = 1;
- if (info->direct_monitor) {
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
- &private->direct_monitor_ctl->id);
- return;
- }
-
if (info->has_speaker_switching)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->speaker_switching_ctl->id);
@@ -4885,6 +4900,18 @@ static void scarlett2_notify_monitor_other(struct usb_mixer_interface *mixer)
}
}
+/* Notify on direct monitor switch change */
+static void scarlett2_notify_direct_monitor(struct usb_mixer_interface *mixer)
+{
+ struct snd_card *card = mixer->chip->card;
+ struct scarlett2_data *private = mixer->private_data;
+
+ private->direct_monitor_updated = 1;
+
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->direct_monitor_ctl->id);
+}
+
/* Interrupt callback */
static void scarlett2_notify(struct urb *urb)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
` (22 preceding siblings ...)
2023-12-24 19:31 ` [PATCH 23/23] ALSA: scarlett2: Split direct_monitor out from monitor_other Geoffrey D. Bennett
@ 2023-12-29 15:06 ` Takashi Iwai
23 siblings, 0 replies; 25+ messages in thread
From: Takashi Iwai @ 2023-12-29 15:06 UTC (permalink / raw)
To: Geoffrey D. Bennett; +Cc: Takashi Iwai, alsa-devel, linux-sound
On Sun, 24 Dec 2023 20:18:35 +0100,
Geoffrey D. Bennett wrote:
>
> Hi Takashi,
>
> This series is preparation for adding support for the Focusrite
> Scarlett 4th Gen devices. It applies on top of the previous series
> https://lore.kernel.org/linux-sound/cover.1703001053.git.g@b4.vu/
> "ALSA: scarlett2: Firmware Upgrade and Error Handling Improvements".
>
> There should be no notable functional changes in this series, just
> refactoring/restructuring/renaming/reformatting.
>
> Regards,
> Geoffrey.
>
> Geoffrey D. Bennett (23):
> ALSA: scarlett2: Simplify enums by removing explicit values
> ALSA: scarlett2: Infer has_msd_mode from config items
> ALSA: scarlett2: Infer standalone switch from config items
> ALSA: scarlett2: Check for phantom persistence config item
> ALSA: scarlett2: Check presence of mixer using mux_assignment
> ALSA: scarlett2: Add config set struct
> ALSA: scarlett2: Remove scarlett2_config_sets array
> ALSA: scarlett2: Add check for config_item presence
> ALSA: scarlett2: Refactor scarlett2_usb_set_config()
> ALSA: scarlett2: Refactor scarlett2_config_save()
> ALSA: scarlett2: Formatting fixes
> ALSA: scarlett2: Parameterise notifications
> ALSA: scarlett2: Change num_mux_* from int to u8
> ALSA: scarlett2: Refactor common port_count lookups
> ALSA: scarlett2: Remove struct scarlett2_usb_volume_status
> ALSA: scarlett2: Split dim_mute_update from vol_updated
> ALSA: scarlett2: Remove line_out_hw_vol device info entry
> ALSA: scarlett2: Allow for interfaces without per-channel volume
> ALSA: scarlett2: Add scarlett2_mixer_value_to_db()
> ALSA: scarlett2: Add #define for SCARLETT2_MIX_MAX
> ALSA: scarlett2: Rename db_scale_scarlett2_gain to volume
> ALSA: scarlett2: Split input_other into level/pad/air/phantom
> ALSA: scarlett2: Split direct_monitor out from monitor_other
Now applied all patches to topic/scarlett2 branch, which is merged to
for-next branch.
There was a wrong sha id reference in some fixes tag and I corrected
manually.
thanks,
Takashi
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2023-12-29 15:06 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-24 19:18 [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 01/23] ALSA: scarlett2: Simplify enums by removing explicit values Geoffrey D. Bennett
2023-12-24 19:20 ` [PATCH 02/23] ALSA: scarlett2: Infer has_msd_mode from config items Geoffrey D. Bennett
2023-12-24 19:21 ` [PATCH 03/23] ALSA: scarlett2: Infer standalone switch " Geoffrey D. Bennett
2023-12-24 19:21 ` [PATCH 04/23] ALSA: scarlett2: Check for phantom persistence config item Geoffrey D. Bennett
2023-12-24 19:22 ` [PATCH 05/23] ALSA: scarlett2: Check presence of mixer using mux_assignment Geoffrey D. Bennett
2023-12-24 19:22 ` [PATCH 06/23] ALSA: scarlett2: Add config set struct Geoffrey D. Bennett
2023-12-24 19:23 ` [PATCH 07/23] ALSA: scarlett2: Remove scarlett2_config_sets array Geoffrey D. Bennett
2023-12-24 19:25 ` [PATCH 08/23] ALSA: scarlett2: Add check for config_item presence Geoffrey D. Bennett
2023-12-24 19:26 ` [PATCH 09/23] ALSA: scarlett2: Refactor scarlett2_usb_set_config() Geoffrey D. Bennett
2023-12-24 19:27 ` [PATCH 10/23] ALSA: scarlett2: Refactor scarlett2_config_save() Geoffrey D. Bennett
2023-12-24 19:27 ` [PATCH 11/23] ALSA: scarlett2: Formatting fixes Geoffrey D. Bennett
2023-12-24 19:27 ` [PATCH 12/23] ALSA: scarlett2: Parameterise notifications Geoffrey D. Bennett
2023-12-24 19:28 ` [PATCH 13/23] ALSA: scarlett2: Change num_mux_* from int to u8 Geoffrey D. Bennett
2023-12-24 19:28 ` [PATCH 14/23] ALSA: scarlett2: Refactor common port_count lookups Geoffrey D. Bennett
2023-12-24 19:28 ` [PATCH 15/23] ALSA: scarlett2: Remove struct scarlett2_usb_volume_status Geoffrey D. Bennett
2023-12-24 19:29 ` [PATCH 16/23] ALSA: scarlett2: Split dim_mute_update from vol_updated Geoffrey D. Bennett
2023-12-24 19:29 ` [PATCH 17/23] ALSA: scarlett2: Remove line_out_hw_vol device info entry Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 18/23] ALSA: scarlett2: Allow for interfaces without per-channel volume Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 19/23] ALSA: scarlett2: Add scarlett2_mixer_value_to_db() Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 20/23] ALSA: scarlett2: Add #define for SCARLETT2_MIX_MAX Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 21/23] ALSA: scarlett2: Rename db_scale_scarlett2_gain to volume Geoffrey D. Bennett
2023-12-24 19:30 ` [PATCH 22/23] ALSA: scarlett2: Split input_other into level/pad/air/phantom Geoffrey D. Bennett
2023-12-24 19:31 ` [PATCH 23/23] ALSA: scarlett2: Split direct_monitor out from monitor_other Geoffrey D. Bennett
2023-12-29 15:06 ` [PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4 Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox