aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb/format.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@caiaq.de>2010-05-31 08:51:31 -0400
committerTakashi Iwai <tiwai@suse.de>2010-05-31 12:16:59 -0400
commit79f920fbff566ffc9de44111eb1456a3cef310f0 (patch)
tree97b574ee648320163fcbcf8793b23e826fb3a1f8 /sound/usb/format.c
parent7176d37a28fa4ea7e32815007673f578cdcebf51 (diff)
ALSA: usb-audio: parse clock topology of UAC2 devices
Audio devices which comply to the UAC2 standard can export complex clock topologies in its descriptors and set up links between them. The entities that are defined are - clock sources, which define the end-leafs. - clock selectors, which act as switch to select one out of many possible clocks sources. - clock multipliers, which have an input clock source, and act as clock source again. They can be used to derive one clock from another. All sample rate changes, clock validity queries and the like must go to clock source elements, while clock selectors and multipliers can be used as terminal clock source. The following patch adds a parser for these elements and functions to iterate over the tree and find the leaf nodes (clock sources). The samplerate set functions were moved to the new clock.c file. Signed-off-by: Daniel Mack <daniel@caiaq.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/format.c')
-rw-r--r--sound/usb/format.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/sound/usb/format.c b/sound/usb/format.c
index fe29d61de19b..5367cd1e52d9 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -29,6 +29,7 @@
29#include "quirks.h" 29#include "quirks.h"
30#include "helper.h" 30#include "helper.h"
31#include "debug.h" 31#include "debug.h"
32#include "clock.h"
32 33
33/* 34/*
34 * parse the audio format type I descriptor 35 * parse the audio format type I descriptor
@@ -215,15 +216,17 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
215 struct usb_device *dev = chip->dev; 216 struct usb_device *dev = chip->dev;
216 unsigned char tmp[2], *data; 217 unsigned char tmp[2], *data;
217 int i, nr_rates, data_size, ret = 0; 218 int i, nr_rates, data_size, ret = 0;
219 int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock);
218 220
219 /* get the number of sample rates first by only fetching 2 bytes */ 221 /* get the number of sample rates first by only fetching 2 bytes */
220 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, 222 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
221 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 223 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
222 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, 224 UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
223 tmp, sizeof(tmp), 1000); 225 tmp, sizeof(tmp), 1000);
224 226
225 if (ret < 0) { 227 if (ret < 0) {
226 snd_printk(KERN_ERR "unable to retrieve number of sample rates\n"); 228 snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n",
229 __func__, clock);
227 goto err; 230 goto err;
228 } 231 }
229 232
@@ -237,12 +240,13 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip,
237 240
238 /* now get the full information */ 241 /* now get the full information */
239 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, 242 ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE,
240 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 243 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
241 UAC2_CS_CONTROL_SAM_FREQ << 8, chip->clock_id << 8, 244 UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8,
242 data, data_size, 1000); 245 data, data_size, 1000);
243 246
244 if (ret < 0) { 247 if (ret < 0) {
245 snd_printk(KERN_ERR "unable to retrieve sample rate range\n"); 248 snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n",
249 __func__, clock);
246 ret = -EINVAL; 250 ret = -EINVAL;
247 goto err_free; 251 goto err_free;
248 } 252 }