summaryrefslogtreecommitdiff
path: root/sound/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/mixer_scarlett2.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c
index ce842c29be5e..d6e2f69c32b9 100644
--- a/sound/usb/mixer_scarlett2.c
+++ b/sound/usb/mixer_scarlett2.c
@@ -760,6 +760,7 @@ struct scarlett2_data {
u8 monitor_other_updated;
u8 direct_monitor_updated;
u8 mux_updated;
+ u8 mix_updated;
u8 speaker_switching_switched;
u8 power_status_updated;
u8 sync;
@@ -804,6 +805,7 @@ struct scarlett2_data {
struct snd_kcontrol *autogain_status_ctls[SCARLETT2_INPUT_GAIN_MAX];
struct snd_kcontrol *safe_ctls[SCARLETT2_INPUT_GAIN_MAX];
struct snd_kcontrol *mux_ctls[SCARLETT2_MUX_MAX];
+ struct snd_kcontrol *mix_ctls[SCARLETT2_MIX_MAX];
struct snd_kcontrol *direct_monitor_ctl;
struct snd_kcontrol *speaker_switching_ctl;
struct snd_kcontrol *talkback_ctl;
@@ -4960,6 +4962,22 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
/*** Mixer Volume Controls ***/
+static int scarlett2_update_mix(struct usb_mixer_interface *mixer)
+{
+ struct scarlett2_data *private = mixer->private_data;
+ int i, err;
+
+ private->mix_updated = 0;
+
+ for (i = 0; i < private->num_mix_out; i++) {
+ err = scarlett2_usb_get_mix(mixer, i);
+ if (err < 0)
+ return err;
+ }
+
+ return 1;
+}
+
static int scarlett2_mixer_ctl_info(struct snd_kcontrol *kctl,
struct snd_ctl_elem_info *uinfo)
{
@@ -4977,10 +4995,27 @@ static int scarlett2_mixer_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;
+ struct usb_mixer_interface *mixer = elem->head.mixer;
+ struct scarlett2_data *private = mixer->private_data;
+ int err = 0;
+ mutex_lock(&private->data_mutex);
+
+ if (private->hwdep_in_use) {
+ err = -EBUSY;
+ goto unlock;
+ }
+
+ if (private->mix_updated) {
+ err = scarlett2_update_mix(mixer);
+ if (err < 0)
+ goto unlock;
+ }
ucontrol->value.integer.value[0] = private->mix[elem->control];
- return 0;
+
+unlock:
+ mutex_unlock(&private->data_mutex);
+ return err;
}
static int scarlett2_mixer_ctl_put(struct snd_kcontrol *kctl,
@@ -5048,7 +5083,8 @@ static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *mixer)
"Mix %c Input %02d Playback Volume",
'A' + i, j + 1);
err = scarlett2_add_new_ctl(mixer, &scarlett2_mixer_ctl,
- index, 1, s, NULL);
+ index, 1, s,
+ &private->mix_ctls[index]);
if (err < 0)
return err;
}
@@ -5993,11 +6029,9 @@ static int scarlett2_read_configs(struct usb_mixer_interface *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)
- return err;
- }
+ err = scarlett2_update_mix(mixer);
+ if (err < 0)
+ return err;
return scarlett2_usb_get_mux(mixer);
}