@@ -1079,6 +1079,9 @@ struct scarlett2_device_info {
1079
1079
/* minimum firmware version required */
1080
1080
u16 min_firmware_version ;
1081
1081
1082
+ /* has a downloadable device map */
1083
+ u8 has_devmap ;
1084
+
1082
1085
/* support for main/alt speaker switching */
1083
1086
u8 has_speaker_switching ;
1084
1087
@@ -1773,6 +1776,7 @@ static const struct scarlett2_device_info s18i20_gen3_info = {
1773
1776
static const struct scarlett2_device_info vocaster_one_info = {
1774
1777
.config_set = & scarlett2_config_set_vocaster ,
1775
1778
.min_firmware_version = 1769 ,
1779
+ .has_devmap = 1 ,
1776
1780
1777
1781
.phantom_count = 1 ,
1778
1782
.inputs_per_phantom = 1 ,
@@ -1815,6 +1819,7 @@ static const struct scarlett2_device_info vocaster_one_info = {
1815
1819
static const struct scarlett2_device_info vocaster_two_info = {
1816
1820
.config_set = & scarlett2_config_set_vocaster ,
1817
1821
.min_firmware_version = 1769 ,
1822
+ .has_devmap = 1 ,
1818
1823
1819
1824
.phantom_count = 2 ,
1820
1825
.inputs_per_phantom = 1 ,
@@ -1858,6 +1863,7 @@ static const struct scarlett2_device_info vocaster_two_info = {
1858
1863
static const struct scarlett2_device_info solo_gen4_info = {
1859
1864
.config_set = & scarlett2_config_set_gen4_solo ,
1860
1865
.min_firmware_version = 2115 ,
1866
+ .has_devmap = 1 ,
1861
1867
1862
1868
.level_input_count = 1 ,
1863
1869
.air_input_count = 1 ,
@@ -1912,6 +1918,7 @@ static const struct scarlett2_device_info solo_gen4_info = {
1912
1918
static const struct scarlett2_device_info s2i2_gen4_info = {
1913
1919
.config_set = & scarlett2_config_set_gen4_2i2 ,
1914
1920
.min_firmware_version = 2115 ,
1921
+ .has_devmap = 1 ,
1915
1922
1916
1923
.level_input_count = 2 ,
1917
1924
.air_input_count = 2 ,
@@ -1966,6 +1973,7 @@ static const struct scarlett2_device_info s2i2_gen4_info = {
1966
1973
static const struct scarlett2_device_info s4i4_gen4_info = {
1967
1974
.config_set = & scarlett2_config_set_gen4_4i4 ,
1968
1975
.min_firmware_version = 2089 ,
1976
+ .has_devmap = 1 ,
1969
1977
1970
1978
.level_input_count = 2 ,
1971
1979
.air_input_count = 2 ,
@@ -2264,6 +2272,8 @@ static int scarlett2_get_port_start_num(
2264
2272
#define SCARLETT2_USB_GET_DATA 0x00800000
2265
2273
#define SCARLETT2_USB_SET_DATA 0x00800001
2266
2274
#define SCARLETT2_USB_DATA_CMD 0x00800002
2275
+ #define SCARLETT2_USB_INFO_DEVMAP 0x0080000c
2276
+ #define SCARLETT2_USB_GET_DEVMAP 0x0080000d
2267
2277
2268
2278
#define SCARLETT2_USB_CONFIG_SAVE 6
2269
2279
@@ -2277,6 +2287,14 @@ static int scarlett2_get_port_start_num(
2277
2287
#define SCARLETT2_SEGMENT_SETTINGS_NAME "App_Settings"
2278
2288
#define SCARLETT2_SEGMENT_FIRMWARE_NAME "App_Upgrade"
2279
2289
2290
+ /* Gen 4 device firmware provides access to a base64-encoded
2291
+ * zlib-compressed JSON description of the device's capabilities and
2292
+ * configuration. This device map is made available in
2293
+ * /proc/asound/cardX/device-map.json.zz.b64
2294
+ */
2295
+ #define SCARLETT2_DEVMAP_BLOCK_SIZE 1024
2296
+ #define SCARLETT2_DEVMAP_FILENAME "device-map.json.zz.b64"
2297
+
2280
2298
/* proprietary request/response format */
2281
2299
struct scarlett2_usb_packet {
2282
2300
__le32 cmd ;
@@ -9562,6 +9580,116 @@ static int scarlett2_hwdep_init(struct usb_mixer_interface *mixer)
9562
9580
return 0 ;
9563
9581
}
9564
9582
9583
+ /*** device-map file ***/
9584
+
9585
+ static ssize_t scarlett2_devmap_read (
9586
+ struct snd_info_entry * entry ,
9587
+ void * file_private_data ,
9588
+ struct file * file ,
9589
+ char __user * buf ,
9590
+ size_t count ,
9591
+ loff_t pos )
9592
+ {
9593
+ struct usb_mixer_interface * mixer = entry -> private_data ;
9594
+ u8 * resp_buf ;
9595
+ const size_t block_size = SCARLETT2_DEVMAP_BLOCK_SIZE ;
9596
+ size_t copied = 0 ;
9597
+
9598
+ if (pos >= entry -> size )
9599
+ return 0 ;
9600
+
9601
+ if (pos + count > entry -> size )
9602
+ count = entry -> size - pos ;
9603
+
9604
+ resp_buf = kmalloc (block_size , GFP_KERNEL );
9605
+ if (!resp_buf )
9606
+ return - ENOMEM ;
9607
+
9608
+ while (count > 0 ) {
9609
+ /* SCARLETT2_USB_GET_DEVMAP reads only on block boundaries,
9610
+ * so we need to read a whole block and copy the requested
9611
+ * chunk to userspace.
9612
+ */
9613
+
9614
+ __le32 req ;
9615
+ int err ;
9616
+
9617
+ /* offset within the block that we're reading */
9618
+ size_t offset = pos % block_size ;
9619
+
9620
+ /* read_size is block_size except for the last block */
9621
+ size_t block_start = pos - offset ;
9622
+ size_t read_size = min_t (size_t ,
9623
+ block_size ,
9624
+ entry -> size - block_start );
9625
+
9626
+ /* size of the chunk to copy to userspace */
9627
+ size_t copy_size = min_t (size_t , count , read_size - offset );
9628
+
9629
+ /* request the block */
9630
+ req = cpu_to_le32 (pos / block_size );
9631
+ err = scarlett2_usb (mixer , SCARLETT2_USB_GET_DEVMAP ,
9632
+ & req , sizeof (req ), resp_buf , read_size );
9633
+ if (err < 0 ) {
9634
+ kfree (resp_buf );
9635
+ return copied ? copied : err ;
9636
+ }
9637
+
9638
+ if (copy_to_user (buf , resp_buf + offset , copy_size )) {
9639
+ kfree (resp_buf );
9640
+ return - EFAULT ;
9641
+ }
9642
+
9643
+ buf += copy_size ;
9644
+ pos += copy_size ;
9645
+ copied += copy_size ;
9646
+ count -= copy_size ;
9647
+ }
9648
+
9649
+ kfree (resp_buf );
9650
+ return copied ;
9651
+ }
9652
+
9653
+ static const struct snd_info_entry_ops scarlett2_devmap_ops = {
9654
+ .read = scarlett2_devmap_read ,
9655
+ };
9656
+
9657
+ static int scarlett2_devmap_init (struct usb_mixer_interface * mixer )
9658
+ {
9659
+ struct snd_card * card = mixer -> chip -> card ;
9660
+ struct scarlett2_data * private = mixer -> private_data ;
9661
+ const struct scarlett2_device_info * info = private -> info ;
9662
+ __le16 config_len_buf [2 ];
9663
+ int config_len ;
9664
+ struct snd_info_entry * entry ;
9665
+ int err ;
9666
+
9667
+ /* If the device doesn't support the DEVMAP commands, don't
9668
+ * create the /proc/asound/cardX/scarlett.json.zlib entry
9669
+ */
9670
+ if (!info -> has_devmap )
9671
+ return 0 ;
9672
+
9673
+ err = scarlett2_usb (mixer , SCARLETT2_USB_INFO_DEVMAP ,
9674
+ NULL , 0 , & config_len_buf , sizeof (config_len_buf ));
9675
+ if (err < 0 )
9676
+ return err ;
9677
+
9678
+ config_len = le16_to_cpu (config_len_buf [1 ]);
9679
+
9680
+ err = snd_card_proc_new (card , SCARLETT2_DEVMAP_FILENAME , & entry );
9681
+ if (err < 0 )
9682
+ return err ;
9683
+
9684
+ entry -> content = SNDRV_INFO_CONTENT_DATA ;
9685
+ entry -> private_data = mixer ;
9686
+ entry -> c .ops = & scarlett2_devmap_ops ;
9687
+ entry -> size = config_len ;
9688
+ entry -> mode = S_IFREG | 0444 ;
9689
+
9690
+ return 0 ;
9691
+ }
9692
+
9565
9693
int snd_scarlett2_init (struct usb_mixer_interface * mixer )
9566
9694
{
9567
9695
struct snd_usb_audio * chip = mixer -> chip ;
@@ -9612,11 +9740,20 @@ int snd_scarlett2_init(struct usb_mixer_interface *mixer)
9612
9740
}
9613
9741
9614
9742
err = scarlett2_hwdep_init (mixer );
9615
- if (err < 0 )
9743
+ if (err < 0 ) {
9616
9744
usb_audio_err (mixer -> chip ,
9617
9745
"Error creating %s hwdep device: %d" ,
9618
9746
entry -> series_name ,
9619
9747
err );
9748
+ return err ;
9749
+ }
9750
+
9751
+ err = scarlett2_devmap_init (mixer );
9752
+ if (err < 0 )
9753
+ usb_audio_err (mixer -> chip ,
9754
+ "Error creating %s devmap entry: %d" ,
9755
+ entry -> series_name ,
9756
+ err );
9620
9757
9621
9758
return err ;
9622
9759
}
0 commit comments