@@ -541,6 +541,7 @@ enum {
541541 SCARLETT2_CONFIG_PCM_INPUT_SWITCH ,
542542 SCARLETT2_CONFIG_DIRECT_MONITOR_GAIN ,
543543 SCARLETT2_CONFIG_BLUETOOTH_VOLUME ,
544+ SCARLETT2_CONFIG_SPDIF_MODE ,
544545 SCARLETT2_CONFIG_COUNT
545546};
546547
@@ -754,6 +755,9 @@ static const struct scarlett2_config_set scarlett2_config_set_gen3c = {
754755
755756 [SCARLETT2_CONFIG_TALKBACK_MAP ] = {
756757 .offset = 0xb0 , .size = 16 , .activate = 10 },
758+
759+ [SCARLETT2_CONFIG_SPDIF_MODE ] = {
760+ .offset = 0x94 , .size = 8 , .activate = 6 },
757761 }
758762};
759763
@@ -977,6 +981,9 @@ static const struct scarlett2_config_set scarlett2_config_set_clarett = {
977981
978982 [SCARLETT2_CONFIG_STANDALONE_SWITCH ] = {
979983 .offset = 0x8d , .size = 8 , .activate = 6 },
984+
985+ [SCARLETT2_CONFIG_SPDIF_MODE ] = {
986+ .offset = 0x9e , .size = 8 , .activate = 4 },
980987 }
981988};
982989
@@ -1147,6 +1154,11 @@ struct scarlett2_device_info {
11471154 /* has a Bluetooth module with volume control */
11481155 u8 has_bluetooth ;
11491156
1157+ /* S/PDIF Source/Digital I/O mode control */
1158+ const char * const spdif_mode_control_name ;
1159+ const u8 * spdif_mode_values ;
1160+ const char * const * spdif_mode_texts ;
1161+
11501162 /* remap analogue outputs; 18i8 Gen 3 has "line 3/4" connected
11511163 * internally to the analogue 7/8 outputs
11521164 */
@@ -1255,6 +1267,7 @@ struct scarlett2_data {
12551267 u8 standalone_switch ;
12561268 u8 power_status ;
12571269 u8 bluetooth_volume ;
1270+ u8 spdif_mode ;
12581271 u8 meter_level_map [SCARLETT2_MAX_METERS ];
12591272 struct snd_kcontrol * sync_ctl ;
12601273 struct snd_kcontrol * master_vol_ctl ;
@@ -1582,6 +1595,14 @@ static const struct scarlett2_device_info s8i6_gen3_info = {
15821595 }
15831596};
15841597
1598+ static const u8 scarlett2_spdif_s18i8_gen3_values [] = { 0 , 2 , 0xff };
1599+
1600+ static const char * const scarlett2_spdif_s18i8_gen3_texts [] = {
1601+ "RCA" ,
1602+ "Optical" ,
1603+ NULL
1604+ };
1605+
15851606static const struct scarlett2_device_info s18i8_gen3_info = {
15861607 .config_set = & scarlett2_config_set_gen3c ,
15871608 .has_speaker_switching = 1 ,
@@ -1591,6 +1612,10 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
15911612 .phantom_count = 2 ,
15921613 .inputs_per_phantom = 2 ,
15931614
1615+ .spdif_mode_control_name = "S/PDIF Mode Capture Enum" ,
1616+ .spdif_mode_values = scarlett2_spdif_s18i8_gen3_values ,
1617+ .spdif_mode_texts = scarlett2_spdif_s18i8_gen3_texts ,
1618+
15941619 .line_out_remap_enable = 1 ,
15951620 .line_out_remap = { 0 , 1 , 6 , 7 , 2 , 3 , 4 , 5 },
15961621 .line_out_unmap = { 0 , 1 , 4 , 5 , 6 , 7 , 2 , 3 },
@@ -1661,6 +1686,15 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
16611686 }
16621687};
16631688
1689+ static const u8 scarlett2_spdif_s18i20_gen3_values [] = { 0 , 6 , 1 , 0xff };
1690+
1691+ static const char * const scarlett2_spdif_s18i20_gen3_texts [] = {
1692+ "S/PDIF RCA" ,
1693+ "S/PDIF Optical" ,
1694+ "Dual ADAT" ,
1695+ NULL
1696+ };
1697+
16641698static const struct scarlett2_device_info s18i20_gen3_info = {
16651699 .config_set = & scarlett2_config_set_gen3c ,
16661700 .has_speaker_switching = 1 ,
@@ -1671,6 +1705,10 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
16711705 .phantom_count = 2 ,
16721706 .inputs_per_phantom = 4 ,
16731707
1708+ .spdif_mode_control_name = "Digital I/O Mode Capture Enum" ,
1709+ .spdif_mode_values = scarlett2_spdif_s18i20_gen3_values ,
1710+ .spdif_mode_texts = scarlett2_spdif_s18i20_gen3_texts ,
1711+
16741712 .line_out_descrs = {
16751713 "Monitor 1 L" ,
16761714 "Monitor 1 R" ,
@@ -2019,11 +2057,24 @@ static const struct scarlett2_device_info clarett_2pre_info = {
20192057 }
20202058};
20212059
2060+ static const u8 scarlett2_spdif_clarett_values [] = { 0 , 1 , 2 , 0xff };
2061+
2062+ static const char * const scarlett2_spdif_clarett_texts [] = {
2063+ "None" ,
2064+ "Optical" ,
2065+ "RCA" ,
2066+ NULL
2067+ };
2068+
20222069static const struct scarlett2_device_info clarett_4pre_info = {
20232070 .config_set = & scarlett2_config_set_clarett ,
20242071 .level_input_count = 2 ,
20252072 .air_input_count = 4 ,
20262073
2074+ .spdif_mode_control_name = "S/PDIF Source Capture Enum" ,
2075+ .spdif_mode_values = scarlett2_spdif_clarett_values ,
2076+ .spdif_mode_texts = scarlett2_spdif_clarett_texts ,
2077+
20272078 .line_out_descrs = {
20282079 "Monitor L" ,
20292080 "Monitor R" ,
@@ -2076,6 +2127,10 @@ static const struct scarlett2_device_info clarett_8pre_info = {
20762127 .level_input_count = 2 ,
20772128 .air_input_count = 8 ,
20782129
2130+ .spdif_mode_control_name = "S/PDIF Source Capture Enum" ,
2131+ .spdif_mode_values = scarlett2_spdif_clarett_values ,
2132+ .spdif_mode_texts = scarlett2_spdif_clarett_texts ,
2133+
20792134 .line_out_descrs = {
20802135 "Monitor L" ,
20812136 "Monitor R" ,
@@ -7885,6 +7940,121 @@ static int scarlett2_add_bluetooth_volume_ctl(
78857940 & private -> bluetooth_volume_ctl );
78867941}
78877942
7943+ /*** S/PDIF Mode Controls ***/
7944+
7945+ static int scarlett2_update_spdif_mode (struct usb_mixer_interface * mixer )
7946+ {
7947+ struct scarlett2_data * private = mixer -> private_data ;
7948+ int err , i ;
7949+ u8 mode ;
7950+ const u8 * mode_values = private -> info -> spdif_mode_values ;
7951+
7952+ if (!private -> info -> spdif_mode_control_name )
7953+ return 0 ;
7954+
7955+ err = scarlett2_usb_get_config (mixer , SCARLETT2_CONFIG_SPDIF_MODE ,
7956+ 1 , & mode );
7957+ if (err < 0 )
7958+ return err ;
7959+
7960+ private -> spdif_mode = 0 ;
7961+
7962+ for (i = 0 ; * mode_values != 0xff ; i ++ , mode_values ++ )
7963+ if (* mode_values == mode ) {
7964+ private -> spdif_mode = i ;
7965+ break ;
7966+ }
7967+
7968+ return 0 ;
7969+ }
7970+
7971+ static int scarlett2_spdif_mode_ctl_info (struct snd_kcontrol * kctl ,
7972+ struct snd_ctl_elem_info * uinfo )
7973+ {
7974+ struct usb_mixer_elem_info * elem = kctl -> private_data ;
7975+ struct scarlett2_data * private = elem -> head .mixer -> private_data ;
7976+ const char * const * mode_texts = private -> info -> spdif_mode_texts ;
7977+ int count = 0 ;
7978+
7979+ while (* mode_texts ++ )
7980+ count ++ ;
7981+
7982+ return snd_ctl_enum_info (uinfo , 1 , count ,
7983+ private -> info -> spdif_mode_texts );
7984+ }
7985+
7986+ static int scarlett2_spdif_mode_ctl_get (struct snd_kcontrol * kctl ,
7987+ struct snd_ctl_elem_value * ucontrol )
7988+ {
7989+ struct usb_mixer_elem_info * elem = kctl -> private_data ;
7990+ struct scarlett2_data * private = elem -> head .mixer -> private_data ;
7991+
7992+ ucontrol -> value .enumerated .item [0 ] = private -> spdif_mode ;
7993+ return 0 ;
7994+ }
7995+
7996+ static int scarlett2_spdif_mode_ctl_put (struct snd_kcontrol * kctl ,
7997+ struct snd_ctl_elem_value * ucontrol )
7998+ {
7999+ struct usb_mixer_elem_info * elem = kctl -> private_data ;
8000+ struct usb_mixer_interface * mixer = elem -> head .mixer ;
8001+ struct scarlett2_data * private = mixer -> private_data ;
8002+ int oval , val , err = 0 ;
8003+ int i ;
8004+
8005+ mutex_lock (& private -> data_mutex );
8006+
8007+ oval = private -> spdif_mode ;
8008+ val = ucontrol -> value .enumerated .item [0 ];
8009+
8010+ if (val < 0 ) {
8011+ err = - EINVAL ;
8012+ goto unlock ;
8013+ }
8014+
8015+ for (i = 0 ; i <= val ; i ++ )
8016+ if (private -> info -> spdif_mode_values [i ] == 0xff ) {
8017+ err = - EINVAL ;
8018+ goto unlock ;
8019+ }
8020+
8021+ if (oval == val )
8022+ goto unlock ;
8023+
8024+ private -> spdif_mode = val ;
8025+
8026+ err = scarlett2_usb_set_config (
8027+ mixer , SCARLETT2_CONFIG_SPDIF_MODE , 0 ,
8028+ private -> info -> spdif_mode_values [val ]);
8029+ if (!err )
8030+ err = 1 ;
8031+
8032+ unlock :
8033+ mutex_unlock (& private -> data_mutex );
8034+ return err ;
8035+ }
8036+
8037+ static const struct snd_kcontrol_new scarlett2_spdif_mode_ctl = {
8038+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
8039+ .name = "" ,
8040+ .info = scarlett2_spdif_mode_ctl_info ,
8041+ .get = scarlett2_spdif_mode_ctl_get ,
8042+ .put = scarlett2_spdif_mode_ctl_put ,
8043+ };
8044+
8045+ static int scarlett2_add_spdif_mode_ctl (struct usb_mixer_interface * mixer )
8046+ {
8047+ struct scarlett2_data * private = mixer -> private_data ;
8048+
8049+ if (!private -> info -> spdif_mode_control_name )
8050+ return 0 ;
8051+
8052+ return scarlett2_add_new_ctl (mixer , & scarlett2_spdif_mode_ctl ,
8053+ 0 , 1 ,
8054+ private -> info -> spdif_mode_control_name ,
8055+ NULL );
8056+ }
8057+
78888058/*** Notification Handlers ***/
78898059
78908060/* Notify on sync change */
@@ -8797,6 +8967,10 @@ static int scarlett2_read_configs(struct usb_mixer_interface *mixer)
87978967 if (err < 0 )
87988968 return err ;
87998969
8970+ err = scarlett2_update_spdif_mode (mixer );
8971+ if (err < 0 )
8972+ return err ;
8973+
88008974 err = scarlett2_update_mix (mixer );
88018975 if (err < 0 )
88028976 return err ;
@@ -8929,6 +9103,11 @@ static int snd_scarlett2_controls_create(
89299103 if (err < 0 )
89309104 return err ;
89319105
9106+ /* Create the S/PDIF mode control */
9107+ err = scarlett2_add_spdif_mode_ctl (mixer );
9108+ if (err < 0 )
9109+ return err ;
9110+
89329111 /* Set the access mode of controls disabled during
89339112 * autogain/phantom power switching.
89349113 */
0 commit comments