*/
u8 direct_monitor;
+ /* remap analogue outputs; 18i8 Gen 3 has "line 3/4" connected
+ * internally to the analogue 7/8 outputs
+ */
+ u8 line_out_remap_enable;
+ u8 line_out_remap[SCARLETT2_ANALOGUE_MAX];
+
/* additional description for the line out volume controls */
const char * const line_out_descrs[SCARLETT2_ANALOGUE_MAX];
.phantom_count = 2,
.inputs_per_phantom = 2,
+ .line_out_remap_enable = 1,
+ .line_out_remap = { 0, 1, 6, 7, 2, 3, 4, 5 },
+
.line_out_descrs = {
"Monitor L",
"Monitor R",
+ "Alt Monitor L",
+ "Alt Monitor R",
"Headphones 1 L",
"Headphones 1 R",
"Headphones 2 L",
"Headphones 2 R",
- "Alt Monitor L",
- "Alt Monitor R",
},
.port_count = {
return 0;
}
+static int line_out_remap(struct scarlett2_data *private, int index)
+{
+ const struct scarlett2_device_info *info = private->info;
+
+ if (!info->line_out_remap_enable)
+ return index;
+ return info->line_out_remap[index];
+}
+
static int scarlett2_volume_ctl_get(struct snd_kcontrol *kctl,
struct snd_ctl_elem_value *ucontrol)
{
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
- int index = elem->control;
+ int index = line_out_remap(private, elem->control);
mutex_lock(&private->data_mutex);
if (private->vol_updated)
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 index = line_out_remap(private, elem->control);
int oval, val, err = 0;
mutex_lock(&private->data_mutex);
{
struct usb_mixer_elem_info *elem = kctl->private_data;
struct scarlett2_data *private = elem->head.mixer->private_data;
- int index = elem->control;
+ int index = line_out_remap(private, elem->control);
ucontrol->value.integer.value[0] = private->mute_switch[index];
return 0;
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 index = line_out_remap(private, elem->control);
int oval, val, err = 0;
mutex_lock(&private->data_mutex);
{
struct usb_mixer_elem_info *elem = kctl->private_data;
struct scarlett2_data *private = elem->head.mixer->private_data;
+ int index = line_out_remap(private, elem->control);
- ucontrol->value.enumerated.item[0] =
- private->vol_sw_hw_switch[elem->control];
+ ucontrol->value.enumerated.item[0] = private->vol_sw_hw_switch[index];
return 0;
}
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 ctl_index = elem->control;
+ int index = line_out_remap(private, ctl_index);
int oval, val, err = 0;
mutex_lock(&private->data_mutex);
/* Change access mode to RO (hardware controlled volume)
* or RW (software controlled volume)
*/
- scarlett2_vol_ctl_set_writable(mixer, index, !val);
+ scarlett2_vol_ctl_set_writable(mixer, ctl_index, !val);
/* Reset volume/mute to master volume/mute */
private->vol[index] = private->master_vol;
err = 1;
if (index == SCARLETT2_BUTTON_MUTE)
- for (i = 0; i < num_line_out; i++)
- if (private->vol_sw_hw_switch[i]) {
- private->mute_switch[i] = val;
+ for (i = 0; i < num_line_out; i++) {
+ int line_index = line_out_remap(private, i);
+
+ if (private->vol_sw_hw_switch[line_index]) {
+ private->mute_switch[line_index] = val;
snd_ctl_notify(mixer->chip->card,
SNDRV_CTL_EVENT_MASK_INFO,
&private->mute_ctls[i]->id);
}
+ }
unlock:
mutex_unlock(&private->data_mutex);
/* Add volume controls */
for (i = 0; i < num_line_out; i++) {
+ int index = line_out_remap(private, i);
/* Fader */
if (info->line_out_descrs[i])
/* Make the fader and mute controls read-only if the
* SW/HW switch is set to HW
*/
- if (private->vol_sw_hw_switch[i])
+ if (private->vol_sw_hw_switch[index])
scarlett2_vol_ctl_set_writable(mixer, i, 0);
/* SW/HW Switch */
{
struct usb_mixer_elem_info *elem = kctl->private_data;
struct scarlett2_data *private = elem->head.mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int line_out_count =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
+ int index = elem->control;
+
+ if (index < line_out_count)
+ index = line_out_remap(private, index);
- ucontrol->value.enumerated.item[0] = private->mux[elem->control];
+ ucontrol->value.enumerated.item[0] = private->mux[index];
return 0;
}
struct usb_mixer_elem_info *elem = kctl->private_data;
struct usb_mixer_interface *mixer = elem->head.mixer;
struct scarlett2_data *private = mixer->private_data;
+ const struct scarlett2_device_info *info = private->info;
+ const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
+ int line_out_count =
+ port_count[SCARLETT2_PORT_TYPE_ANALOGUE][SCARLETT2_PORT_OUT];
int index = elem->control;
int oval, val, err = 0;
+ if (index < line_out_count)
+ index = line_out_remap(private, index);
+
mutex_lock(&private->data_mutex);
oval = private->mux[index];
static void scarlett2_notify_monitor(
struct usb_mixer_interface *mixer)
{
+ struct snd_card *card = mixer->chip->card;
struct scarlett2_data *private = mixer->private_data;
const struct scarlett2_device_info *info = private->info;
const int (*port_count)[SCARLETT2_PORT_DIRNS] = info->port_count;
snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->master_vol_ctl->id);
- for (i = 0; i < num_line_out; i++) {
- if (!private->vol_sw_hw_switch[i])
- continue;
- snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
- &private->vol_ctls[i]->id);
- }
+ for (i = 0; i < num_line_out; i++)
+ if (private->vol_sw_hw_switch[line_out_remap(private, i)])
+ snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &private->vol_ctls[i]->id);
}
/* Notify on dim/mute change */
&private->dim_mute_ctls[i]->id);
for (i = 0; i < num_line_out; i++)
- if (private->vol_sw_hw_switch[i])
+ if (private->vol_sw_hw_switch[line_out_remap(private, i)])
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE,
&private->mute_ctls[i]->id);
}