@@ -151,16 +151,42 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i
151
151
return ret ;
152
152
}
153
153
154
+ /*
155
+ * Assume the clock is valid if clock source supports only one single sample
156
+ * rate, the terminal is connected directly to it (there is no clock selector)
157
+ * and clock type is internal. This is to deal with some Denon DJ controllers
158
+ * that always reports that clock is invalid.
159
+ */
160
+ static bool uac_clock_source_is_valid_quirk (struct snd_usb_audio * chip ,
161
+ struct audioformat * fmt ,
162
+ int source_id )
163
+ {
164
+ if (fmt -> protocol == UAC_VERSION_2 ) {
165
+ struct uac_clock_source_descriptor * cs_desc =
166
+ snd_usb_find_clock_source (chip -> ctrl_intf , source_id );
167
+
168
+ if (!cs_desc )
169
+ return false;
170
+
171
+ return (fmt -> nr_rates == 1 &&
172
+ (fmt -> clock & 0xff ) == cs_desc -> bClockID &&
173
+ (cs_desc -> bmAttributes & 0x3 ) !=
174
+ UAC_CLOCK_SOURCE_TYPE_EXT );
175
+ }
176
+
177
+ return false;
178
+ }
179
+
154
180
static bool uac_clock_source_is_valid (struct snd_usb_audio * chip ,
155
- int protocol ,
181
+ struct audioformat * fmt ,
156
182
int source_id )
157
183
{
158
184
int err ;
159
185
unsigned char data ;
160
186
struct usb_device * dev = chip -> dev ;
161
187
u32 bmControls ;
162
188
163
- if (protocol == UAC_VERSION_3 ) {
189
+ if (fmt -> protocol == UAC_VERSION_3 ) {
164
190
struct uac3_clock_source_descriptor * cs_desc =
165
191
snd_usb_find_clock_source_v3 (chip -> ctrl_intf , source_id );
166
192
@@ -194,10 +220,14 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
194
220
return false;
195
221
}
196
222
197
- return data ? true : false;
223
+ if (data )
224
+ return true;
225
+ else
226
+ return uac_clock_source_is_valid_quirk (chip , fmt , source_id );
198
227
}
199
228
200
- static int __uac_clock_find_source (struct snd_usb_audio * chip , int entity_id ,
229
+ static int __uac_clock_find_source (struct snd_usb_audio * chip ,
230
+ struct audioformat * fmt , int entity_id ,
201
231
unsigned long * visited , bool validate )
202
232
{
203
233
struct uac_clock_source_descriptor * source ;
@@ -217,7 +247,7 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
217
247
source = snd_usb_find_clock_source (chip -> ctrl_intf , entity_id );
218
248
if (source ) {
219
249
entity_id = source -> bClockID ;
220
- if (validate && !uac_clock_source_is_valid (chip , UAC_VERSION_2 ,
250
+ if (validate && !uac_clock_source_is_valid (chip , fmt ,
221
251
entity_id )) {
222
252
usb_audio_err (chip ,
223
253
"clock source %d is not valid, cannot use\n" ,
@@ -248,8 +278,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
248
278
}
249
279
250
280
cur = ret ;
251
- ret = __uac_clock_find_source (chip , selector -> baCSourceID [ret - 1 ],
252
- visited , validate );
281
+ ret = __uac_clock_find_source (chip , fmt ,
282
+ selector -> baCSourceID [ret - 1 ],
283
+ visited , validate );
253
284
if (!validate || ret > 0 || !chip -> autoclock )
254
285
return ret ;
255
286
@@ -260,8 +291,9 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
260
291
if (i == cur )
261
292
continue ;
262
293
263
- ret = __uac_clock_find_source (chip , selector -> baCSourceID [i - 1 ],
264
- visited , true);
294
+ ret = __uac_clock_find_source (chip , fmt ,
295
+ selector -> baCSourceID [i - 1 ],
296
+ visited , true);
265
297
if (ret < 0 )
266
298
continue ;
267
299
@@ -281,14 +313,16 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
281
313
/* FIXME: multipliers only act as pass-thru element for now */
282
314
multiplier = snd_usb_find_clock_multiplier (chip -> ctrl_intf , entity_id );
283
315
if (multiplier )
284
- return __uac_clock_find_source (chip , multiplier -> bCSourceID ,
285
- visited , validate );
316
+ return __uac_clock_find_source (chip , fmt ,
317
+ multiplier -> bCSourceID ,
318
+ visited , validate );
286
319
287
320
return - EINVAL ;
288
321
}
289
322
290
- static int __uac3_clock_find_source (struct snd_usb_audio * chip , int entity_id ,
291
- unsigned long * visited , bool validate )
323
+ static int __uac3_clock_find_source (struct snd_usb_audio * chip ,
324
+ struct audioformat * fmt , int entity_id ,
325
+ unsigned long * visited , bool validate )
292
326
{
293
327
struct uac3_clock_source_descriptor * source ;
294
328
struct uac3_clock_selector_descriptor * selector ;
@@ -307,7 +341,7 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
307
341
source = snd_usb_find_clock_source_v3 (chip -> ctrl_intf , entity_id );
308
342
if (source ) {
309
343
entity_id = source -> bClockID ;
310
- if (validate && !uac_clock_source_is_valid (chip , UAC_VERSION_3 ,
344
+ if (validate && !uac_clock_source_is_valid (chip , fmt ,
311
345
entity_id )) {
312
346
usb_audio_err (chip ,
313
347
"clock source %d is not valid, cannot use\n" ,
@@ -338,7 +372,8 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
338
372
}
339
373
340
374
cur = ret ;
341
- ret = __uac3_clock_find_source (chip , selector -> baCSourceID [ret - 1 ],
375
+ ret = __uac3_clock_find_source (chip , fmt ,
376
+ selector -> baCSourceID [ret - 1 ],
342
377
visited , validate );
343
378
if (!validate || ret > 0 || !chip -> autoclock )
344
379
return ret ;
@@ -350,8 +385,9 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
350
385
if (i == cur )
351
386
continue ;
352
387
353
- ret = __uac3_clock_find_source (chip , selector -> baCSourceID [i - 1 ],
354
- visited , true);
388
+ ret = __uac3_clock_find_source (chip , fmt ,
389
+ selector -> baCSourceID [i - 1 ],
390
+ visited , true);
355
391
if (ret < 0 )
356
392
continue ;
357
393
@@ -372,7 +408,8 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
372
408
multiplier = snd_usb_find_clock_multiplier_v3 (chip -> ctrl_intf ,
373
409
entity_id );
374
410
if (multiplier )
375
- return __uac3_clock_find_source (chip , multiplier -> bCSourceID ,
411
+ return __uac3_clock_find_source (chip , fmt ,
412
+ multiplier -> bCSourceID ,
376
413
visited , validate );
377
414
378
415
return - EINVAL ;
@@ -389,18 +426,18 @@ static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
389
426
*
390
427
* Returns the clock source UnitID (>=0) on success, or an error.
391
428
*/
392
- int snd_usb_clock_find_source (struct snd_usb_audio * chip , int protocol ,
393
- int entity_id , bool validate )
429
+ int snd_usb_clock_find_source (struct snd_usb_audio * chip ,
430
+ struct audioformat * fmt , bool validate )
394
431
{
395
432
DECLARE_BITMAP (visited , 256 );
396
433
memset (visited , 0 , sizeof (visited ));
397
434
398
- switch (protocol ) {
435
+ switch (fmt -> protocol ) {
399
436
case UAC_VERSION_2 :
400
- return __uac_clock_find_source (chip , entity_id , visited ,
437
+ return __uac_clock_find_source (chip , fmt , fmt -> clock , visited ,
401
438
validate );
402
439
case UAC_VERSION_3 :
403
- return __uac3_clock_find_source (chip , entity_id , visited ,
440
+ return __uac3_clock_find_source (chip , fmt , fmt -> clock , visited ,
404
441
validate );
405
442
default :
406
443
return - EINVAL ;
@@ -501,17 +538,15 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
501
538
* automatic clock selection if the current clock is not
502
539
* valid.
503
540
*/
504
- clock = snd_usb_clock_find_source (chip , fmt -> protocol ,
505
- fmt -> clock , true);
541
+ clock = snd_usb_clock_find_source (chip , fmt , true);
506
542
if (clock < 0 ) {
507
543
/* We did not find a valid clock, but that might be
508
544
* because the current sample rate does not match an
509
545
* external clock source. Try again without validation
510
546
* and we will do another validation after setting the
511
547
* rate.
512
548
*/
513
- clock = snd_usb_clock_find_source (chip , fmt -> protocol ,
514
- fmt -> clock , false);
549
+ clock = snd_usb_clock_find_source (chip , fmt , false);
515
550
if (clock < 0 )
516
551
return clock ;
517
552
}
@@ -577,7 +612,7 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
577
612
578
613
validation :
579
614
/* validate clock after rate change */
580
- if (!uac_clock_source_is_valid (chip , fmt -> protocol , clock ))
615
+ if (!uac_clock_source_is_valid (chip , fmt , clock ))
581
616
return - ENXIO ;
582
617
return 0 ;
583
618
}
0 commit comments