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

ALSA: scarlett2: Add additional input configuration parameters

The 4th Gen Scarlett interfaces added software-controllable input gain
along with channel select, channel link, auto-gain, and "safe" mode.
Vocaster has software-controllable input gain and auto-gain but not
channel select, channel link, or safe mode.

Add a device info field safe_input_count to indicate how many channels
have a safe mode control, and use the presence of the input select and
input link switch configuration parameters to determine if those
controls should be created.
Signed-off-by: default avatarGeoffrey D. Bennett <g@b4.vu>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Message-ID: <167f04a37d0fb23f3077705df835adbc4f2b6a8e.1710264833.git.g@b4.vu>
parent b1b3b258
...@@ -916,6 +916,9 @@ struct scarlett2_device_info { ...@@ -916,6 +916,9 @@ struct scarlett2_device_info {
/* the number of inputs with software-controllable gain */ /* the number of inputs with software-controllable gain */
u8 gain_input_count; u8 gain_input_count;
/* the number of inputs with safe mode */
u8 safe_input_count;
/* the number of direct monitor options /* the number of direct monitor options
* (0 = none, 1 = mono only, 2 = mono/stereo) * (0 = none, 1 = mono only, 2 = mono/stereo)
*/ */
...@@ -1550,6 +1553,7 @@ static const struct scarlett2_device_info s2i2_gen4_info = { ...@@ -1550,6 +1553,7 @@ static const struct scarlett2_device_info s2i2_gen4_info = {
.phantom_count = 1, .phantom_count = 1,
.inputs_per_phantom = 2, .inputs_per_phantom = 2,
.gain_input_count = 2, .gain_input_count = 2,
.safe_input_count = 2,
.direct_monitor = 2, .direct_monitor = 2,
.dsp_count = 2, .dsp_count = 2,
...@@ -1603,6 +1607,7 @@ static const struct scarlett2_device_info s4i4_gen4_info = { ...@@ -1603,6 +1607,7 @@ static const struct scarlett2_device_info s4i4_gen4_info = {
.phantom_count = 2, .phantom_count = 2,
.inputs_per_phantom = 1, .inputs_per_phantom = 1,
.gain_input_count = 2, .gain_input_count = 2,
.safe_input_count = 2,
.dsp_count = 2, .dsp_count = 2,
.port_count = { .port_count = {
...@@ -2937,13 +2942,18 @@ static void scarlett2_autogain_update_access(struct usb_mixer_interface *mixer) ...@@ -2937,13 +2942,18 @@ static void scarlett2_autogain_update_access(struct usb_mixer_interface *mixer)
int val = !scarlett2_autogain_is_running(private); int val = !scarlett2_autogain_is_running(private);
int i; int i;
scarlett2_set_ctl_access(private->input_select_ctl, val); if (scarlett2_has_config_item(private,
for (i = 0; i < info->gain_input_count / 2; i++) SCARLETT2_CONFIG_INPUT_SELECT_SWITCH))
scarlett2_set_ctl_access(private->input_link_ctls[i], val); scarlett2_set_ctl_access(private->input_select_ctl, val);
for (i = 0; i < info->gain_input_count; i++) { if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_LINK_SWITCH))
for (i = 0; i < info->gain_input_count / 2; i++)
scarlett2_set_ctl_access(private->input_link_ctls[i],
val);
for (i = 0; i < info->gain_input_count; i++)
scarlett2_set_ctl_access(private->input_gain_ctls[i], val); scarlett2_set_ctl_access(private->input_gain_ctls[i], val);
for (i = 0; i < info->safe_input_count; i++)
scarlett2_set_ctl_access(private->safe_ctls[i], val); scarlett2_set_ctl_access(private->safe_ctls[i], val);
}
for (i = 0; i < info->level_input_count; i++) for (i = 0; i < info->level_input_count; i++)
scarlett2_set_ctl_access(private->level_ctls[i], val); scarlett2_set_ctl_access(private->level_ctls[i], val);
for (i = 0; i < info->air_input_count; i++) for (i = 0; i < info->air_input_count; i++)
...@@ -2962,17 +2972,21 @@ static void scarlett2_autogain_notify_access(struct usb_mixer_interface *mixer) ...@@ -2962,17 +2972,21 @@ static void scarlett2_autogain_notify_access(struct usb_mixer_interface *mixer)
const struct scarlett2_device_info *info = private->info; const struct scarlett2_device_info *info = private->info;
int i; int i;
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, if (scarlett2_has_config_item(private,
&private->input_select_ctl->id); SCARLETT2_CONFIG_INPUT_SELECT_SWITCH))
for (i = 0; i < info->gain_input_count / 2; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
&private->input_link_ctls[i]->id); &private->input_select_ctl->id);
for (i = 0; i < info->gain_input_count; i++) { if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_LINK_SWITCH))
for (i = 0; i < info->gain_input_count / 2; 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++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
&private->input_gain_ctls[i]->id); &private->input_gain_ctls[i]->id);
for (i = 0; i < info->safe_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
&private->safe_ctls[i]->id); &private->safe_ctls[i]->id);
}
for (i = 0; i < info->level_input_count; i++) for (i = 0; i < info->level_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO,
&private->level_ctls[i]->id); &private->level_ctls[i]->id);
...@@ -3183,7 +3197,9 @@ static int scarlett2_update_input_select(struct usb_mixer_interface *mixer) ...@@ -3183,7 +3197,9 @@ static int scarlett2_update_input_select(struct usb_mixer_interface *mixer)
private->input_select_updated = 0; private->input_select_updated = 0;
if (!link_count) if (!scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_SELECT_SWITCH) ||
!link_count)
return 0; return 0;
err = scarlett2_usb_get_config( err = scarlett2_usb_get_config(
...@@ -3596,12 +3612,12 @@ static int scarlett2_update_input_safe(struct usb_mixer_interface *mixer) ...@@ -3596,12 +3612,12 @@ static int scarlett2_update_input_safe(struct usb_mixer_interface *mixer)
private->input_safe_updated = 0; private->input_safe_updated = 0;
if (!info->gain_input_count) if (!info->safe_input_count)
return 0; return 0;
return scarlett2_usb_get_config( return scarlett2_usb_get_config(
mixer, SCARLETT2_CONFIG_SAFE_SWITCH, mixer, SCARLETT2_CONFIG_SAFE_SWITCH,
info->gain_input_count, private->safe_switch); info->safe_input_count, private->safe_switch);
} }
static int scarlett2_safe_ctl_get(struct snd_kcontrol *kctl, static int scarlett2_safe_ctl_get(struct snd_kcontrol *kctl,
...@@ -5507,58 +5523,65 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer) ...@@ -5507,58 +5523,65 @@ static int scarlett2_add_line_in_ctls(struct usb_mixer_interface *mixer)
return err; return err;
} }
/* Add software-controllable input gain controls */ /* Add input select/link controls */
if (info->gain_input_count) { if (scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_SELECT_SWITCH)) {
err = scarlett2_add_new_ctl( err = scarlett2_add_new_ctl(
mixer, &scarlett2_input_select_ctl, 0, 1, mixer, &scarlett2_input_select_ctl, 0, 1,
"Input Select Capture Enum", "Input Select Capture Enum",
&private->input_select_ctl); &private->input_select_ctl);
if (err < 0) if (err < 0)
return err; return err;
}
for (i = 0; i < info->gain_input_count; i++) { if (scarlett2_has_config_item(private,
if (i % 2) { SCARLETT2_CONFIG_INPUT_LINK_SWITCH)) {
scnprintf(s, sizeof(s), for (i = 0; i < info->gain_input_count / 2; i++) {
"Line In %d-%d Link Capture Switch", scnprintf(s, sizeof(s),
i, i + 1); "Line In %d-%d Link Capture Switch",
err = scarlett2_add_new_ctl( (i * 2) + 1, (i * 2) + 2);
mixer, &scarlett2_input_link_ctl,
i / 2, 1, s,
&private->input_link_ctls[i / 2]);
if (err < 0)
return err;
}
scnprintf(s, sizeof(s), fmt, i + 1,
"Gain", "Volume");
err = scarlett2_add_new_ctl( err = scarlett2_add_new_ctl(
mixer, &scarlett2_input_gain_ctl, mixer, &scarlett2_input_link_ctl,
i, 1, s, &private->input_gain_ctls[i]); i, 1, s, &private->input_link_ctls[i]);
if (err < 0) if (err < 0)
return err; return err;
}
}
scnprintf(s, sizeof(s), fmt, i + 1, /* Add software-controllable input gain controls */
"Autogain", "Switch"); for (i = 0; i < info->gain_input_count; i++) {
err = scarlett2_add_new_ctl( scnprintf(s, sizeof(s), fmt, i + 1,
mixer, &scarlett2_autogain_switch_ctl, "Gain", "Volume");
i, 1, s, &private->autogain_ctls[i]); err = scarlett2_add_new_ctl(
if (err < 0) mixer, &scarlett2_input_gain_ctl,
return err; i, 1, s, &private->input_gain_ctls[i]);
if (err < 0)
return err;
scnprintf(s, sizeof(s), fmt, i + 1, scnprintf(s, sizeof(s), fmt, i + 1,
"Autogain Status", "Enum"); "Autogain", "Switch");
err = scarlett2_add_new_ctl( err = scarlett2_add_new_ctl(
mixer, &scarlett2_autogain_status_ctl, mixer, &scarlett2_autogain_switch_ctl,
i, 1, s, &private->autogain_status_ctls[i]); i, 1, s, &private->autogain_ctls[i]);
if (err < 0)
return err;
scnprintf(s, sizeof(s), fmt, i + 1, scnprintf(s, sizeof(s), fmt, i + 1,
"Safe", "Switch"); "Autogain Status", "Enum");
err = scarlett2_add_new_ctl( err = scarlett2_add_new_ctl(
mixer, &scarlett2_safe_ctl, mixer, &scarlett2_autogain_status_ctl,
i, 1, s, &private->safe_ctls[i]); i, 1, s, &private->autogain_status_ctls[i]);
if (err < 0) }
return err;
} /* Add safe-mode input switch controls */
for (i = 0; i < info->safe_input_count; i++) {
scnprintf(s, sizeof(s), fmt, i + 1,
"Safe", "Switch");
err = scarlett2_add_new_ctl(
mixer, &scarlett2_safe_ctl,
i, 1, s, &private->safe_ctls[i]);
if (err < 0)
return err;
} }
/* Add PCM Input Switch control */ /* Add PCM Input Switch control */
...@@ -6557,7 +6580,8 @@ static void scarlett2_notify_input_select(struct usb_mixer_interface *mixer) ...@@ -6557,7 +6580,8 @@ static void scarlett2_notify_input_select(struct usb_mixer_interface *mixer)
const struct scarlett2_device_info *info = private->info; const struct scarlett2_device_info *info = private->info;
int i; int i;
if (!info->gain_input_count) if (!scarlett2_has_config_item(private,
SCARLETT2_CONFIG_INPUT_SELECT_SWITCH))
return; return;
private->input_select_updated = 1; private->input_select_updated = 1;
...@@ -6620,12 +6644,12 @@ static void scarlett2_notify_input_safe(struct usb_mixer_interface *mixer) ...@@ -6620,12 +6644,12 @@ static void scarlett2_notify_input_safe(struct usb_mixer_interface *mixer)
const struct scarlett2_device_info *info = private->info; const struct scarlett2_device_info *info = private->info;
int i; int i;
if (!info->gain_input_count) if (!info->safe_input_count)
return; return;
private->input_safe_updated = 1; private->input_safe_updated = 1;
for (i = 0; i < info->gain_input_count; i++) for (i = 0; i < info->safe_input_count; i++)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->safe_ctls[i]->id); &private->safe_ctls[i]->id);
} }
......
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