Skip to content

Commit 604b388

Browse files
geoffreybennetttiwai
authored andcommitted
ALSA: scarlett2: Add support for the internal "standalone" switch
The Focusrite Scarlett Gen 2/3 interfaces with internal mixers have a "standalone" mode. When the interface is not connected to a USB host and standalone mode is enabled, the interface will pass audio as previously configured. This patch adds an ALSA control to allow enabling/disabling that mode. Signed-off-by: Geoffrey D. Bennett <g@b4.vu> Link: https://lore.kernel.org/r/cd88871c5e77abd5c23a4758a1f2ec9fd427fd69.1646578164.git.g@b4.vu Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 441d1e1 commit 604b388

1 file changed

Lines changed: 90 additions & 7 deletions

File tree

sound/usb/mixer_scarlett_gen2.c

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
* - phantom power, direct monitor, speaker switching, and talkback
6161
* controls
6262
* - disable/enable MSD mode
63+
* - disable/enable standalone mode
6364
*
6465
* <ditaa>
6566
* /--------------\ 18chn 20chn /--------------\
@@ -411,6 +412,7 @@ struct scarlett2_data {
411412
u8 talkback_switch;
412413
u8 talkback_map[SCARLETT2_OUTPUT_MIX_MAX];
413414
u8 msd_switch;
415+
u8 standalone_switch;
414416
struct snd_kcontrol *sync_ctl;
415417
struct snd_kcontrol *master_vol_ctl;
416418
struct snd_kcontrol *vol_ctls[SCARLETT2_ANALOGUE_MAX];
@@ -936,13 +938,14 @@ enum {
936938
SCARLETT2_CONFIG_PAD_SWITCH = 5,
937939
SCARLETT2_CONFIG_MSD_SWITCH = 6,
938940
SCARLETT2_CONFIG_AIR_SWITCH = 7,
939-
SCARLETT2_CONFIG_PHANTOM_SWITCH = 8,
940-
SCARLETT2_CONFIG_PHANTOM_PERSISTENCE = 9,
941-
SCARLETT2_CONFIG_DIRECT_MONITOR = 10,
942-
SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH = 11,
943-
SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE = 12,
944-
SCARLETT2_CONFIG_TALKBACK_MAP = 13,
945-
SCARLETT2_CONFIG_COUNT = 14
941+
SCARLETT2_CONFIG_STANDALONE_SWITCH = 8,
942+
SCARLETT2_CONFIG_PHANTOM_SWITCH = 9,
943+
SCARLETT2_CONFIG_PHANTOM_PERSISTENCE = 10,
944+
SCARLETT2_CONFIG_DIRECT_MONITOR = 11,
945+
SCARLETT2_CONFIG_MONITOR_OTHER_SWITCH = 12,
946+
SCARLETT2_CONFIG_MONITOR_OTHER_ENABLE = 13,
947+
SCARLETT2_CONFIG_TALKBACK_MAP = 14,
948+
SCARLETT2_CONFIG_COUNT = 15
946949
};
947950

948951
/* Location, size, and activation command number for the configuration
@@ -998,6 +1001,9 @@ static const struct scarlett2_config
9981001
[SCARLETT2_CONFIG_PAD_SWITCH] = {
9991002
.offset = 0x84, .size = 8, .activate = 8 },
10001003

1004+
[SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
1005+
.offset = 0x8d, .size = 8, .activate = 6 },
1006+
10011007
/* Gen 3 devices: 4i4, 8i6, 18i8, 18i20 */
10021008
}, {
10031009
[SCARLETT2_CONFIG_DIM_MUTE] = {
@@ -1021,6 +1027,9 @@ static const struct scarlett2_config
10211027
[SCARLETT2_CONFIG_AIR_SWITCH] = {
10221028
.offset = 0x8c, .size = 8, .activate = 8 },
10231029

1030+
[SCARLETT2_CONFIG_STANDALONE_SWITCH] = {
1031+
.offset = 0x95, .size = 8, .activate = 6 },
1032+
10241033
[SCARLETT2_CONFIG_PHANTOM_SWITCH] = {
10251034
.offset = 0x9c, .size = 1, .activate = 8 },
10261035

@@ -3502,6 +3511,69 @@ static int scarlett2_add_msd_ctl(struct usb_mixer_interface *mixer)
35023511
0, 1, "MSD Mode Switch", NULL);
35033512
}
35043513

3514+
/*** Standalone Control ***/
3515+
3516+
static int scarlett2_standalone_ctl_get(struct snd_kcontrol *kctl,
3517+
struct snd_ctl_elem_value *ucontrol)
3518+
{
3519+
struct usb_mixer_elem_info *elem = kctl->private_data;
3520+
struct scarlett2_data *private = elem->head.mixer->private_data;
3521+
3522+
ucontrol->value.integer.value[0] = private->standalone_switch;
3523+
return 0;
3524+
}
3525+
3526+
static int scarlett2_standalone_ctl_put(struct snd_kcontrol *kctl,
3527+
struct snd_ctl_elem_value *ucontrol)
3528+
{
3529+
struct usb_mixer_elem_info *elem = kctl->private_data;
3530+
struct usb_mixer_interface *mixer = elem->head.mixer;
3531+
struct scarlett2_data *private = mixer->private_data;
3532+
3533+
int oval, val, err = 0;
3534+
3535+
mutex_lock(&private->data_mutex);
3536+
3537+
oval = private->standalone_switch;
3538+
val = !!ucontrol->value.integer.value[0];
3539+
3540+
if (oval == val)
3541+
goto unlock;
3542+
3543+
private->standalone_switch = val;
3544+
3545+
/* Send switch change to the device */
3546+
err = scarlett2_usb_set_config(mixer,
3547+
SCARLETT2_CONFIG_STANDALONE_SWITCH,
3548+
0, val);
3549+
if (err == 0)
3550+
err = 1;
3551+
3552+
unlock:
3553+
mutex_unlock(&private->data_mutex);
3554+
return err;
3555+
}
3556+
3557+
static const struct snd_kcontrol_new scarlett2_standalone_ctl = {
3558+
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3559+
.name = "",
3560+
.info = snd_ctl_boolean_mono_info,
3561+
.get = scarlett2_standalone_ctl_get,
3562+
.put = scarlett2_standalone_ctl_put,
3563+
};
3564+
3565+
static int scarlett2_add_standalone_ctl(struct usb_mixer_interface *mixer)
3566+
{
3567+
struct scarlett2_data *private = mixer->private_data;
3568+
3569+
if (private->info->config_set == SCARLETT2_CONFIG_SET_NO_MIXER)
3570+
return 0;
3571+
3572+
/* Add standalone control */
3573+
return scarlett2_add_new_ctl(mixer, &scarlett2_standalone_ctl,
3574+
0, 1, "Standalone Switch", NULL);
3575+
}
3576+
35053577
/*** Cleanup/Suspend Callbacks ***/
35063578

35073579
static void scarlett2_private_free(struct usb_mixer_interface *mixer)
@@ -3663,6 +3735,12 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
36633735
if (info->config_set == SCARLETT2_CONFIG_SET_NO_MIXER)
36643736
return 0;
36653737

3738+
err = scarlett2_usb_get_config(
3739+
mixer, SCARLETT2_CONFIG_STANDALONE_SWITCH,
3740+
1, &private->standalone_switch);
3741+
if (err < 0)
3742+
return err;
3743+
36663744
err = scarlett2_update_sync(mixer);
36673745
if (err < 0)
36683746
return err;
@@ -3985,6 +4063,11 @@ static int snd_scarlett_gen2_controls_create(struct usb_mixer_interface *mixer)
39854063
if (err < 0)
39864064
return err;
39874065

4066+
/* Create the standalone control */
4067+
err = scarlett2_add_standalone_ctl(mixer);
4068+
if (err < 0)
4069+
return err;
4070+
39884071
/* Set up the interrupt polling */
39894072
err = scarlett2_init_notify(mixer);
39904073
if (err < 0)

0 commit comments

Comments
 (0)