diff options
Diffstat (limited to 'sound/usb/mixer_scarlett2.c')
| -rw-r--r-- | sound/usb/mixer_scarlett2.c | 1647 |
1 files changed, 716 insertions, 931 deletions
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 1150cf104985..f2446bf3982c 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -10,8 +10,9 @@ * - Solo/2i2/4i4 Gen 4 * - Clarett 2Pre/4Pre/8Pre USB * - Clarett+ 2Pre/4Pre/8Pre + * - Vocaster One/Two * - * Copyright (c) 2018-2023 by Geoffrey D. Bennett <g at b4.vu> + * Copyright (c) 2018-2025 by Geoffrey D. Bennett <g at b4.vu> * Copyright (c) 2020-2021 by Vladimir Sadovnikov <sadko4u@gmail.com> * Copyright (c) 2022 by Christian Colglazier <christian@cacolglazier.com> * @@ -75,6 +76,9 @@ * to many LinuxMusicians people and to Focusrite for hardware * donations). * + * Support for Vocaster One and Two added in Mar 2024 (thanks to many + * LinuxMusicians people and to Focusrite for hardware donations). + * * This ALSA mixer gives access to (model-dependent): * - input, output, mixer-matrix muxes * - mixer-matrix gain stages @@ -166,6 +170,7 @@ #include "helper.h" #include "mixer_scarlett2.h" +#include "fcp.h" /* device_setup value to allow turning MSD mode back on */ #define SCARLETT2_MSD_ENABLE 0x02 @@ -173,6 +178,9 @@ /* device_setup value to disable this mixer driver */ #define SCARLETT2_DISABLE 0x04 +/* device_setup value to use the FCP driver instead */ +#define SCARLETT2_USE_FCP_DRIVER 0x08 + /* some gui mixers can't handle negative ctl values */ #define SCARLETT2_VOLUME_BIAS 127 @@ -360,6 +368,21 @@ static const char *const scarlett2_dim_mute_names[SCARLETT2_DIM_MUTE_COUNT] = { "Mute Playback Switch", "Dim Playback Switch" }; +/* Vocaster One speaker/headphone mute names */ +static const char *const vocaster_one_sp_hp_mute_names[] = { + "Speaker Mute Playback Switch", + "Headphones Mute Playback Switch", + NULL +}; + +/* Vocaster Two speaker/headphone mute names */ +static const char *const vocaster_two_sp_hp_mute_names[] = { + "Speaker Mute Playback Switch", + "Headphones 1 Mute Playback Switch", + "Headphones 2 Mute Playback Switch", + NULL +}; + /* The autogain_status is set based on the autogain_switch and * raw_autogain_status values. * @@ -543,6 +566,7 @@ enum { SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN, SCARLETT2_CONFIG_BLUETOOTH_VOLUME, SCARLETT2_CONFIG_SPDIF_MODE, + SCARLETT2_CONFIG_SP_HP_MUTE, SCARLETT2_CONFIG_COUNT }; @@ -810,6 +834,9 @@ static const struct scarlett2_config_set scarlett2_config_set_vocaster = { [SCARLETT2_CONFIG_BLUETOOTH_VOLUME] = { .offset = 0xbf, .size = 8, .activate = 28 }, + + [SCARLETT2_CONFIG_SP_HP_MUTE] = { + .offset = 0xab, .size = 8, .activate = 10 }, } }; @@ -1079,6 +1106,9 @@ struct scarlett2_device_info { /* minimum firmware version required */ u16 min_firmware_version; + /* has a downloadable device map */ + u8 has_devmap; + /* support for main/alt speaker switching */ u8 has_speaker_switching; @@ -1170,6 +1200,9 @@ struct scarlett2_device_info { /* additional description for the line out volume controls */ const char * const line_out_descrs[SCARLETT2_ANALOGUE_MAX]; + /* Vocaster speaker/headphone mute control names */ + const char * const *sp_hp_mute_names; + /* number of sources/destinations of each port type */ const int port_count[SCARLETT2_PORT_TYPE_COUNT][SCARLETT2_PORT_DIRNS]; @@ -1242,6 +1275,7 @@ struct scarlett2_data { u8 level_switch[SCARLETT2_LEVEL_SWITCH_MAX]; u8 pad_switch[SCARLETT2_PAD_SWITCH_MAX]; u8 dim_mute[SCARLETT2_DIM_MUTE_COUNT]; + u8 sp_hp_mute; u8 air_switch[SCARLETT2_AIR_SWITCH_MAX]; u8 dsp_switch[SCARLETT2_DSP_SWITCH_MAX]; s32 compressor_values[SCARLETT2_COMPRESSOR_CTLS_MAX]; @@ -1253,7 +1287,7 @@ struct scarlett2_data { u8 phantom_switch[SCARLETT2_PHANTOM_SWITCH_MAX]; u8 phantom_persistence; u8 input_select_switch; - u8 input_link_switch[SCARLETT2_INPUT_GAIN_MAX / 2]; + u8 input_link_switch[SCARLETT2_INPUT_GAIN_MAX]; u8 gain[SCARLETT2_INPUT_GAIN_MAX]; u8 autogain_switch[SCARLETT2_INPUT_GAIN_MAX]; u8 autogain_status[SCARLETT2_INPUT_GAIN_MAX]; @@ -1284,7 +1318,7 @@ struct scarlett2_data { struct snd_kcontrol *input_mute_ctls[SCARLETT2_INPUT_MUTE_SWITCH_MAX]; struct snd_kcontrol *phantom_ctls[SCARLETT2_PHANTOM_SWITCH_MAX]; struct snd_kcontrol *input_select_ctl; - struct snd_kcontrol *input_link_ctls[SCARLETT2_INPUT_GAIN_MAX / 2]; + struct snd_kcontrol *input_link_ctls[SCARLETT2_INPUT_GAIN_MAX]; struct snd_kcontrol *input_gain_ctls[SCARLETT2_INPUT_GAIN_MAX]; struct snd_kcontrol *autogain_ctls[SCARLETT2_INPUT_GAIN_MAX]; struct snd_kcontrol *autogain_status_ctls[SCARLETT2_INPUT_GAIN_MAX]; @@ -1773,6 +1807,7 @@ static const struct scarlett2_device_info s18i20_gen3_info = { static const struct scarlett2_device_info vocaster_one_info = { .config_set = &scarlett2_config_set_vocaster, .min_firmware_version = 1769, + .has_devmap = 1, .phantom_count = 1, .inputs_per_phantom = 1, @@ -1783,6 +1818,7 @@ static const struct scarlett2_device_info vocaster_one_info = { .peq_flt_total_count = 4, .mute_input_count = 1, .gain_input_count = 1, + .sp_hp_mute_names = vocaster_one_sp_hp_mute_names, .port_count = { [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 }, @@ -1815,6 +1851,7 @@ static const struct scarlett2_device_info vocaster_one_info = { static const struct scarlett2_device_info vocaster_two_info = { .config_set = &scarlett2_config_set_vocaster, .min_firmware_version = 1769, + .has_devmap = 1, .phantom_count = 2, .inputs_per_phantom = 1, @@ -1826,6 +1863,7 @@ static const struct scarlett2_device_info vocaster_two_info = { .mute_input_count = 2, .gain_input_count = 2, .has_bluetooth = 1, + .sp_hp_mute_names = vocaster_two_sp_hp_mute_names, .port_count = { [SCARLETT2_PORT_TYPE_NONE] = { 1, 0 }, @@ -1858,6 +1896,7 @@ static const struct scarlett2_device_info vocaster_two_info = { static const struct scarlett2_device_info solo_gen4_info = { .config_set = &scarlett2_config_set_gen4_solo, .min_firmware_version = 2115, + .has_devmap = 1, .level_input_count = 1, .air_input_count = 1, @@ -1912,6 +1951,7 @@ static const struct scarlett2_device_info solo_gen4_info = { static const struct scarlett2_device_info s2i2_gen4_info = { .config_set = &scarlett2_config_set_gen4_2i2, .min_firmware_version = 2115, + .has_devmap = 1, .level_input_count = 2, .air_input_count = 2, @@ -1966,6 +2006,7 @@ static const struct scarlett2_device_info s2i2_gen4_info = { static const struct scarlett2_device_info s4i4_gen4_info = { .config_set = &scarlett2_config_set_gen4_4i4, .min_firmware_version = 2089, + .has_devmap = 1, .level_input_count = 2, .air_input_count = 2, @@ -2264,6 +2305,8 @@ static int scarlett2_get_port_start_num( #define SCARLETT2_USB_GET_DATA 0x00800000 #define SCARLETT2_USB_SET_DATA 0x00800001 #define SCARLETT2_USB_DATA_CMD 0x00800002 +#define SCARLETT2_USB_INFO_DEVMAP 0x0080000c +#define SCARLETT2_USB_GET_DEVMAP 0x0080000d #define SCARLETT2_USB_CONFIG_SAVE 6 @@ -2277,6 +2320,14 @@ static int scarlett2_get_port_start_num( #define SCARLETT2_SEGMENT_SETTINGS_NAME "App_Settings" #define SCARLETT2_SEGMENT_FIRMWARE_NAME "App_Upgrade" +/* Gen 4 device firmware provides access to a base64-encoded + * zlib-compressed JSON description of the device's capabilities and + * configuration. This device map is made available in + * /proc/asound/cardX/device-map.json.zz.b64 + */ +#define SCARLETT2_DEVMAP_BLOCK_SIZE 1024 +#define SCARLETT2_DEVMAP_FILENAME "device-map.json.zz.b64" + /* proprietary request/response format */ struct scarlett2_usb_packet { __le32 cmd; @@ -2326,24 +2377,23 @@ static int scarlett2_usb( { struct scarlett2_data *private = mixer->private_data; struct usb_device *dev = mixer->chip->dev; - struct scarlett2_usb_packet *req, *resp = NULL; + struct scarlett2_usb_packet *req __free(kfree) = NULL; + struct scarlett2_usb_packet *resp __free(kfree) = NULL; size_t req_buf_size = struct_size(req, data, req_size); size_t resp_buf_size = struct_size(resp, data, resp_size); + int retries = 0; + const int max_retries = 5; int err; req = kmalloc(req_buf_size, GFP_KERNEL); - if (!req) { - err = -ENOMEM; - goto error; - } + if (!req) + return -ENOMEM; resp = kmalloc(resp_buf_size, GFP_KERNEL); - if (!resp) { - err = -ENOMEM; - goto error; - } + if (!resp) + return -ENOMEM; - mutex_lock(&private->usb_mutex); + guard(mutex)(&private->usb_mutex); /* build request message and send it */ @@ -2352,16 +2402,20 @@ static int scarlett2_usb( if (req_size) memcpy(req->data, req_data, req_size); +retry: err = scarlett2_usb_tx(dev, private->bInterfaceNumber, req, req_buf_size); if (err != req_buf_size) { + if (err == -EPROTO && ++retries <= max_retries) { + msleep(5 * (1 << (retries - 1))); + goto retry; + } usb_audio_err( mixer->chip, "%s USB request result cmd %x was %d\n", private->series_name, cmd, err); - err = -EINVAL; - goto unlock; + return -EINVAL; } if (!wait_for_completion_timeout(&private->cmd_done, @@ -2371,8 +2425,7 @@ static int scarlett2_usb( "%s USB request timed out, cmd %x\n", private->series_name, cmd); - err = -ETIMEDOUT; - goto unlock; + return -ETIMEDOUT; } /* send a second message to get the response */ @@ -2389,17 +2442,14 @@ static int scarlett2_usb( * reboot request */ if (cmd == SCARLETT2_USB_REBOOT && - (err == -ESHUTDOWN || err == -EPROTO)) { - err = 0; - goto unlock; - } + (err == -ESHUTDOWN || err == -EPROTO)) + return 0; usb_audio_err( mixer->chip, "%s USB response result cmd %x was %d expected %zu\n", private->series_name, cmd, err, resp_buf_size); - err = -EINVAL; - goto unlock; + return -EINVAL; } /* cmd/seq/size should match except when initialising @@ -2422,18 +2472,12 @@ static int scarlett2_usb( resp_size, le16_to_cpu(resp->size), le32_to_cpu(resp->error), le32_to_cpu(resp->pad)); - err = -EINVAL; - goto unlock; + return -EINVAL; } if (resp_data && resp_size > 0) memcpy(resp_data, resp->data, resp_size); -unlock: - mutex_unlock(&private->usb_mutex); -error: - kfree(req); - kfree(resp); return err; } @@ -3292,25 +3336,20 @@ static int scarlett2_sync_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->sync_updated) { err = scarlett2_update_sync(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->sync; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static const struct snd_kcontrol_new scarlett2_sync_ctl = { @@ -3409,7 +3448,7 @@ static int scarlett2_update_autogain(struct usb_mixer_interface *mixer) private->num_autogain_status_texts - 1; - for (int i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++) + for (i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++) if (scarlett2_has_config_item(private, scarlett2_ag_target_configs[i])) { err = scarlett2_usb_get_config( @@ -3420,7 +3459,7 @@ static int scarlett2_update_autogain(struct usb_mixer_interface *mixer) } /* convert from negative dBFS as used by the device */ - for (int i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++) + for (i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++) private->ag_targets[i] = -ag_target_values[i]; return 0; @@ -3439,7 +3478,7 @@ static void scarlett2_autogain_update_access(struct usb_mixer_interface *mixer) scarlett2_set_ctl_access(private->input_select_ctl, val); if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_INPUT_LINK_SWITCH)) - for (i = 0; i < info->gain_input_count / 2; i++) + for (i = 0; i < info->gain_input_count; i++) scarlett2_set_ctl_access(private->input_link_ctls[i], val); for (i = 0; i < info->gain_input_count; i++) @@ -3480,7 +3519,7 @@ static void scarlett2_autogain_notify_access(struct usb_mixer_interface *mixer) &private->input_select_ctl->id); if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_INPUT_LINK_SWITCH)) - for (i = 0; i < info->gain_input_count / 2; i++) + for (i = 0; i < info->gain_input_count; i++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &private->input_link_ctls[i]->id); for (i = 0; i < info->gain_input_count; i++) @@ -3560,17 +3599,13 @@ static int scarlett2_autogain_switch_ctl_info( struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); err = scarlett2_check_input_phantom_updated(mixer); if (err < 0) - goto unlock; - - err = snd_ctl_boolean_mono_info(kctl, uinfo); + return err; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return snd_ctl_boolean_mono_info(kctl, uinfo); } static int scarlett2_autogain_switch_ctl_get( @@ -3581,23 +3616,18 @@ static int scarlett2_autogain_switch_ctl_get( struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; + return err; ucontrol->value.enumerated.item[0] = private->autogain_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_autogain_status_ctl_get( @@ -3608,23 +3638,18 @@ static int scarlett2_autogain_status_ctl_get( struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; + return err; ucontrol->value.enumerated.item[0] = private->autogain_status[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_autogain_switch_ctl_put( @@ -3633,46 +3658,37 @@ static int scarlett2_autogain_switch_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_input_phantom_updated(mixer); if (err < 0) - goto unlock; + return err; - if (scarlett2_phantom_is_switching(private, index)) { - err = -EPERM; - goto unlock; - } + if (scarlett2_phantom_is_switching(private, index)) + return -EPERM; oval = private->autogain_switch[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->autogain_switch[index] = val; /* Send switch change to the device */ err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_AUTOGAIN_SWITCH, index, val); - if (err == 0) - err = 1; scarlett2_autogain_update_access(mixer); scarlett2_autogain_notify_access(mixer); -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_autogain_status_ctl_info( @@ -3713,16 +3729,14 @@ static int scarlett2_ag_target_ctl_info( struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; + return err; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -3730,9 +3744,7 @@ static int scarlett2_ag_target_ctl_info( uinfo->value.integer.max = 0; uinfo->value.integer.step = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_ag_target_ctl_get( @@ -3741,26 +3753,21 @@ static int scarlett2_ag_target_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->autogain_updated) { err = scarlett2_update_autogain(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->ag_targets[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_ag_target_ctl_put( @@ -3769,39 +3776,32 @@ static int scarlett2_ag_target_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->ag_targets[index]; val = clamp(ucontrol->value.integer.value[0], (long)SCARLETT2_AG_TARGET_MIN, 0L); if (oval == val) - goto unlock; + return 0; private->ag_targets[index] = val; /* Send new value to the device */ err = scarlett2_usb_set_config( mixer, scarlett2_ag_target_configs[index], 1, -val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const DECLARE_TLV_DB_MINMAX( @@ -3825,7 +3825,7 @@ static int scarlett2_update_input_select(struct usb_mixer_interface *mixer) { struct scarlett2_data *private = mixer->private_data; const struct scarlett2_device_info *info = private->info; - int link_count = info->gain_input_count / 2; + int link_count = info->gain_input_count; int err; private->input_select_updated = 0; @@ -3847,10 +3847,6 @@ static int scarlett2_update_input_select(struct usb_mixer_interface *mixer) if (err < 0) return err; - /* simplified because no model yet has link_count > 1 */ - if (private->input_link_switch[0]) - private->input_select_switch = 0; - return 0; } @@ -3860,25 +3856,20 @@ static int scarlett2_input_select_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_select_updated) { err = scarlett2_update_input_select(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->input_select_switch; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_input_select_ctl_put( @@ -3887,45 +3878,37 @@ static int scarlett2_input_select_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 struct scarlett2_device_info *info = private->info; int oval, val, err; - int max_val = private->input_link_switch[0] ? 0 : 1; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->input_select_switch; val = ucontrol->value.integer.value[0]; if (val < 0) val = 0; - else if (val > max_val) - val = max_val; + else if (val >= info->gain_input_count) + val = info->gain_input_count - 1; if (oval == val) - goto unlock; + return 0; private->input_select_switch = val; - /* Send switch change to the device if inputs not linked */ - if (!private->input_link_switch[0]) - err = scarlett2_usb_set_config( - mixer, SCARLETT2_CONFIG_INPUT_SELECT_SWITCH, - 1, val); - if (err == 0) - err = 1; + /* Send new value to the device */ + err = scarlett2_usb_set_config( + mixer, SCARLETT2_CONFIG_INPUT_SELECT_SWITCH, + 0, val); -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_input_select_ctl_info( @@ -3934,49 +3917,38 @@ static int scarlett2_input_select_ctl_info( 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 inputs = private->info->gain_input_count; - int i, j; - int err; - char **values = kcalloc(inputs, sizeof(char *), GFP_KERNEL); + int i, err; + char **values __free(kfree) = NULL; + values = kcalloc(inputs, sizeof(char *), GFP_KERNEL); if (!values) return -ENOMEM; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; + return err; - /* Loop through each input - * Linked inputs have one value for the pair - */ - for (i = 0, j = 0; i < inputs; i++) { - if (private->input_link_switch[i / 2]) { - values[j++] = kasprintf( - GFP_KERNEL, "Input %d-%d", i + 1, i + 2); - i++; - } else { - values[j++] = kasprintf( - GFP_KERNEL, "Input %d", i + 1); + /* Loop through each input */ + for (i = 0; i < inputs; i++) { + values[i] = kasprintf(GFP_KERNEL, "Input %d", i + 1); + if (!values[i]) { + err = -ENOMEM; + goto clear; } } - err = snd_ctl_enum_info(uinfo, 1, j, + err = snd_ctl_enum_info(uinfo, 1, i, (const char * const *)values); -unlock: - mutex_unlock(&private->data_mutex); - +clear: for (i = 0; i < inputs; i++) kfree(values[i]); - kfree(values); return err; } @@ -4002,22 +3974,16 @@ static int scarlett2_autogain_disables_ctl_info(struct snd_kcontrol *kctl, struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; - - err = snd_ctl_boolean_mono_info(kctl, uinfo); + return err; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return snd_ctl_boolean_mono_info(kctl, uinfo); } static int scarlett2_input_link_ctl_get( @@ -4026,26 +3992,21 @@ static int scarlett2_input_link_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_select_updated) { err = scarlett2_update_input_select(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->input_link_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_input_link_ctl_put( @@ -4054,47 +4015,30 @@ static int scarlett2_input_link_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->input_link_switch[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->input_link_switch[index] = val; - /* Notify of change in input select options available */ - snd_ctl_notify(mixer->chip->card, - SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, - &private->input_select_ctl->id); - private->input_select_updated = 1; - - /* Send switch change to the device - * Link for channels 1-2 is at index 1 - * No device yet has more than 2 channels linked - */ err = scarlett2_usb_set_config( - mixer, SCARLETT2_CONFIG_INPUT_LINK_SWITCH, index + 1, val); - if (err == 0) - err = 1; + mixer, SCARLETT2_CONFIG_INPUT_LINK_SWITCH, index, val); -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_input_link_ctl = { @@ -4130,16 +4074,14 @@ static int scarlett2_input_gain_ctl_info(struct snd_kcontrol *kctl, struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; + return err; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = elem->channels; @@ -4147,9 +4089,7 @@ static int scarlett2_input_gain_ctl_info(struct snd_kcontrol *kctl, uinfo->value.integer.max = SCARLETT2_MAX_GAIN_VALUE; uinfo->value.integer.step = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_input_gain_ctl_get(struct snd_kcontrol *kctl, @@ -4158,26 +4098,21 @@ static int scarlett2_input_gain_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_gain_updated) { err = scarlett2_update_input_gain(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->gain[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_input_gain_ctl_put(struct snd_kcontrol *kctl, @@ -4186,38 +4121,31 @@ static int scarlett2_input_gain_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->gain[index]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->gain[index] = val; /* Send gain change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_INPUT_GAIN, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_input_gain_ctl = { @@ -4254,26 +4182,21 @@ static int scarlett2_safe_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_safe_updated) { err = scarlett2_update_input_safe(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->safe_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_safe_ctl_put(struct snd_kcontrol *kctl, @@ -4282,38 +4205,31 @@ static int scarlett2_safe_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->safe_switch[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->safe_switch[index] = val; /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_SAFE_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_safe_ctl = { @@ -4348,20 +4264,17 @@ static int scarlett2_pcm_input_switch_ctl_get( 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; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); if (private->pcm_input_switch_updated) { err = scarlett2_update_pcm_input_switch(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->pcm_input_switch; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_pcm_input_switch_ctl_put( @@ -4370,21 +4283,18 @@ static int scarlett2_pcm_input_switch_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; + int oval, val, err; - int oval, val, err = 0; - - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->pcm_input_switch; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->pcm_input_switch = val; @@ -4392,12 +4302,8 @@ static int scarlett2_pcm_input_switch_ctl_put( err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_PCM_INPUT_SWITCH, 0, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_pcm_input_switch_ctl_info( @@ -4484,25 +4390,20 @@ static int scarlett2_master_volume_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->master_vol; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_headphone_volume_ctl_get( @@ -4512,25 +4413,20 @@ static int scarlett2_headphone_volume_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->headphone_vol; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int line_out_remap(struct scarlett2_data *private, int index) @@ -4553,25 +4449,20 @@ static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->vol_updated) { err = scarlett2_update_volumes(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->vol[index]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl, @@ -4581,30 +4472,24 @@ static int scarlett2_volume_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->vol[index]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->vol[index] = val; err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_LINE_OUT_VOLUME, index, val - SCARLETT2_VOLUME_BIAS); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const DECLARE_TLV_DB_MINMAX( @@ -4683,25 +4568,20 @@ static int scarlett2_mute_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->dim_mute_updated) { err = scarlett2_update_dim_mute(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->mute_switch[index]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl, @@ -4711,32 +4591,26 @@ static int scarlett2_mute_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->mute_switch[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->mute_switch[index] = val; /* Send mute change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_MUTE_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_mute_ctl = { @@ -4855,28 +4729,22 @@ static int scarlett2_sw_hw_enum_ctl_put(struct snd_kcontrol *kctl, struct scarlett2_data *private = mixer->private_data; int ctl_index = elem->control; int index = line_out_remap(private, ctl_index); - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->vol_sw_hw_switch[index]; val = !!ucontrol->value.enumerated.item[0]; if (oval == val) - goto unlock; + return 0; err = scarlett2_sw_hw_change(mixer, ctl_index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_sw_hw_enum_ctl = { @@ -4916,22 +4784,16 @@ static int scarlett2_level_enum_ctl_info(struct snd_kcontrol *kctl, struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; - - err = snd_ctl_enum_info(uinfo, 1, 2, values); + return err; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return snd_ctl_enum_info(uinfo, 1, 2, values); } static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl, @@ -4941,28 +4803,22 @@ static int scarlett2_level_enum_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; const struct scarlett2_device_info *info = private->info; - int index = elem->control + info->level_input_first; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_level_updated) { err = scarlett2_update_input_level(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = scarlett2_decode_muteable( private->level_switch[index]); - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl, @@ -4972,26 +4828,23 @@ static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; const struct scarlett2_device_info *info = private->info; - int index = elem->control + info->level_input_first; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->level_switch[index]; val = !!ucontrol->value.enumerated.item[0]; if (oval == val) - goto unlock; + return 0; private->level_switch[index] = val; @@ -5002,12 +4855,8 @@ static int scarlett2_level_enum_ctl_put(struct snd_kcontrol *kctl, /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_LEVEL_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_level_enum_ctl = { @@ -5041,26 +4890,21 @@ static int scarlett2_pad_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_pad_updated) { err = scarlett2_update_input_pad(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->pad_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_pad_ctl_put(struct snd_kcontrol *kctl, @@ -5069,34 +4913,27 @@ static int scarlett2_pad_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; - int index = elem->control; - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->pad_switch[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->pad_switch[index] = val; /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_PAD_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_pad_ctl = { @@ -5130,25 +4967,20 @@ static int scarlett2_air_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_air_updated) { err = scarlett2_update_input_air(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->air_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_air_ctl_put(struct snd_kcontrol *kctl, @@ -5157,38 +4989,31 @@ static int scarlett2_air_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->air_switch[index]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->air_switch[index] = val; /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_AIR_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_air_with_drive_ctl_info( @@ -5202,22 +5027,16 @@ static int scarlett2_air_with_drive_ctl_info( struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_autogain_updated(mixer); if (err < 0) - goto unlock; - - err = snd_ctl_enum_info(uinfo, 1, 3, values); + return err; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return snd_ctl_enum_info(uinfo, 1, 3, values); } static const struct snd_kcontrol_new scarlett2_air_ctl[2] = { @@ -5260,25 +5079,20 @@ static int scarlett2_dsp_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_dsp_updated) { err = scarlett2_update_input_dsp(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->dsp_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_dsp_ctl_put(struct snd_kcontrol *kctl, @@ -5287,38 +5101,31 @@ static int scarlett2_dsp_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->dsp_switch[index]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->dsp_switch[index] = val; /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_DSP_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_dsp_ctl = { @@ -5381,33 +5188,29 @@ static int scarlett2_compressor_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; - int index = elem->control; int channel = index / SCARLETT2_COMPRESSOR_PARAM_COUNT; int param_index = index % SCARLETT2_COMPRESSOR_PARAM_COUNT; + const struct compressor_param *param = &compressor_params[param_index]; int oval, val, err; s32 scaled_val; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->compressor_values[index]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->compressor_values[index] = val; - const struct compressor_param *param = &compressor_params[param_index]; - scaled_val = val << param->scale_bits; /* Send change to the device */ @@ -5419,19 +5222,12 @@ static int scarlett2_compressor_ctl_put( err = scarlett2_usb_set_data( mixer, private->config_set->param_buf_addr + 1, 1, channel); if (err < 0) - goto unlock; + return err; err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_COMPRESSOR_PARAMS, index, scaled_val); - if (err < 0) - goto unlock; - - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_compressor_ctl_info( @@ -5487,20 +5283,18 @@ static int scarlett2_precomp_flt_switch_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; - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->precomp_flt_switch[elem->control]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->precomp_flt_switch[elem->control] = val; @@ -5508,12 +5302,8 @@ static int scarlett2_precomp_flt_switch_ctl_put( err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_PRECOMP_FLT_SWITCH, elem->control, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_peq_flt_switch_ctl_put( @@ -5522,20 +5312,18 @@ static int scarlett2_peq_flt_switch_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; - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->peq_flt_switch[elem->control]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->peq_flt_switch[elem->control] = val; @@ -5543,12 +5331,8 @@ static int scarlett2_peq_flt_switch_ctl_put( err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_PEQ_FLT_SWITCH, elem->control, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_precomp_flt_switch_ctl = { @@ -5613,6 +5397,8 @@ static int scarlett2_update_filter_values(struct usb_mixer_interface *mixer) info->peq_flt_total_count * SCARLETT2_BIQUAD_COEFFS, peq_flt_values); + if (err < 0) + return err; for (i = 0, dst_idx = 0; i < info->dsp_input_count; i++) { src_idx = i * @@ -5667,20 +5453,17 @@ static int scarlett2_precomp_flt_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; - int index = elem->control * SCARLETT2_BIQUAD_COEFFS; int i, oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; /* Check if any of the values have changed; if not, return */ for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++) { @@ -5691,7 +5474,7 @@ static int scarlett2_precomp_flt_ctl_put( } if (i == SCARLETT2_BIQUAD_COEFFS) - goto unlock; + return 0; /* Update the values */ for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++) @@ -5702,19 +5485,14 @@ static int scarlett2_precomp_flt_ctl_put( err = scarlett2_usb_set_data( mixer, private->config_set->param_buf_addr, 1, index); if (err < 0) - goto unlock; + return err; err = scarlett2_usb_set_config_buf( mixer, SCARLETT2_CONFIG_PRECOMP_FLT_PARAMS, index, SCARLETT2_BIQUAD_COEFFS, &private->precomp_flt_values[index]); - if (err == 0) - err = 1; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_peq_flt_ctl_put( @@ -5724,7 +5502,6 @@ static int scarlett2_peq_flt_ctl_put( struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; const struct scarlett2_device_info *info = private->info; - int src_index = elem->control * SCARLETT2_BIQUAD_COEFFS; int dst_index = ( elem->control / @@ -5734,16 +5511,14 @@ static int scarlett2_peq_flt_ctl_put( ) * SCARLETT2_BIQUAD_COEFFS; int i, oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; /* Check if any of the values have changed; if not, return */ for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++) { @@ -5754,7 +5529,7 @@ static int scarlett2_peq_flt_ctl_put( } if (i == SCARLETT2_BIQUAD_COEFFS) - goto unlock; + return 0; /* Update the values */ for (i = 0; i < SCARLETT2_BIQUAD_COEFFS; i++) @@ -5765,19 +5540,14 @@ static int scarlett2_peq_flt_ctl_put( err = scarlett2_usb_set_data( mixer, private->config_set->param_buf_addr, 1, dst_index); if (err < 0) - goto unlock; + return err; err = scarlett2_usb_set_config_buf( mixer, SCARLETT2_CONFIG_PEQ_FLT_PARAMS, dst_index, SCARLETT2_BIQUAD_COEFFS, &private->peq_flt_values[src_index]); - if (err == 0) - err = 1; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_flt_ctl_info( @@ -5830,26 +5600,21 @@ static int scarlett2_input_mute_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->input_mute_updated) { err = scarlett2_update_input_mute(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->input_mute_switch[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_input_mute_ctl_put(struct snd_kcontrol *kctl, @@ -5858,26 +5623,23 @@ static int scarlett2_input_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; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->input_mute_switch[index]; val = ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->input_mute_switch[index] = val; @@ -5885,12 +5647,8 @@ static int scarlett2_input_mute_ctl_put(struct snd_kcontrol *kctl, err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_INPUT_MUTE_SWITCH, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_input_mute_ctl = { @@ -6001,23 +5759,18 @@ static int scarlett2_phantom_ctl_get(struct snd_kcontrol *kctl, struct scarlett2_data *private = mixer->private_data; int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_input_phantom_updated(mixer); if (err < 0) - goto unlock; + return err; ucontrol->value.integer.value[0] = scarlett2_decode_muteable( private->phantom_switch[elem->control]); - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl, @@ -6027,26 +5780,23 @@ static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; const struct scarlett2_device_info *info = private->info; - int index = elem->control; int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_check_put_during_autogain(mixer); if (err < 0) - goto unlock; + return err; oval = private->phantom_switch[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->phantom_switch[index] = val; @@ -6057,15 +5807,10 @@ static int scarlett2_phantom_ctl_put(struct snd_kcontrol *kctl, /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_PHANTOM_SWITCH, index + info->phantom_first, val); - if (err == 0) - err = 1; - scarlett2_phantom_update_access(mixer); scarlett2_phantom_notify_access(mixer); -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_phantom_ctl = { @@ -6094,34 +5839,27 @@ static int scarlett2_phantom_persistence_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; - int index = elem->control; - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->phantom_persistence; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->phantom_persistence = val; /* Send switch change to the device */ err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_PHANTOM_PERSISTENCE, index, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_phantom_persistence_ctl = { @@ -6212,25 +5950,20 @@ static int scarlett2_speaker_switch_enum_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->monitor_other_updated) { err = scarlett2_update_monitor_other(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->speaker_switching_switch; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } /* when speaker switching gets enabled, switch the main/alt speakers @@ -6296,21 +6029,18 @@ static int scarlett2_speaker_switch_enum_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; + int oval, val, err; - int oval, val, err = 0; + guard(mutex)(&private->data_mutex); - mutex_lock(&private->data_mutex); - - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->speaker_switching_switch; val = min(ucontrol->value.enumerated.item[0], 2U); if (oval == val) - goto unlock; + return 0; private->speaker_switching_switch = val; @@ -6319,14 +6049,14 @@ static int scarlett2_speaker_switch_enum_ctl_put( mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE, 0, !!val); if (err < 0) - goto unlock; + return err; /* if speaker switching is enabled, select main or alt */ err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH, 0, val == 2); if (err < 0) - goto unlock; + return err; /* update controls if speaker switching gets enabled or disabled */ if (!oval && val) @@ -6334,12 +6064,7 @@ static int scarlett2_speaker_switch_enum_ctl_put( else if (oval && !val) scarlett2_speaker_switch_disable(mixer); - if (err == 0) - err = 1; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_speaker_switch_enum_ctl = { @@ -6382,25 +6107,20 @@ static int scarlett2_talkback_enum_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->monitor_other_updated) { err = scarlett2_update_monitor_other(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->talkback_switch; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_talkback_enum_ctl_put( @@ -6409,21 +6129,18 @@ static int scarlett2_talkback_enum_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; + int oval, val, err; - int oval, val, err = 0; - - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->talkback_switch; val = min(ucontrol->value.enumerated.item[0], 2U); if (oval == val) - goto unlock; + return 0; private->talkback_switch = val; @@ -6432,18 +6149,14 @@ static int scarlett2_talkback_enum_ctl_put( mixer, SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE, 1, !!val); if (err < 0) - goto unlock; + return err; /* if talkback is enabled, select main or alt */ err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH, 1, val == 2); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_talkback_enum_ctl = { @@ -6474,21 +6187,19 @@ static int scarlett2_talkback_map_ctl_put( struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = elem->control; - int oval, val, err = 0, i; + int oval, val, err, i; u16 bitmap = 0; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->talkback_map[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->talkback_map[index] = val; @@ -6498,12 +6209,8 @@ static int scarlett2_talkback_map_ctl_put( /* Send updated bitmap to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_TALKBACK_MAP, 0, bitmap); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_talkback_map_ctl = { @@ -6551,25 +6258,20 @@ static int scarlett2_dim_mute_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->dim_mute_updated) { err = scarlett2_update_dim_mute(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->dim_mute[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl, @@ -6579,29 +6281,24 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = elem->control; - int oval, val, err = 0, i; + int oval, val, err, i; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->dim_mute[index]; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->dim_mute[index] = val; /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_DIM_MUTE, index, val); - if (err == 0) - err = 1; - if (index == SCARLETT2_BUTTON_MUTE) for (i = 0; i < private->num_line_out; i++) { int line_index = line_out_remap(private, i); @@ -6614,9 +6311,7 @@ static int scarlett2_dim_mute_ctl_put(struct snd_kcontrol *kctl, } } -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_dim_mute_ctl = { @@ -6627,6 +6322,61 @@ static const struct snd_kcontrol_new scarlett2_dim_mute_ctl = { .put = scarlett2_dim_mute_ctl_put }; +/*** Vocaster Speaker/Headphone Mute Controls ***/ + +static int scarlett2_sp_hp_mute_ctl_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *ucontrol) +{ + struct usb_mixer_elem_info *elem = kctl->private_data; + struct scarlett2_data *private = elem->head.mixer->private_data; + + ucontrol->value.integer.value[0] = + !!(private->sp_hp_mute & (1 << elem->control)); + + return 0; +} + +static int scarlett2_sp_hp_mute_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 val, err; + + guard(mutex)(&private->data_mutex); + + if (private->hwdep_in_use) + return -EBUSY; + + val = private->sp_hp_mute; + + if (ucontrol->value.integer.value[0]) + val |= (1 << index); + else + val &= ~(1 << index); + + if (val == private->sp_hp_mute) + return 0; + + private->sp_hp_mute = val; + + /* Send change to the device */ + err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_SP_HP_MUTE, + 0, val); + + return err < 0 ? err : 1; +} + +static const struct snd_kcontrol_new scarlett2_sp_hp_mute_ctl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "", + .info = snd_ctl_boolean_mono_info, + .get = scarlett2_sp_hp_mute_ctl_get, + .put = scarlett2_sp_hp_mute_ctl_put +}; + /*** Create the analogue output controls ***/ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer) @@ -6659,6 +6409,17 @@ static int scarlett2_add_line_out_ctls(struct usb_mixer_interface *mixer) return err; } + /* Add Vocaster speaker/headphone mute controls */ + if (private->info->sp_hp_mute_names) + for (i = 0; private->info->sp_hp_mute_names[i]; i++) { + err = scarlett2_add_new_ctl( + mixer, &scarlett2_sp_hp_mute_ctl, + i, 1, private->info->sp_hp_mute_names[i], + NULL); + if (err < 0) + return err; + } + /* Remaining controls are only applicable if the device * has per-channel line-out volume controls. */ @@ -6914,10 +6675,9 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer) if (scarlett2_has_config_item(private, SCARLETT2_CONFIG_INPUT_LINK_SWITCH)) { - for (i = 0; i < info->gain_input_count / 2; i++) { + for (i = 0; i < info->gain_input_count; i++) { scnprintf(s, sizeof(s), - "Line In %d-%d Link Capture Switch", - (i * 2) + 1, (i * 2) + 2); + "Line In %d Link Capture Switch", i + 1); err = scarlett2_add_new_ctl( mixer, &scarlett2_input_link_ctl, i, 1, s, &private->input_link_ctls[i]); @@ -7029,25 +6789,20 @@ static int scarlett2_mixer_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->mix_updated) { err = scarlett2_update_mix(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->mix[elem->control]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl, @@ -7056,15 +6811,13 @@ 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; - int oval, val, mix_num, err = 0; + int oval, val, mix_num, err; int index = elem->control; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->mix[index]; val = clamp(ucontrol->value.integer.value[0], @@ -7072,16 +6825,12 @@ static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl, mix_num = index / private->num_mix_in; if (oval == val) - goto unlock; + return 0; private->mix[index] = val; err = scarlett2_usb_set_mix(mixer, mix_num); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const DECLARE_TLV_DB_MINMAX( @@ -7168,25 +6917,20 @@ static int scarlett2_direct_monitor_ctl_get( 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 err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->direct_monitor_updated) { err = scarlett2_update_direct_monitor(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->direct_monitor_switch; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_direct_monitor_ctl_put( @@ -7195,34 +6939,27 @@ static int scarlett2_direct_monitor_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; - int index = elem->control; - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->direct_monitor_switch; val = min(ucontrol->value.enumerated.item[0], 2U); if (oval == val) - goto unlock; + return 0; 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; + return err < 0 ? err : 1; } static int scarlett2_direct_monitor_stereo_enum_ctl_info( @@ -7272,33 +7009,27 @@ static int scarlett2_monitor_mix_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; - int oval, val, err = 0; + int oval, val, err; int index = elem->control; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->monitor_mix[index]; val = clamp(ucontrol->value.integer.value[0], 0L, (long)SCARLETT2_MIXER_MAX_VALUE); if (oval == val) - goto unlock; + return 0; private->monitor_mix[index] = val; err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN, index, scarlett2_mixer_values[val]); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_monitor_mix_ctl = { @@ -7399,13 +7130,15 @@ static int scarlett2_mux_src_enum_ctl_info(struct snd_kcontrol *kctl, if (port_type == SCARLETT2_PORT_TYPE_MIX && item >= private->num_mix_out) - sprintf(uinfo->value.enumerated.name, - port->dsp_src_descr, - item - private->num_mix_out + 1); + scnprintf(uinfo->value.enumerated.name, + sizeof(uinfo->value.enumerated.name), + port->dsp_src_descr, + item - private->num_mix_out + 1); else - sprintf(uinfo->value.enumerated.name, - port->src_descr, - item + port->src_num_offset); + scnprintf(uinfo->value.enumerated.name, + sizeof(uinfo->value.enumerated.name), + port->src_descr, + item + port->src_num_offset); return 0; } @@ -7422,25 +7155,20 @@ static int scarlett2_mux_src_enum_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->mux_updated) { err = scarlett2_usb_get_mux(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.enumerated.item[0] = private->mux[index]; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, @@ -7450,30 +7178,24 @@ static int scarlett2_mux_src_enum_ctl_put(struct snd_kcontrol *kctl, struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; int index = line_out_remap(private, elem->control); - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->mux[index]; val = min(ucontrol->value.enumerated.item[0], private->num_mux_srcs - 1U); if (oval == val) - goto unlock; + return 0; private->mux[index] = val; err = scarlett2_usb_set_mux(mixer); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_mux_src_enum_ctl = { @@ -7550,17 +7272,15 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, u16 meter_levels[SCARLETT2_MAX_METERS]; int i, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; err = scarlett2_usb_get_meter_levels(mixer, elem->channels, meter_levels); if (err < 0) - goto unlock; + return err; /* copy & translate from meter_levels[] using meter_level_map[] */ for (i = 0; i < elem->channels; i++) { @@ -7575,10 +7295,7 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl, ucontrol->value.integer.value[i] = value; } -unlock: - mutex_unlock(&private->data_mutex); - - return err; + return 0; } static const struct snd_kcontrol_new scarlett2_meter_ctl = { @@ -7620,33 +7337,26 @@ static int scarlett2_msd_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; + int oval, val, err; - int oval, val, err = 0; - - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->msd_switch; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->msd_switch = val; /* Send switch change to the device */ err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_MSD_SWITCH, 0, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_msd_ctl = { @@ -7691,21 +7401,18 @@ static int scarlett2_standalone_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; + int oval, val, err; - int oval, val, err = 0; - - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->standalone_switch; val = !!ucontrol->value.integer.value[0]; if (oval == val) - goto unlock; + return 0; private->standalone_switch = val; @@ -7713,12 +7420,8 @@ static int scarlett2_standalone_ctl_put(struct snd_kcontrol *kctl, err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_STANDALONE_SWITCH, 0, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_standalone_ctl = { @@ -7778,20 +7481,17 @@ static int scarlett2_power_status_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); if (private->power_status_updated) { err = scarlett2_update_power_status(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->power_status; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_power_status_ctl_info( @@ -7853,25 +7553,20 @@ static int scarlett2_bluetooth_volume_ctl_get(struct snd_kcontrol *kctl, struct usb_mixer_elem_info *elem = kctl->private_data; struct usb_mixer_interface *mixer = elem->head.mixer; struct scarlett2_data *private = mixer->private_data; - int err = 0; + int err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; if (private->bluetooth_updated) { err = scarlett2_update_bluetooth_volume(mixer); if (err < 0) - goto unlock; + return err; } ucontrol->value.integer.value[0] = private->bluetooth_volume; - -unlock: - mutex_unlock(&private->data_mutex); - return err; + return 0; } static int scarlett2_bluetooth_volume_ctl_put(struct snd_kcontrol *kctl, @@ -7880,32 +7575,26 @@ static int scarlett2_bluetooth_volume_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; - int oval, val, err = 0; + int oval, val, err; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); - if (private->hwdep_in_use) { - err = -EBUSY; - goto unlock; - } + if (private->hwdep_in_use) + return -EBUSY; oval = private->bluetooth_volume; val = clamp(ucontrol->value.integer.value[0], 0L, (long)SCARLETT2_MAX_BLUETOOTH_VOLUME); if (oval == val) - goto unlock; + return 0; private->bluetooth_volume = val; err = scarlett2_usb_set_config(mixer, SCARLETT2_CONFIG_BLUETOOTH_VOLUME, 0, val); - if (err == 0) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static int scarlett2_bluetooth_volume_ctl_info( @@ -8000,39 +7689,31 @@ static int scarlett2_spdif_mode_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; - int oval, val, err = 0; + int oval, val, err; int i; - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); oval = private->spdif_mode; val = ucontrol->value.enumerated.item[0]; - if (val < 0) { - err = -EINVAL; - goto unlock; - } + if (val < 0) + return -EINVAL; for (i = 0; i <= val; i++) - if (private->info->spdif_mode_values[i] == 0xff) { - err = -EINVAL; - goto unlock; - } + if (private->info->spdif_mode_values[i] == 0xff) + return -EINVAL; if (oval == val) - goto unlock; + return 0; private->spdif_mode = val; err = scarlett2_usb_set_config( mixer, SCARLETT2_CONFIG_SPDIF_MODE, 0, private->info->spdif_mode_values[val]); - if (!err) - err = 1; -unlock: - mutex_unlock(&private->data_mutex); - return err; + return err < 0 ? err : 1; } static const struct snd_kcontrol_new scarlett2_spdif_mode_ctl = { @@ -8244,7 +7925,7 @@ static void scarlett2_notify_input_select(struct usb_mixer_interface *mixer) SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO, &private->input_select_ctl->id); - for (i = 0; i < info->gain_input_count / 2; i++) + for (i = 0; i < info->gain_input_count; i++) snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &private->input_link_ctls[i]->id); } @@ -8577,8 +8258,7 @@ static int scarlett2_find_fc_interface(struct usb_device *dev, epd = get_endpoint(intf->altsetting, 0); private->bInterfaceNumber = desc->bInterfaceNumber; - private->bEndpointAddress = epd->bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK; + private->bEndpointAddress = usb_endpoint_num(epd); private->wMaxPacketSize = le16_to_cpu(epd->wMaxPacketSize); private->bInterval = epd->bInterval; return 0; @@ -9130,9 +8810,8 @@ static int snd_scarlett2_controls_create( */ static void scarlett2_lock(struct scarlett2_data *private) { - mutex_lock(&private->data_mutex); + guard(mutex)(&private->data_mutex); private->hwdep_in_use = 1; - mutex_unlock(&private->data_mutex); } /* Call SCARLETT2_USB_GET_ERASE to get the erase progress */ @@ -9404,7 +9083,7 @@ static long scarlett2_hwdep_read(struct snd_hwdep *hw, __le32 len; } __packed req; - u8 *resp; + u8 *resp __free(kfree) = NULL; /* Flash segment must first be selected */ if (private->flash_write_state != SCARLETT2_FLASH_WRITE_STATE_SELECTED) @@ -9450,20 +9129,14 @@ static long scarlett2_hwdep_read(struct snd_hwdep *hw, err = scarlett2_usb(mixer, SCARLETT2_USB_READ_SEGMENT, &req, sizeof(req), resp, count); if (err < 0) - goto error; + return err; /* Copy the response to userspace */ - if (copy_to_user(buf, resp, count)) { - err = -EFAULT; - goto error; - } + if (copy_to_user(buf, resp, count)) + return -EFAULT; *offset += count; - err = count; - -error: - kfree(resp); - return err; + return count; } static long scarlett2_hwdep_write(struct snd_hwdep *hw, @@ -9481,7 +9154,7 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw, __le32 offset; __le32 pad; u8 data[]; - } __packed *req; + } __packed *req __free(kfree) = NULL; /* Calculate the maximum permitted in data[] */ const size_t max_data_size = SCARLETT2_FLASH_RW_MAX - @@ -9516,7 +9189,7 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw, SCARLETT2_FLASH_BLOCK_SIZE; if (count < 0 || *offset < 0 || *offset + count >= flash_size) - return -EINVAL; + return -ENOSPC; if (!count) return 0; @@ -9535,22 +9208,16 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw, req->offset = cpu_to_le32(*offset); req->pad = 0; - if (copy_from_user(req->data, buf, count)) { - err = -EFAULT; - goto error; - } + if (copy_from_user(req->data, buf, count)) + return -EFAULT; err = scarlett2_usb(mixer, SCARLETT2_USB_WRITE_SEGMENT, req, len, NULL, 0); if (err < 0) - goto error; + return err; *offset += count; - err = count; - -error: - kfree(req); - return err; + return count; } static int scarlett2_hwdep_release(struct snd_hwdep *hw, struct file *file) @@ -9589,6 +9256,111 @@ static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer) return 0; } +/*** device-map file ***/ + +static ssize_t scarlett2_devmap_read( + struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + char __user *buf, + size_t count, + loff_t pos) +{ + struct usb_mixer_interface *mixer = entry->private_data; + u8 *resp_buf __free(kfree) = NULL; + const size_t block_size = SCARLETT2_DEVMAP_BLOCK_SIZE; + size_t copied = 0; + + if (pos >= entry->size) + return 0; + + if (pos + count > entry->size) + count = entry->size - pos; + + resp_buf = kmalloc(block_size, GFP_KERNEL); + if (!resp_buf) + return -ENOMEM; + + while (count > 0) { + /* SCARLETT2_USB_GET_DEVMAP reads only on block boundaries, + * so we need to read a whole block and copy the requested + * chunk to userspace. + */ + + __le32 req; + int err; + + /* offset within the block that we're reading */ + size_t offset = pos % block_size; + + /* read_size is block_size except for the last block */ + size_t block_start = pos - offset; + size_t read_size = min_t(size_t, + block_size, + entry->size - block_start); + + /* size of the chunk to copy to userspace */ + size_t copy_size = min_t(size_t, count, read_size - offset); + + /* request the block */ + req = cpu_to_le32(pos / block_size); + err = scarlett2_usb(mixer, SCARLETT2_USB_GET_DEVMAP, + &req, sizeof(req), resp_buf, read_size); + if (err < 0) + return copied ? copied : err; + + if (copy_to_user(buf, resp_buf + offset, copy_size)) + return -EFAULT; + + buf += copy_size; + pos += copy_size; + copied += copy_size; + count -= copy_size; + } + + return copied; +} + +static const struct snd_info_entry_ops scarlett2_devmap_ops = { + .read = scarlett2_devmap_read, +}; + +static int scarlett2_devmap_init(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; + __le16 config_len_buf[2]; + int config_len; + struct snd_info_entry *entry; + int err; + + /* If the device doesn't support the DEVMAP commands, don't + * create the /proc/asound/cardX/scarlett.json.zlib entry + */ + if (!info->has_devmap) + return 0; + + err = scarlett2_usb(mixer, SCARLETT2_USB_INFO_DEVMAP, + NULL, 0, &config_len_buf, sizeof(config_len_buf)); + if (err < 0) + return err; + + config_len = le16_to_cpu(config_len_buf[1]); + + err = snd_card_proc_new(card, SCARLETT2_DEVMAP_FILENAME, &entry); + if (err < 0) + return err; + + entry->content = SNDRV_INFO_CONTENT_DATA; + entry->private_data = mixer; + entry->c.ops = &scarlett2_devmap_ops; + entry->size = config_len; + entry->mode = S_IFREG | 0444; + + return 0; +} + int snd_scarlett2_init(struct usb_mixer_interface *mixer) { struct snd_usb_audio *chip = mixer->chip; @@ -9599,6 +9371,10 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer) if (!mixer->protocol) return 0; + /* check if the user wants to use the FCP driver instead */ + if (chip->setup & SCARLETT2_USE_FCP_DRIVER) + return snd_fcp_init(mixer); + /* find entry in scarlett2_devices */ entry = get_scarlett2_device_entry(mixer); if (!entry) { @@ -9639,11 +9415,20 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer) } err = scarlett2_hwdep_init(mixer); - if (err < 0) + if (err < 0) { usb_audio_err(mixer->chip, "Error creating %s hwdep device: %d", entry->series_name, err); + return err; + } + + err = scarlett2_devmap_init(mixer); + if (err < 0) + usb_audio_err(mixer->chip, + "Error creating %s devmap entry: %d", + entry->series_name, + err); return err; } |
