aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/clock.c')
-rw-r--r--sound/usb/clock.c231
1 files changed, 205 insertions, 26 deletions
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index eb3396ffba4c..ab39ccb974c6 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -23,6 +23,7 @@
23#include <linux/usb.h> 23#include <linux/usb.h>
24#include <linux/usb/audio.h> 24#include <linux/usb/audio.h>
25#include <linux/usb/audio-v2.h> 25#include <linux/usb/audio-v2.h>
26#include <linux/usb/audio-v3.h>
26 27
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/info.h> 29#include <sound/info.h>
@@ -50,6 +51,22 @@ static struct uac_clock_source_descriptor *
50 return NULL; 51 return NULL;
51} 52}
52 53
54static struct uac3_clock_source_descriptor *
55 snd_usb_find_clock_source_v3(struct usb_host_interface *ctrl_iface,
56 int clock_id)
57{
58 struct uac3_clock_source_descriptor *cs = NULL;
59
60 while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
61 ctrl_iface->extralen,
62 cs, UAC3_CLOCK_SOURCE))) {
63 if (cs->bClockID == clock_id)
64 return cs;
65 }
66
67 return NULL;
68}
69
53static struct uac_clock_selector_descriptor * 70static struct uac_clock_selector_descriptor *
54 snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface, 71 snd_usb_find_clock_selector(struct usb_host_interface *ctrl_iface,
55 int clock_id) 72 int clock_id)
@@ -69,6 +86,22 @@ static struct uac_clock_selector_descriptor *
69 return NULL; 86 return NULL;
70} 87}
71 88
89static struct uac3_clock_selector_descriptor *
90 snd_usb_find_clock_selector_v3(struct usb_host_interface *ctrl_iface,
91 int clock_id)
92{
93 struct uac3_clock_selector_descriptor *cs = NULL;
94
95 while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
96 ctrl_iface->extralen,
97 cs, UAC3_CLOCK_SELECTOR))) {
98 if (cs->bClockID == clock_id)
99 return cs;
100 }
101
102 return NULL;
103}
104
72static struct uac_clock_multiplier_descriptor * 105static struct uac_clock_multiplier_descriptor *
73 snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface, 106 snd_usb_find_clock_multiplier(struct usb_host_interface *ctrl_iface,
74 int clock_id) 107 int clock_id)
@@ -85,6 +118,22 @@ static struct uac_clock_multiplier_descriptor *
85 return NULL; 118 return NULL;
86} 119}
87 120
121static struct uac3_clock_multiplier_descriptor *
122 snd_usb_find_clock_multiplier_v3(struct usb_host_interface *ctrl_iface,
123 int clock_id)
124{
125 struct uac3_clock_multiplier_descriptor *cs = NULL;
126
127 while ((cs = snd_usb_find_csint_desc(ctrl_iface->extra,
128 ctrl_iface->extralen,
129 cs, UAC3_CLOCK_MULTIPLIER))) {
130 if (cs->bClockID == clock_id)
131 return cs;
132 }
133
134 return NULL;
135}
136
88static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id) 137static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_id)
89{ 138{
90 unsigned char buf; 139 unsigned char buf;
@@ -138,20 +187,34 @@ static int uac_clock_selector_set_val(struct snd_usb_audio *chip, int selector_i
138 return ret; 187 return ret;
139} 188}
140 189
141static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) 190static bool uac_clock_source_is_valid(struct snd_usb_audio *chip,
191 int protocol,
192 int source_id)
142{ 193{
143 int err; 194 int err;
144 unsigned char data; 195 unsigned char data;
145 struct usb_device *dev = chip->dev; 196 struct usb_device *dev = chip->dev;
146 struct uac_clock_source_descriptor *cs_desc = 197 u32 bmControls;
147 snd_usb_find_clock_source(chip->ctrl_intf, source_id); 198
148 199 if (protocol == UAC_VERSION_3) {
149 if (!cs_desc) 200 struct uac3_clock_source_descriptor *cs_desc =
150 return 0; 201 snd_usb_find_clock_source_v3(chip->ctrl_intf, source_id);
202
203 if (!cs_desc)
204 return 0;
205 bmControls = le32_to_cpu(cs_desc->bmControls);
206 } else { /* UAC_VERSION_1/2 */
207 struct uac_clock_source_descriptor *cs_desc =
208 snd_usb_find_clock_source(chip->ctrl_intf, source_id);
209
210 if (!cs_desc)
211 return 0;
212 bmControls = cs_desc->bmControls;
213 }
151 214
152 /* If a clock source can't tell us whether it's valid, we assume it is */ 215 /* If a clock source can't tell us whether it's valid, we assume it is */
153 if (!uac2_control_is_readable(cs_desc->bmControls, 216 if (!uac_v2v3_control_is_readable(bmControls,
154 UAC2_CS_CONTROL_CLOCK_VALID - 1)) 217 UAC2_CS_CONTROL_CLOCK_VALID))
155 return 1; 218 return 1;
156 219
157 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, 220 err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR,
@@ -170,9 +233,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id)
170 return !!data; 233 return !!data;
171} 234}
172 235
173static int __uac_clock_find_source(struct snd_usb_audio *chip, 236static int __uac_clock_find_source(struct snd_usb_audio *chip, int entity_id,
174 int entity_id, unsigned long *visited, 237 unsigned long *visited, bool validate)
175 bool validate)
176{ 238{
177 struct uac_clock_source_descriptor *source; 239 struct uac_clock_source_descriptor *source;
178 struct uac_clock_selector_descriptor *selector; 240 struct uac_clock_selector_descriptor *selector;
@@ -191,7 +253,8 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
191 source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id); 253 source = snd_usb_find_clock_source(chip->ctrl_intf, entity_id);
192 if (source) { 254 if (source) {
193 entity_id = source->bClockID; 255 entity_id = source->bClockID;
194 if (validate && !uac_clock_source_is_valid(chip, entity_id)) { 256 if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_2,
257 entity_id)) {
195 usb_audio_err(chip, 258 usb_audio_err(chip,
196 "clock source %d is not valid, cannot use\n", 259 "clock source %d is not valid, cannot use\n",
197 entity_id); 260 entity_id);
@@ -260,6 +323,97 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
260 return -EINVAL; 323 return -EINVAL;
261} 324}
262 325
326static int __uac3_clock_find_source(struct snd_usb_audio *chip, int entity_id,
327 unsigned long *visited, bool validate)
328{
329 struct uac3_clock_source_descriptor *source;
330 struct uac3_clock_selector_descriptor *selector;
331 struct uac3_clock_multiplier_descriptor *multiplier;
332
333 entity_id &= 0xff;
334
335 if (test_and_set_bit(entity_id, visited)) {
336 usb_audio_warn(chip,
337 "%s(): recursive clock topology detected, id %d.\n",
338 __func__, entity_id);
339 return -EINVAL;
340 }
341
342 /* first, see if the ID we're looking for is a clock source already */
343 source = snd_usb_find_clock_source_v3(chip->ctrl_intf, entity_id);
344 if (source) {
345 entity_id = source->bClockID;
346 if (validate && !uac_clock_source_is_valid(chip, UAC_VERSION_3,
347 entity_id)) {
348 usb_audio_err(chip,
349 "clock source %d is not valid, cannot use\n",
350 entity_id);
351 return -ENXIO;
352 }
353 return entity_id;
354 }
355
356 selector = snd_usb_find_clock_selector_v3(chip->ctrl_intf, entity_id);
357 if (selector) {
358 int ret, i, cur;
359
360 /* the entity ID we are looking for is a selector.
361 * find out what it currently selects */
362 ret = uac_clock_selector_get_val(chip, selector->bClockID);
363 if (ret < 0)
364 return ret;
365
366 /* Selector values are one-based */
367
368 if (ret > selector->bNrInPins || ret < 1) {
369 usb_audio_err(chip,
370 "%s(): selector reported illegal value, id %d, ret %d\n",
371 __func__, selector->bClockID, ret);
372
373 return -EINVAL;
374 }
375
376 cur = ret;
377 ret = __uac3_clock_find_source(chip, selector->baCSourceID[ret - 1],
378 visited, validate);
379 if (!validate || ret > 0 || !chip->autoclock)
380 return ret;
381
382 /* The current clock source is invalid, try others. */
383 for (i = 1; i <= selector->bNrInPins; i++) {
384 int err;
385
386 if (i == cur)
387 continue;
388
389 ret = __uac3_clock_find_source(chip, selector->baCSourceID[i - 1],
390 visited, true);
391 if (ret < 0)
392 continue;
393
394 err = uac_clock_selector_set_val(chip, entity_id, i);
395 if (err < 0)
396 continue;
397
398 usb_audio_info(chip,
399 "found and selected valid clock source %d\n",
400 ret);
401 return ret;
402 }
403
404 return -ENXIO;
405 }
406
407 /* FIXME: multipliers only act as pass-thru element for now */
408 multiplier = snd_usb_find_clock_multiplier_v3(chip->ctrl_intf,
409 entity_id);
410 if (multiplier)
411 return __uac3_clock_find_source(chip, multiplier->bCSourceID,
412 visited, validate);
413
414 return -EINVAL;
415}
416
263/* 417/*
264 * For all kinds of sample rate settings and other device queries, 418 * For all kinds of sample rate settings and other device queries,
265 * the clock source (end-leaf) must be used. However, clock selectors, 419 * the clock source (end-leaf) must be used. However, clock selectors,
@@ -271,12 +425,22 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip,
271 * 425 *
272 * Returns the clock source UnitID (>=0) on success, or an error. 426 * Returns the clock source UnitID (>=0) on success, or an error.
273 */ 427 */
274int snd_usb_clock_find_source(struct snd_usb_audio *chip, int entity_id, 428int snd_usb_clock_find_source(struct snd_usb_audio *chip, int protocol,
275 bool validate) 429 int entity_id, bool validate)
276{ 430{
277 DECLARE_BITMAP(visited, 256); 431 DECLARE_BITMAP(visited, 256);
278 memset(visited, 0, sizeof(visited)); 432 memset(visited, 0, sizeof(visited));
279 return __uac_clock_find_source(chip, entity_id, visited, validate); 433
434 switch (protocol) {
435 case UAC_VERSION_2:
436 return __uac_clock_find_source(chip, entity_id, visited,
437 validate);
438 case UAC_VERSION_3:
439 return __uac3_clock_find_source(chip, entity_id, visited,
440 validate);
441 default:
442 return -EINVAL;
443 }
280} 444}
281 445
282static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, 446static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
@@ -335,7 +499,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
335 return 0; 499 return 0;
336} 500}
337 501
338static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface, 502static int get_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
339 int altsetting, int clock) 503 int altsetting, int clock)
340{ 504{
341 struct usb_device *dev = chip->dev; 505 struct usb_device *dev = chip->dev;
@@ -348,7 +512,7 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface,
348 snd_usb_ctrl_intf(chip) | (clock << 8), 512 snd_usb_ctrl_intf(chip) | (clock << 8),
349 &data, sizeof(data)); 513 &data, sizeof(data));
350 if (err < 0) { 514 if (err < 0) {
351 dev_warn(&dev->dev, "%d:%d: cannot get freq (v2): err %d\n", 515 dev_warn(&dev->dev, "%d:%d: cannot get freq (v2/v3): err %d\n",
352 iface, altsetting, err); 516 iface, altsetting, err);
353 return 0; 517 return 0;
354 } 518 }
@@ -356,7 +520,7 @@ static int get_sample_rate_v2(struct snd_usb_audio *chip, int iface,
356 return le32_to_cpu(data); 520 return le32_to_cpu(data);
357} 521}
358 522
359static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, 523static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
360 struct usb_host_interface *alts, 524 struct usb_host_interface *alts,
361 struct audioformat *fmt, int rate) 525 struct audioformat *fmt, int rate)
362{ 526{
@@ -365,18 +529,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
365 int err, cur_rate, prev_rate; 529 int err, cur_rate, prev_rate;
366 int clock; 530 int clock;
367 bool writeable; 531 bool writeable;
368 struct uac_clock_source_descriptor *cs_desc; 532 u32 bmControls;
369 533
370 clock = snd_usb_clock_find_source(chip, fmt->clock, true); 534 clock = snd_usb_clock_find_source(chip, fmt->protocol,
535 fmt->clock, true);
371 if (clock < 0) 536 if (clock < 0)
372 return clock; 537 return clock;
373 538
374 prev_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); 539 prev_rate = get_sample_rate_v2v3(chip, iface, fmt->altsetting, clock);
375 if (prev_rate == rate) 540 if (prev_rate == rate)
376 return 0; 541 return 0;
377 542
378 cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock); 543 if (fmt->protocol == UAC_VERSION_3) {
379 writeable = uac2_control_is_writeable(cs_desc->bmControls, UAC2_CS_CONTROL_SAM_FREQ - 1); 544 struct uac3_clock_source_descriptor *cs_desc;
545
546 cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock);
547 bmControls = le32_to_cpu(cs_desc->bmControls);
548 } else {
549 struct uac_clock_source_descriptor *cs_desc;
550
551 cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
552 bmControls = cs_desc->bmControls;
553 }
554
555 writeable = uac_v2v3_control_is_writeable(bmControls,
556 UAC2_CS_CONTROL_SAM_FREQ);
380 if (writeable) { 557 if (writeable) {
381 data = cpu_to_le32(rate); 558 data = cpu_to_le32(rate);
382 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, 559 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR,
@@ -386,12 +563,13 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface,
386 &data, sizeof(data)); 563 &data, sizeof(data));
387 if (err < 0) { 564 if (err < 0) {
388 usb_audio_err(chip, 565 usb_audio_err(chip,
389 "%d:%d: cannot set freq %d (v2): err %d\n", 566 "%d:%d: cannot set freq %d (v2/v3): err %d\n",
390 iface, fmt->altsetting, rate, err); 567 iface, fmt->altsetting, rate, err);
391 return err; 568 return err;
392 } 569 }
393 570
394 cur_rate = get_sample_rate_v2(chip, iface, fmt->altsetting, clock); 571 cur_rate = get_sample_rate_v2v3(chip, iface,
572 fmt->altsetting, clock);
395 } else { 573 } else {
396 cur_rate = prev_rate; 574 cur_rate = prev_rate;
397 } 575 }
@@ -430,7 +608,8 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
430 return set_sample_rate_v1(chip, iface, alts, fmt, rate); 608 return set_sample_rate_v1(chip, iface, alts, fmt, rate);
431 609
432 case UAC_VERSION_2: 610 case UAC_VERSION_2:
433 return set_sample_rate_v2(chip, iface, alts, fmt, rate); 611 case UAC_VERSION_3:
612 return set_sample_rate_v2v3(chip, iface, alts, fmt, rate);
434 } 613 }
435} 614}
436 615