23
23
24
24
#include <sound/core.h>
25
25
#include <sound/pcm.h>
26
+ #include <sound/control.h>
27
+ #include <sound/tlv.h>
26
28
27
29
#include "usbaudio.h"
28
30
#include "card.h"
@@ -47,6 +49,7 @@ static void free_substream(struct snd_usb_substream *subs)
47
49
list_for_each_safe (p , n , & subs -> fmt_list ) {
48
50
struct audioformat * fp = list_entry (p , struct audioformat , list );
49
51
kfree (fp -> rate_table );
52
+ kfree (fp -> chmap );
50
53
kfree (fp );
51
54
}
52
55
kfree (subs -> rate_list .list );
@@ -99,6 +102,206 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
99
102
subs -> num_formats ++ ;
100
103
subs -> fmt_type = fp -> fmt_type ;
101
104
subs -> ep_num = fp -> endpoint ;
105
+ if (fp -> channels > subs -> channels_max )
106
+ subs -> channels_max = fp -> channels ;
107
+ }
108
+
109
+ /* kctl callbacks for usb-audio channel maps */
110
+ static int usb_chmap_ctl_info (struct snd_kcontrol * kcontrol ,
111
+ struct snd_ctl_elem_info * uinfo )
112
+ {
113
+ struct snd_pcm_chmap * info = snd_kcontrol_chip (kcontrol );
114
+ struct snd_usb_substream * subs = info -> private_data ;
115
+
116
+ uinfo -> type = SNDRV_CTL_ELEM_TYPE_INTEGER ;
117
+ uinfo -> count = subs -> channels_max ;
118
+ uinfo -> value .integer .min = 0 ;
119
+ uinfo -> value .integer .max = SNDRV_CHMAP_LAST ;
120
+ return 0 ;
121
+ }
122
+
123
+ /* check whether a duplicated entry exists in the audiofmt list */
124
+ static bool have_dup_chmap (struct snd_usb_substream * subs ,
125
+ struct audioformat * fp )
126
+ {
127
+ struct list_head * p ;
128
+
129
+ for (p = fp -> list .prev ; p != & subs -> fmt_list ; p = p -> prev ) {
130
+ struct audioformat * prev ;
131
+ prev = list_entry (p , struct audioformat , list );
132
+ if (prev -> chmap &&
133
+ !memcmp (prev -> chmap , fp -> chmap , sizeof (* fp -> chmap )))
134
+ return true;
135
+ }
136
+ return false;
137
+ }
138
+
139
+ static int usb_chmap_ctl_tlv (struct snd_kcontrol * kcontrol , int op_flag ,
140
+ unsigned int size , unsigned int __user * tlv )
141
+ {
142
+ struct snd_pcm_chmap * info = snd_kcontrol_chip (kcontrol );
143
+ struct snd_usb_substream * subs = info -> private_data ;
144
+ struct audioformat * fp ;
145
+ unsigned int __user * dst ;
146
+ int count = 0 ;
147
+
148
+ if (size < 8 )
149
+ return - ENOMEM ;
150
+ if (put_user (SNDRV_CTL_TLVT_CONTAINER , tlv ))
151
+ return - EFAULT ;
152
+ size -= 8 ;
153
+ dst = tlv + 2 ;
154
+ list_for_each_entry (fp , & subs -> fmt_list , list ) {
155
+ int i , ch_bytes ;
156
+
157
+ if (!fp -> chmap )
158
+ continue ;
159
+ if (have_dup_chmap (subs , fp ))
160
+ continue ;
161
+ /* copy the entry */
162
+ ch_bytes = fp -> chmap -> channels * 4 ;
163
+ if (size < 8 + ch_bytes )
164
+ return - ENOMEM ;
165
+ if (put_user (SNDRV_CTL_TLVT_CHMAP_FIXED , dst ) ||
166
+ put_user (ch_bytes , dst + 1 ))
167
+ return - EFAULT ;
168
+ dst += 2 ;
169
+ for (i = 0 ; i < fp -> chmap -> channels ; i ++ , dst ++ ) {
170
+ if (put_user (fp -> chmap -> map [i ], dst ))
171
+ return - EFAULT ;
172
+ }
173
+
174
+ count += 8 + ch_bytes ;
175
+ size -= 8 + ch_bytes ;
176
+ }
177
+ if (put_user (count , tlv + 1 ))
178
+ return - EFAULT ;
179
+ return 0 ;
180
+ }
181
+
182
+ static int usb_chmap_ctl_get (struct snd_kcontrol * kcontrol ,
183
+ struct snd_ctl_elem_value * ucontrol )
184
+ {
185
+ struct snd_pcm_chmap * info = snd_kcontrol_chip (kcontrol );
186
+ struct snd_usb_substream * subs = info -> private_data ;
187
+ struct snd_pcm_chmap_elem * chmap = NULL ;
188
+ int i ;
189
+
190
+ memset (ucontrol -> value .integer .value , 0 ,
191
+ sizeof (ucontrol -> value .integer .value ));
192
+ if (subs -> cur_audiofmt )
193
+ chmap = subs -> cur_audiofmt -> chmap ;
194
+ if (chmap ) {
195
+ for (i = 0 ; i < chmap -> channels ; i ++ )
196
+ ucontrol -> value .integer .value [i ] = chmap -> map [i ];
197
+ }
198
+ return 0 ;
199
+ }
200
+
201
+ /* create a chmap kctl assigned to the given USB substream */
202
+ static int add_chmap (struct snd_pcm * pcm , int stream ,
203
+ struct snd_usb_substream * subs )
204
+ {
205
+ struct audioformat * fp ;
206
+ struct snd_pcm_chmap * chmap ;
207
+ struct snd_kcontrol * kctl ;
208
+ int err ;
209
+
210
+ list_for_each_entry (fp , & subs -> fmt_list , list )
211
+ if (fp -> chmap )
212
+ goto ok ;
213
+ /* no chmap is found */
214
+ return 0 ;
215
+
216
+ ok :
217
+ err = snd_pcm_add_chmap_ctls (pcm , stream , NULL , 0 , 0 , & chmap );
218
+ if (err < 0 )
219
+ return err ;
220
+
221
+ /* override handlers */
222
+ chmap -> private_data = subs ;
223
+ kctl = chmap -> kctl ;
224
+ kctl -> info = usb_chmap_ctl_info ;
225
+ kctl -> get = usb_chmap_ctl_get ;
226
+ kctl -> tlv .c = usb_chmap_ctl_tlv ;
227
+
228
+ return 0 ;
229
+ }
230
+
231
+ /* convert from USB ChannelConfig bits to ALSA chmap element */
232
+ static struct snd_pcm_chmap_elem * convert_chmap (int channels , unsigned int bits ,
233
+ int protocol )
234
+ {
235
+ static unsigned int uac1_maps [] = {
236
+ SNDRV_CHMAP_FL , /* left front */
237
+ SNDRV_CHMAP_FR , /* right front */
238
+ SNDRV_CHMAP_FC , /* center front */
239
+ SNDRV_CHMAP_LFE , /* LFE */
240
+ SNDRV_CHMAP_SL , /* left surround */
241
+ SNDRV_CHMAP_SR , /* right surround */
242
+ SNDRV_CHMAP_FLC , /* left of center */
243
+ SNDRV_CHMAP_FRC , /* right of center */
244
+ SNDRV_CHMAP_RC , /* surround */
245
+ SNDRV_CHMAP_SL , /* side left */
246
+ SNDRV_CHMAP_SR , /* side right */
247
+ SNDRV_CHMAP_TC , /* top */
248
+ 0 /* terminator */
249
+ };
250
+ static unsigned int uac2_maps [] = {
251
+ SNDRV_CHMAP_FL , /* front left */
252
+ SNDRV_CHMAP_FR , /* front right */
253
+ SNDRV_CHMAP_FC , /* front center */
254
+ SNDRV_CHMAP_LFE , /* LFE */
255
+ SNDRV_CHMAP_RL , /* back left */
256
+ SNDRV_CHMAP_RR , /* back right */
257
+ SNDRV_CHMAP_FLC , /* front left of center */
258
+ SNDRV_CHMAP_FRC , /* front right of center */
259
+ SNDRV_CHMAP_RC , /* back center */
260
+ SNDRV_CHMAP_SL , /* side left */
261
+ SNDRV_CHMAP_SR , /* side right */
262
+ SNDRV_CHMAP_TC , /* top center */
263
+ SNDRV_CHMAP_TFL , /* top front left */
264
+ SNDRV_CHMAP_TFC , /* top front center */
265
+ SNDRV_CHMAP_TFR , /* top front right */
266
+ SNDRV_CHMAP_TRL , /* top back left */
267
+ SNDRV_CHMAP_TRC , /* top back center */
268
+ SNDRV_CHMAP_TRR , /* top back right */
269
+ SNDRV_CHMAP_TFLC , /* top front left of center */
270
+ SNDRV_CHMAP_TFRC , /* top front right of center */
271
+ SNDRV_CHMAP_LLFE , /* left LFE */
272
+ SNDRV_CHMAP_RLFE , /* right LFE */
273
+ SNDRV_CHMAP_TSL , /* top side left */
274
+ SNDRV_CHMAP_TSR , /* top side right */
275
+ SNDRV_CHMAP_BC , /* bottom center */
276
+ SNDRV_CHMAP_BLC , /* bottom left center */
277
+ SNDRV_CHMAP_BRC , /* bottom right center */
278
+ 0 /* terminator */
279
+ };
280
+ struct snd_pcm_chmap_elem * chmap ;
281
+ const unsigned int * maps ;
282
+ int c ;
283
+
284
+ if (!bits )
285
+ return NULL ;
286
+ if (channels > ARRAY_SIZE (chmap -> map ))
287
+ return NULL ;
288
+
289
+ chmap = kzalloc (sizeof (* chmap ), GFP_KERNEL );
290
+ if (!chmap )
291
+ return NULL ;
292
+
293
+ maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps ;
294
+ chmap -> channels = channels ;
295
+ c = 0 ;
296
+ for (; bits && * maps ; maps ++ , bits >>= 1 ) {
297
+ if (bits & 1 )
298
+ chmap -> map [c ++ ] = * maps ;
299
+ }
300
+
301
+ for (; c < channels ; c ++ )
302
+ chmap -> map [c ] = SNDRV_CHMAP_UNKNOWN ;
303
+
304
+ return chmap ;
102
305
}
103
306
104
307
/*
@@ -140,7 +343,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
140
343
if (err < 0 )
141
344
return err ;
142
345
snd_usb_init_substream (as , stream , fp );
143
- return 0 ;
346
+ return add_chmap ( as -> pcm , stream , subs ) ;
144
347
}
145
348
146
349
/* create a new pcm */
@@ -174,7 +377,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
174
377
175
378
snd_usb_proc_pcm_format_add (as );
176
379
177
- return 0 ;
380
+ return add_chmap ( pcm , stream , & as -> substream [ stream ]) ;
178
381
}
179
382
180
383
static int parse_uac_endpoint_attributes (struct snd_usb_audio * chip ,
@@ -218,8 +421,11 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
218
421
return attributes ;
219
422
}
220
423
221
- static struct uac2_input_terminal_descriptor *
222
- snd_usb_find_input_terminal_descriptor (struct usb_host_interface * ctrl_iface ,
424
+ /* find an input terminal descriptor (either UAC1 or UAC2) with the given
425
+ * terminal id
426
+ */
427
+ static void *
428
+ snd_usb_find_input_terminal_descriptor (struct usb_host_interface * ctrl_iface ,
223
429
int terminal_id )
224
430
{
225
431
struct uac2_input_terminal_descriptor * term = NULL ;
@@ -261,6 +467,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
261
467
struct audioformat * fp = NULL ;
262
468
int num , protocol , clock = 0 ;
263
469
struct uac_format_type_i_continuous_descriptor * fmt ;
470
+ unsigned int chconfig ;
264
471
265
472
dev = chip -> dev ;
266
473
@@ -300,6 +507,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
300
507
if (snd_usb_apply_interface_quirk (chip , iface_no , altno ))
301
508
continue ;
302
509
510
+ chconfig = 0 ;
303
511
/* get audio formats */
304
512
switch (protocol ) {
305
513
default :
@@ -311,6 +519,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
311
519
case UAC_VERSION_1 : {
312
520
struct uac1_as_header_descriptor * as =
313
521
snd_usb_find_csint_desc (alts -> extra , alts -> extralen , NULL , UAC_AS_GENERAL );
522
+ struct uac_input_terminal_descriptor * iterm ;
314
523
315
524
if (!as ) {
316
525
snd_printk (KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n" ,
@@ -325,6 +534,14 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
325
534
}
326
535
327
536
format = le16_to_cpu (as -> wFormatTag ); /* remember the format value */
537
+
538
+ iterm = snd_usb_find_input_terminal_descriptor (chip -> ctrl_intf ,
539
+ as -> bTerminalLink );
540
+ if (iterm ) {
541
+ num_channels = iterm -> bNrChannels ;
542
+ chconfig = le16_to_cpu (iterm -> wChannelConfig );
543
+ }
544
+
328
545
break ;
329
546
}
330
547
@@ -355,6 +572,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
355
572
as -> bTerminalLink );
356
573
if (input_term ) {
357
574
clock = input_term -> bCSourceID ;
575
+ chconfig = le32_to_cpu (input_term -> bmChannelConfig );
358
576
break ;
359
577
}
360
578
@@ -413,13 +631,13 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
413
631
fp -> ep_attr = get_endpoint (alts , 0 )-> bmAttributes ;
414
632
fp -> datainterval = snd_usb_parse_datainterval (chip , alts );
415
633
fp -> maxpacksize = le16_to_cpu (get_endpoint (alts , 0 )-> wMaxPacketSize );
416
- /* num_channels is only set for v2 interfaces */
417
634
fp -> channels = num_channels ;
418
635
if (snd_usb_get_speed (dev ) == USB_SPEED_HIGH )
419
636
fp -> maxpacksize = (((fp -> maxpacksize >> 11 ) & 3 ) + 1 )
420
637
* (fp -> maxpacksize & 0x7ff );
421
638
fp -> attributes = parse_uac_endpoint_attributes (chip , alts , protocol , iface_no );
422
639
fp -> clock = clock ;
640
+ fp -> chmap = convert_chmap (num_channels , chconfig , protocol );
423
641
424
642
/* some quirks for attributes here */
425
643
@@ -455,6 +673,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
455
673
/* ok, let's parse further... */
456
674
if (snd_usb_parse_audio_format (chip , fp , format , fmt , stream , alts ) < 0 ) {
457
675
kfree (fp -> rate_table );
676
+ kfree (fp -> chmap );
458
677
kfree (fp );
459
678
fp = NULL ;
460
679
continue ;
@@ -464,6 +683,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
464
683
err = snd_usb_add_audio_stream (chip , stream , fp );
465
684
if (err < 0 ) {
466
685
kfree (fp -> rate_table );
686
+ kfree (fp -> chmap );
467
687
kfree (fp );
468
688
return err ;
469
689
}
0 commit comments