@@ -210,6 +210,9 @@ static const u16 scarlett2_mixer_values[SCARLETT2_MIXER_VALUE_COUNT] = {
210
210
*/
211
211
#define SCARLETT2_MUX_MAX 77
212
212
213
+ /* Maximum number of sources (sum of input port counts) */
214
+ #define SCARLETT2_MAX_SRCS 52
215
+
213
216
/* Maximum number of meters (sum of output port counts) */
214
217
#define SCARLETT2_MAX_METERS 65
215
218
@@ -328,6 +331,18 @@ struct scarlett2_mux_entry {
328
331
u8 count ;
329
332
};
330
333
334
+ /* Maximum number of entries in a mux table */
335
+ #define SCARLETT2_MAX_METER_ENTRIES 9
336
+
337
+ /* One entry within meter_assignment defines the range of mux outputs
338
+ * that consecutive meter entries are mapped to. The end of the list
339
+ * is marked with count == 0.
340
+ */
341
+ struct scarlett2_meter_entry {
342
+ u8 start ;
343
+ u8 count ;
344
+ };
345
+
331
346
struct scarlett2_device_info {
332
347
/* Gen 3 devices have an internal MSD mode switch that needs
333
348
* to be disabled in order to access the full functionality of
@@ -381,6 +396,7 @@ struct scarlett2_device_info {
381
396
*/
382
397
u8 line_out_remap_enable ;
383
398
u8 line_out_remap [SCARLETT2_ANALOGUE_MAX ];
399
+ u8 line_out_unmap [SCARLETT2_ANALOGUE_MAX ];
384
400
385
401
/* additional description for the line out volume controls */
386
402
const char * const line_out_descrs [SCARLETT2_ANALOGUE_MAX ];
@@ -391,6 +407,12 @@ struct scarlett2_device_info {
391
407
/* layout/order of the entries in the set_mux message */
392
408
struct scarlett2_mux_entry mux_assignment [SCARLETT2_MUX_TABLES ]
393
409
[SCARLETT2_MAX_MUX_ENTRIES ];
410
+
411
+ /* map from meter level order returned by
412
+ * SCARLETT2_USB_GET_METER to index into mux[] entries (same
413
+ * as the order returned by scarlett2_meter_ctl_get())
414
+ */
415
+ struct scarlett2_meter_entry meter_map [SCARLETT2_MAX_METER_ENTRIES ];
394
416
};
395
417
396
418
struct scarlett2_data {
@@ -431,6 +453,7 @@ struct scarlett2_data {
431
453
u8 talkback_map [SCARLETT2_OUTPUT_MIX_MAX ];
432
454
u8 msd_switch ;
433
455
u8 standalone_switch ;
456
+ u8 meter_level_map [SCARLETT2_MAX_METERS ];
434
457
struct snd_kcontrol * sync_ctl ;
435
458
struct snd_kcontrol * master_vol_ctl ;
436
459
struct snd_kcontrol * vol_ctls [SCARLETT2_ANALOGUE_MAX ];
@@ -493,6 +516,12 @@ static const struct scarlett2_device_info s6i6_gen2_info = {
493
516
{ SCARLETT2_PORT_TYPE_NONE , 0 , 8 },
494
517
{ 0 , 0 , 0 },
495
518
} },
519
+
520
+ .meter_map = {
521
+ { 24 , 6 },
522
+ { 0 , 24 },
523
+ { 0 , 0 },
524
+ }
496
525
};
497
526
498
527
static const struct scarlett2_device_info s18i8_gen2_info = {
@@ -540,6 +569,12 @@ static const struct scarlett2_device_info s18i8_gen2_info = {
540
569
{ SCARLETT2_PORT_TYPE_NONE , 0 , 4 },
541
570
{ 0 , 0 , 0 },
542
571
} },
572
+
573
+ .meter_map = {
574
+ { 26 , 18 },
575
+ { 0 , 26 },
576
+ { 0 , 0 },
577
+ }
543
578
};
544
579
545
580
static const struct scarlett2_device_info s18i20_gen2_info = {
@@ -592,6 +627,12 @@ static const struct scarlett2_device_info s18i20_gen2_info = {
592
627
{ SCARLETT2_PORT_TYPE_NONE , 0 , 6 },
593
628
{ 0 , 0 , 0 },
594
629
} },
630
+
631
+ .meter_map = {
632
+ { 38 , 18 },
633
+ { 0 , 38 },
634
+ { 0 , 0 },
635
+ }
595
636
};
596
637
597
638
static const struct scarlett2_device_info solo_gen3_info = {
@@ -657,6 +698,12 @@ static const struct scarlett2_device_info s4i4_gen3_info = {
657
698
{ SCARLETT2_PORT_TYPE_NONE , 0 , 16 },
658
699
{ 0 , 0 , 0 },
659
700
} },
701
+
702
+ .meter_map = {
703
+ { 12 , 6 },
704
+ { 0 , 12 },
705
+ { 0 , 0 },
706
+ }
660
707
};
661
708
662
709
static const struct scarlett2_device_info s8i6_gen3_info = {
@@ -708,6 +755,14 @@ static const struct scarlett2_device_info s8i6_gen3_info = {
708
755
{ SCARLETT2_PORT_TYPE_NONE , 0 , 18 },
709
756
{ 0 , 0 , 0 },
710
757
} },
758
+
759
+ .meter_map = {
760
+ { 14 , 8 },
761
+ { 0 , 6 },
762
+ { 22 , 2 },
763
+ { 6 , 8 },
764
+ { 0 , 0 },
765
+ }
711
766
};
712
767
713
768
static const struct scarlett2_device_info s18i8_gen3_info = {
@@ -723,6 +778,7 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
723
778
724
779
.line_out_remap_enable = 1 ,
725
780
.line_out_remap = { 0 , 1 , 6 , 7 , 2 , 3 , 4 , 5 },
781
+ .line_out_unmap = { 0 , 1 , 4 , 5 , 6 , 7 , 2 , 3 },
726
782
727
783
.line_out_descrs = {
728
784
"Monitor L" ,
@@ -776,6 +832,18 @@ static const struct scarlett2_device_info s18i8_gen3_info = {
776
832
{ SCARLETT2_PORT_TYPE_NONE , 0 , 10 },
777
833
{ 0 , 0 , 0 },
778
834
} },
835
+
836
+ .meter_map = {
837
+ { 30 , 10 },
838
+ { 42 , 8 },
839
+ { 0 , 2 },
840
+ { 6 , 2 },
841
+ { 2 , 4 },
842
+ { 8 , 2 },
843
+ { 40 , 2 },
844
+ { 10 , 20 },
845
+ { 0 , 0 }
846
+ }
779
847
};
780
848
781
849
static const struct scarlett2_device_info s18i20_gen3_info = {
@@ -839,6 +907,15 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
839
907
{ SCARLETT2_PORT_TYPE_NONE , 0 , 24 },
840
908
{ 0 , 0 , 0 },
841
909
} },
910
+
911
+ .meter_map = {
912
+ { 45 , 8 },
913
+ { 55 , 10 },
914
+ { 0 , 20 },
915
+ { 53 , 2 },
916
+ { 20 , 25 },
917
+ { 0 , 0 },
918
+ }
842
919
};
843
920
844
921
static const struct scarlett2_device_info clarett_2pre_info = {
@@ -881,6 +958,12 @@ static const struct scarlett2_device_info clarett_2pre_info = {
881
958
{ SCARLETT2_PORT_TYPE_NONE , 0 , 26 },
882
959
{ 0 , 0 , 0 },
883
960
} },
961
+
962
+ .meter_map = {
963
+ { 22 , 12 },
964
+ { 0 , 22 },
965
+ { 0 , 0 }
966
+ }
884
967
};
885
968
886
969
static const struct scarlett2_device_info clarett_4pre_info = {
@@ -928,6 +1011,12 @@ static const struct scarlett2_device_info clarett_4pre_info = {
928
1011
{ SCARLETT2_PORT_TYPE_NONE , 0 , 24 },
929
1012
{ 0 , 0 , 0 },
930
1013
} },
1014
+
1015
+ .meter_map = {
1016
+ { 26 , 18 },
1017
+ { 0 , 26 },
1018
+ { 0 , 0 }
1019
+ }
931
1020
};
932
1021
933
1022
static const struct scarlett2_device_info clarett_8pre_info = {
@@ -981,6 +1070,12 @@ static const struct scarlett2_device_info clarett_8pre_info = {
981
1070
{ SCARLETT2_PORT_TYPE_NONE , 0 , 22 },
982
1071
{ 0 , 0 , 0 },
983
1072
} },
1073
+
1074
+ .meter_map = {
1075
+ { 38 , 18 },
1076
+ { 0 , 38 },
1077
+ { 0 , 0 }
1078
+ }
984
1079
};
985
1080
986
1081
struct scarlett2_device_entry {
@@ -1688,6 +1783,79 @@ static void scarlett2_usb_populate_mux(struct scarlett2_data *private,
1688
1783
private -> mux [dst_idx ] = src_idx ;
1689
1784
}
1690
1785
1786
+ /* Update the meter level map
1787
+ *
1788
+ * The meter level data from the interface (SCARLETT2_USB_GET_METER
1789
+ * request) is returned in mux_assignment order, but to avoid exposing
1790
+ * that to userspace, scarlett2_meter_ctl_get() rearranges the data
1791
+ * into scarlett2_ports order using the meter_level_map[] array which
1792
+ * is set up by this function.
1793
+ *
1794
+ * In addition, the meter level data values returned from the
1795
+ * interface are invalid for destinations where:
1796
+ *
1797
+ * - the source is "Off"; therefore we set those values to zero (map
1798
+ * value of 255)
1799
+ *
1800
+ * - the source is assigned to a previous (with respect to the
1801
+ * mux_assignment order) destination; therefore we set those values
1802
+ * to the value previously reported for that source
1803
+ */
1804
+ static void scarlett2_update_meter_level_map (struct scarlett2_data * private )
1805
+ {
1806
+ const struct scarlett2_device_info * info = private -> info ;
1807
+ const int (* port_count )[SCARLETT2_PORT_DIRNS ] = info -> port_count ;
1808
+ int line_out_count =
1809
+ port_count [SCARLETT2_PORT_TYPE_ANALOGUE ][SCARLETT2_PORT_OUT ];
1810
+ const struct scarlett2_meter_entry * entry ;
1811
+
1812
+ /* sources already assigned to a destination
1813
+ * value is 255 for None, otherwise the value of i
1814
+ * (index into array returned by
1815
+ * scarlett2_usb_get_meter_levels())
1816
+ */
1817
+ u8 seen_src [SCARLETT2_MAX_SRCS ] = { 1 };
1818
+ u8 seen_src_value [SCARLETT2_MAX_SRCS ] = { 255 };
1819
+
1820
+ /* index in meter_map[] order */
1821
+ int i = 0 ;
1822
+
1823
+ /* go through the meter_map[] entries */
1824
+ for (entry = info -> meter_map ;
1825
+ entry -> count ;
1826
+ entry ++ ) {
1827
+
1828
+ /* fill in each meter_level_map[] entry */
1829
+ int j , mux_idx ;
1830
+
1831
+ for (j = 0 , mux_idx = entry -> start ;
1832
+ j < entry -> count ;
1833
+ i ++ , j ++ , mux_idx ++ ) {
1834
+
1835
+ /* convert mux_idx using line_out_unmap[] */
1836
+ int map_mux_idx = (
1837
+ info -> line_out_remap_enable &&
1838
+ mux_idx < line_out_count
1839
+ ) ? info -> line_out_unmap [mux_idx ]
1840
+ : mux_idx ;
1841
+
1842
+ /* check which source is connected, and if
1843
+ * that source is already connected elsewhere,
1844
+ * use that existing connection's destination
1845
+ * for this meter entry instead
1846
+ */
1847
+ int mux_src = private -> mux [mux_idx ];
1848
+
1849
+ if (!seen_src [mux_src ]) {
1850
+ seen_src [mux_src ] = 1 ;
1851
+ seen_src_value [mux_src ] = i ;
1852
+ }
1853
+ private -> meter_level_map [map_mux_idx ] =
1854
+ seen_src_value [mux_src ];
1855
+ }
1856
+ }
1857
+ }
1858
+
1691
1859
/* Send USB message to get mux inputs and then populate private->mux[] */
1692
1860
static int scarlett2_usb_get_mux (struct usb_mixer_interface * mixer )
1693
1861
{
@@ -1716,6 +1884,8 @@ static int scarlett2_usb_get_mux(struct usb_mixer_interface *mixer)
1716
1884
for (i = 0 ; i < count ; i ++ )
1717
1885
scarlett2_usb_populate_mux (private , le32_to_cpu (data [i ]));
1718
1886
1887
+ scarlett2_update_meter_level_map (private );
1888
+
1719
1889
return 0 ;
1720
1890
}
1721
1891
@@ -1782,6 +1952,8 @@ static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
1782
1952
return err ;
1783
1953
}
1784
1954
1955
+ scarlett2_update_meter_level_map (private );
1956
+
1785
1957
return 0 ;
1786
1958
}
1787
1959
@@ -3619,6 +3791,8 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl,
3619
3791
struct snd_ctl_elem_value * ucontrol )
3620
3792
{
3621
3793
struct usb_mixer_elem_info * elem = kctl -> private_data ;
3794
+ struct scarlett2_data * private = elem -> head .mixer -> private_data ;
3795
+ u8 * meter_level_map = private -> meter_level_map ;
3622
3796
u16 meter_levels [SCARLETT2_MAX_METERS ];
3623
3797
int i , err ;
3624
3798
@@ -3627,8 +3801,18 @@ static int scarlett2_meter_ctl_get(struct snd_kcontrol *kctl,
3627
3801
if (err < 0 )
3628
3802
return err ;
3629
3803
3630
- for (i = 0 ; i < elem -> channels ; i ++ )
3631
- ucontrol -> value .integer .value [i ] = meter_levels [i ];
3804
+ /* copy & translate from meter_levels[] using meter_level_map[] */
3805
+ for (i = 0 ; i < elem -> channels ; i ++ ) {
3806
+ int idx = meter_level_map [i ];
3807
+ int value ;
3808
+
3809
+ if (idx == 255 )
3810
+ value = 0 ;
3811
+ else
3812
+ value = meter_levels [idx ];
3813
+
3814
+ ucontrol -> value .integer .value [i ] = value ;
3815
+ }
3632
3816
3633
3817
return 0 ;
3634
3818
}
0 commit comments