[PATCH 00/23] ALSA: scarlett2: Refactor in preparation for gen4
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(-)
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
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);
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)
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);
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,
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;
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;
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);
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;
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,
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;
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 &&
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];
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);
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)
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);
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;
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);
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; }
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 ***/
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 ***/
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) */
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) {
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
participants (2)
-
Geoffrey D. Bennett
-
Takashi Iwai