Commit ac19be06 authored by Geoffrey D. Bennett's avatar Geoffrey D. Bennett Committed by Takashi Iwai

ALSA: scarlett2: Store mix_ctls for Gen 4 Direct Monitor

The Scarlett 4th Gen small interfaces have a software-controllable
mixer like the large 2nd and 3rd Gen interfaces do. Pressing the
"Direct" button on the interface updates the mixer controls, which
this driver hasn't needed to deal with previously.

This commit stores the ALSA mixer controls, and adds a mix_updated
flag so that the controls can be updated when a notification is
received.
Signed-off-by: default avatarGeoffrey D. Bennett <g@b4.vu>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/3ba27c60230511b80b0fa75727551ea70f17d829.1703612638.git.g@b4.vu
parent d7cfa2fd
...@@ -760,6 +760,7 @@ struct scarlett2_data { ...@@ -760,6 +760,7 @@ struct scarlett2_data {
u8 monitor_other_updated; u8 monitor_other_updated;
u8 direct_monitor_updated; u8 direct_monitor_updated;
u8 mux_updated; u8 mux_updated;
u8 mix_updated;
u8 speaker_switching_switched; u8 speaker_switching_switched;
u8 power_status_updated; u8 power_status_updated;
u8 sync; u8 sync;
...@@ -804,6 +805,7 @@ struct scarlett2_data { ...@@ -804,6 +805,7 @@ struct scarlett2_data {
struct snd_kcontrol *autogain_status_ctls[SCARLETT2_INPUT_GAIN_MAX]; struct snd_kcontrol *autogain_status_ctls[SCARLETT2_INPUT_GAIN_MAX];
struct snd_kcontrol *safe_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 *mux_ctls[SCARLETT2_MUX_MAX];
struct snd_kcontrol *mix_ctls[SCARLETT2_MIX_MAX];
struct snd_kcontrol *direct_monitor_ctl; struct snd_kcontrol *direct_monitor_ctl;
struct snd_kcontrol *speaker_switching_ctl; struct snd_kcontrol *speaker_switching_ctl;
struct snd_kcontrol *talkback_ctl; struct snd_kcontrol *talkback_ctl;
...@@ -4960,6 +4962,22 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer) ...@@ -4960,6 +4962,22 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
/*** Mixer Volume Controls ***/ /*** 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, static int scarlett2_mixer_ctl_info(struct snd_kcontrol *kctl,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
...@@ -4977,10 +4995,27 @@ static int scarlett2_mixer_ctl_get(struct snd_kcontrol *kctl, ...@@ -4977,10 +4995,27 @@ static int scarlett2_mixer_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct usb_mixer_elem_info *elem = kctl->private_data; 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]; 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, 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) ...@@ -5048,7 +5083,8 @@ static int scarlett2_add_mixer_ctls(struct usb_mixer_interface *mixer)
"Mix %c Input %02d Playback Volume", "Mix %c Input %02d Playback Volume",
'A' + i, j + 1); 'A' + i, j + 1);
err = scarlett2_add_new_ctl(mixer, &scarlett2_mixer_ctl, err = scarlett2_add_new_ctl(mixer, &scarlett2_mixer_ctl,
index, 1, s, NULL); index, 1, s,
&private->mix_ctls[index]);
if (err < 0) if (err < 0)
return err; return err;
} }
...@@ -5993,11 +6029,9 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer) ...@@ -5993,11 +6029,9 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
if (err < 0) if (err < 0)
return err; return err;
for (i = 0; i < private->num_mix_out; i++) { err = scarlett2_update_mix(mixer);
err = scarlett2_usb_get_mix(mixer, i); if (err < 0)
if (err < 0) return err;
return err;
}
return scarlett2_usb_get_mux(mixer); return scarlett2_usb_get_mux(mixer);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment